forked from Mirrors/openclonk
Clonk control library
parent
3425ae0dae
commit
3212d8ff8c
|
@ -0,0 +1,7 @@
|
|||
[DefCore]
|
||||
id=L_CO
|
||||
Version=4,9,8
|
||||
Category=C4D_StaticBack
|
||||
Width=1
|
||||
Height=1
|
||||
Picture=0,0,64,64
|
|
@ -0,0 +1 @@
|
|||
Standardkontrolle für den Clonk
|
|
@ -0,0 +1 @@
|
|||
Standard controls for the clonk
|
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
|
@ -0,0 +1,324 @@
|
|||
/*-- Standard controls --*/
|
||||
|
||||
// currently
|
||||
local selected;
|
||||
|
||||
/* Item limit */
|
||||
|
||||
public func MaxContentsCount() { return 3; }
|
||||
|
||||
/* Item select access*/
|
||||
|
||||
public func Select(int selection)
|
||||
{
|
||||
var item = Contents(selected);
|
||||
// de-select previous (if any)
|
||||
if(item) item->~Deselection(this);
|
||||
|
||||
// select new (if any)
|
||||
selected = selection;
|
||||
var item = Contents(selected);
|
||||
|
||||
// DEBUG
|
||||
var bla = "nothing";
|
||||
if(item) bla = item->~GetName();
|
||||
Log("selected %s (position %d)", bla, selected);
|
||||
|
||||
if (!item) return;
|
||||
if (item->~Selection(this)) return;
|
||||
|
||||
Sound("Grab");
|
||||
}
|
||||
|
||||
public func GetSelection()
|
||||
{
|
||||
return selected;
|
||||
}
|
||||
|
||||
protected func Initialize()
|
||||
{
|
||||
selected = 0;
|
||||
}
|
||||
|
||||
/* Main control function */
|
||||
public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool repeat, bool release)
|
||||
{
|
||||
if (!this) return false;
|
||||
|
||||
// Any control resets a previously given command
|
||||
SetCommand("None");
|
||||
|
||||
// hotkeys (inventory, vehicle and structure control)
|
||||
var hot = 0;
|
||||
if (ctrl == CON_Hotkey0) hot = 10;
|
||||
if (ctrl == CON_Hotkey1) hot = 1;
|
||||
if (ctrl == CON_Hotkey2) hot = 2;
|
||||
if (ctrl == CON_Hotkey3) hot = 3;
|
||||
if (ctrl == CON_Hotkey4) hot = 4;
|
||||
if (ctrl == CON_Hotkey5) hot = 5;
|
||||
if (ctrl == CON_Hotkey6) hot = 6;
|
||||
if (ctrl == CON_Hotkey7) hot = 7;
|
||||
if (ctrl == CON_Hotkey8) hot = 8;
|
||||
if (ctrl == CON_Hotkey9) hot = 9;
|
||||
|
||||
if (hot > 0) return this->~ControlHotkey(hot-1);
|
||||
|
||||
var proc = GetProcedure();
|
||||
|
||||
// building, vehicle, contents control
|
||||
var house = Contained();
|
||||
var vehicle = GetActionTarget();
|
||||
var contents = Contents(selected);
|
||||
|
||||
if (house)
|
||||
{
|
||||
if (Control2Script(ctrl, x, y, strength, repeat, release, "Contained", house))
|
||||
return true;
|
||||
}
|
||||
else if (vehicle)
|
||||
{
|
||||
// control to grabbed vehicle or riding etc.
|
||||
if (proc == "PUSH" || proc == "ATTACH")
|
||||
if (Control2Script(ctrl, x, y, strength, repeat, release, "Control", vehicle))
|
||||
return true;
|
||||
}
|
||||
else if (contents)
|
||||
{
|
||||
// out of convencience we call Control2Script, even though it can handle
|
||||
// left, right, up and down, too. We don't want that, so this is why we
|
||||
// check that ctrl is Use.
|
||||
if (ctrl == CON_Use)
|
||||
if (Control2Script(ctrl, x, y, strength, repeat, release, "Control", contents))
|
||||
return true;
|
||||
}
|
||||
// clonk control
|
||||
else
|
||||
{
|
||||
// for standard controls
|
||||
if(Control2Script(ctrl, x, y, strength, repeat, release, "Control", this)) return true;
|
||||
// and a few more...
|
||||
if(ctrl == CON_Throw) if(this->~ControlThrow(this,x,y)) return true;
|
||||
if(ctrl == CON_Jump) if(this->~ControlJump(this)) return true;
|
||||
}
|
||||
|
||||
// everything down from here:
|
||||
// standard controls that are called if not overloaded via script
|
||||
|
||||
// Movement controls
|
||||
if (ctrl == CON_Left || ctrl == CON_Right || ctrl == CON_Up || ctrl == CON_Down || ctrl == CON_Jump)
|
||||
return ObjectControlMovement(plr, ctrl, strength, release);
|
||||
|
||||
// Push controls
|
||||
if (ctrl == CON_Grab || ctrl == CON_Ungrab || ctrl == CON_PushEnter || ctrl == CON_GrabPrevious || ctrl == CON_GrabNext)
|
||||
return ObjectControlPush(plr, ctrl);
|
||||
|
||||
// Entrance controls
|
||||
if (ctrl == CON_Enter || ctrl == CON_Exit)
|
||||
return ObjectControlEntrance(plr,ctrl);
|
||||
|
||||
// Inventory control
|
||||
if (ctrl == CON_NextItem)
|
||||
{
|
||||
var sel = selected;
|
||||
sel++;
|
||||
if (sel >= MaxContentsCount()) sel = 0;
|
||||
|
||||
Select(sel);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (ctrl == CON_PreviousItem)
|
||||
{
|
||||
var sel = selected;
|
||||
sel--;
|
||||
if (sel <= 0) sel = MaxContentsCount()-1;
|
||||
|
||||
Select(sel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// only if not in house, not grabbing a vehicle and an item selected
|
||||
if(!house && !vehicle && contents)
|
||||
{
|
||||
// throw
|
||||
if (ctrl == CON_Throw)
|
||||
{
|
||||
if (proc == "SCALE" || proc == "HANGLE")
|
||||
return PlayerObjectCommand(plr, false, "Drop", contents);
|
||||
else
|
||||
return PlayerObjectCommand(plr, false, "Throw", contents);
|
||||
}
|
||||
// drop
|
||||
if (ctrl == CON_Drop)
|
||||
{
|
||||
return PlayerObjectCommand(plr, false, "Drop", contents);
|
||||
}
|
||||
}
|
||||
|
||||
// Unhandled control
|
||||
return false;
|
||||
}
|
||||
|
||||
// Control redirected to script
|
||||
private func Control2Script(int ctrl, int x, int y, int strength, bool repeat, bool release, string control, object obj)
|
||||
{
|
||||
// for the use command
|
||||
if (ctrl == CON_Use)
|
||||
{
|
||||
var handled = false;
|
||||
|
||||
if(!release && !repeat)
|
||||
handled = obj->Call(Format("~%sUse",control),this,x,y);
|
||||
else if(release)
|
||||
handled = obj->Call(Format("~%sUseStop",control),this,x,y);
|
||||
else
|
||||
handled = obj->Call(Format("~%sUseHolding",control),this,x,y);
|
||||
|
||||
return handled;
|
||||
}
|
||||
// overloads of movement commandos
|
||||
else if (ctrl == CON_Left || ctrl == CON_Right || ctrl == CON_Down || ctrl == CON_Up)
|
||||
{
|
||||
if (release)
|
||||
{
|
||||
// if any movement key has been released, ControlStop is called
|
||||
if (obj->Call(Format("~%sStop",control),this)) return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Control*
|
||||
if (ctrl == CON_Left) if (obj->Call(Format("~%sLeft",control),this)) return true;
|
||||
if (ctrl == CON_Right) if (obj->Call(Format("~%sRight",control),this)) return true;
|
||||
if (ctrl == CON_Up) if (obj->Call(Format("~%sUp",control),this)) return true;
|
||||
if (ctrl == CON_Down) if (obj->Call(Format("~%sDown",control),this)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handles enter and exit
|
||||
private func ObjectControlEntrance(int plr, int ctrl)
|
||||
{
|
||||
var proc = GetProcedure();
|
||||
|
||||
// enter
|
||||
if (ctrl == CON_Enter)
|
||||
{
|
||||
// enter only if... one can
|
||||
if (proc != "WALK" && proc != "SWIM" && proc != "SCALE" &&
|
||||
proc != "HANGLE" && proc != "FLOAT" && proc != "FLIGHT") return false;
|
||||
|
||||
// a building with an entrance at right position is there?
|
||||
var obj = GetEntranceObject();
|
||||
if (!obj) return false;
|
||||
|
||||
PlayerObjectCommand(plr, false, "Enter", obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
// exit
|
||||
if (ctrl == CON_Exit)
|
||||
{
|
||||
if (!Contained()) return false;
|
||||
|
||||
PlayerObjectCommand(plr, false, "Exit");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handles push controls
|
||||
private func ObjectControlPush(int plr, int ctrl)
|
||||
{
|
||||
if (!this) return false;
|
||||
|
||||
var proc = GetProcedure();
|
||||
|
||||
// grabbing
|
||||
if (ctrl == CON_Grab)
|
||||
{
|
||||
// grab only if he walks
|
||||
if (proc != "WALK") return false;
|
||||
|
||||
// only if there is someting to grab
|
||||
var obj = FindObject(Find_OCF(OCF_Grab), Find_AtPoint(0,0), Find_Exclude(this));
|
||||
if (!obj) return false;
|
||||
|
||||
// grab
|
||||
PlayerObjectCommand(plr, false, "Grab", obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
// grab next/previous
|
||||
if (ctrl == CON_GrabNext)
|
||||
return ShiftVehicle(plr, false);
|
||||
if (ctrl == CON_GrabPrevious)
|
||||
return ShiftVehicle(plr, true);
|
||||
|
||||
// ungrabbing
|
||||
if (ctrl == CON_Ungrab)
|
||||
{
|
||||
// ungrab only if he pushes
|
||||
if (proc != "PUSH") return false;
|
||||
|
||||
PlayerObjectCommand(plr, false, "Ungrab");
|
||||
return true;
|
||||
}
|
||||
|
||||
// push into building
|
||||
if (ctrl == CON_PushEnter)
|
||||
{
|
||||
if (proc != "PUSH") return false;
|
||||
|
||||
// a building with an entrance at right position is there?
|
||||
var obj = GetActionTarget()->GetEntranceObject();
|
||||
if (!obj) return false;
|
||||
|
||||
PlayerObjectCommand(plr, false, "PushTo", obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// grabs the next/previous vehicle (if there is any)
|
||||
private func ShiftVehicle(int plr, bool back)
|
||||
{
|
||||
if (!this) return false;
|
||||
|
||||
if (GetProcedure() != "PUSH") return false;
|
||||
|
||||
var lorry = GetActionTarget();
|
||||
// get all grabbable objects
|
||||
var objs = FindObjects(Find_OCF(OCF_Grab), Find_AtPoint(0,0), Find_Exclude(this));
|
||||
|
||||
// nothing to switch to (there is no other grabbable object)
|
||||
if (GetLength(objs) <= 1) return false;
|
||||
|
||||
// find out at what index of the array objs the vehicle is located
|
||||
var index = 0;
|
||||
for(var obj in objs)
|
||||
{
|
||||
if (obj == lorry) break;
|
||||
index++;
|
||||
}
|
||||
|
||||
// get the next/previous vehicle
|
||||
if (back)
|
||||
{
|
||||
--index;
|
||||
if (index < 0) index = GetLength(objs)-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
++index;
|
||||
if (index >= GetLength(objs)) index = 0;
|
||||
}
|
||||
|
||||
PlayerObjectCommand(plr, false, "Grab", objs[index]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue