Control: Format scripts

ipv6
Mark 2017-01-03 17:48:09 +01:00
parent fa28a7a643
commit 83486fceb8
3 changed files with 151 additions and 99 deletions

View File

@ -21,52 +21,53 @@ local virtual_cursor;
Fullscreen menus are handled differently. */
func Control2Menu(int ctrl, int x, int y, int strength, bool repeat, int status)
{
/* all this stuff is already done on a higher layer - in playercontrol.c
now this is just the same for gamepad control */
if (!HasVirtualCursor())
return true;
if (!this->GetMenu()) return false;
if (!this->GetMenu())
return false;
// fix pos of x and y
var mex = this.control.mlastx+GetX()-GetMenu()->GetX();
var mey = this.control.mlasty+GetY()-GetMenu()->GetY();
var mex = this.control.mlastx + GetX() - GetMenu()->GetX();
var mey = this.control.mlasty + GetY() - GetMenu()->GetY();
// update angle for visual effect on the menu
if (repeat)
{
if (ctrl == CON_Use || ctrl == CON_UseAlt)
this->GetMenu()->~UpdateCursor(mex,mey);
this->GetMenu()->~UpdateCursor(mex, mey);
}
// click on menu
if (status == CONS_Up)
{
// select
if (ctrl == CON_Use)
this->GetMenu()->~OnMouseClick(mex,mey);
this->GetMenu()->~OnMouseClick(mex, mey);
}
return true;
}
public func ObjectControlMovement(int plr, int ctrl, int strength, int status)
{
// from PlayerControl.c
var result = inherited(plr,ctrl,strength,status,...);
var result = inherited(plr, ctrl, strength, status, ...);
// do the following only if strength >= CON_Gamepad_Deadzone
if(status == CONS_Down)
if(strength != nil && strength < CON_Gamepad_Deadzone)
if (status == CONS_Down)
if (strength != nil && strength < CON_Gamepad_Deadzone)
return result;
if(!virtual_cursor)
virtual_cursor = FindObject(Find_ID(GUI_Crosshair),Find_Owner(GetOwner()));
if(!virtual_cursor) return result;
if (!virtual_cursor)
virtual_cursor = FindObject(Find_ID(GUI_Crosshair), Find_Owner(GetOwner()));
if (!virtual_cursor)
return result;
// change direction of virtual_cursor
if(status == CONS_Down)
if (status == CONS_Down)
virtual_cursor->Direction(ctrl);
return result;
@ -74,12 +75,12 @@ public func ObjectControlMovement(int plr, int ctrl, int strength, int status)
func ReinitializeControls()
{
if(PlayerHasVirtualCursor(GetOwner()))
if (PlayerHasVirtualCursor(GetOwner()))
{
// if is aiming or in menu and no virtual cursor is there, create one
if (!virtual_cursor)
if (this.menu || this.control.current_object) // properties declared in ClonkControl.ocd
VirtualCursor()->StartAim(this,0,this.menu);
VirtualCursor()->StartAim(this, 0, this.menu);
}
else
{
@ -92,18 +93,21 @@ func ReinitializeControls()
/* Virtual cursor stuff */
// Helper function.
private func HasVirtualCursor() { return PlayerHasVirtualCursor(GetOwner()); }
private func HasVirtualCursor()
{
return PlayerHasVirtualCursor(GetOwner());
}
// get virtual cursor, if noone is there, create it
private func VirtualCursor()
{
if (!virtual_cursor)
{
virtual_cursor = FindObject(Find_ID(GUI_Crosshair),Find_Owner(GetOwner()));
virtual_cursor = FindObject(Find_ID(GUI_Crosshair), Find_Owner(GetOwner()));
}
if (!virtual_cursor)
{
virtual_cursor = CreateObject(GUI_Crosshair,0,0,GetOwner());
virtual_cursor = CreateObject(GUI_Crosshair, 0, 0, GetOwner());
}
return virtual_cursor;
@ -112,15 +116,16 @@ private func VirtualCursor()
// virtual cursor is visible
private func VirtualCursorAiming()
{
if (!virtual_cursor) return false;
if (!virtual_cursor)
return false;
return virtual_cursor->IsAiming();
}
// store pos of virtual cursor into mlastx, mlasty
public func UpdateVirtualCursorPos()
{
this.control.mlastx = VirtualCursor()->GetX()-GetX();
this.control.mlasty = VirtualCursor()->GetY()-GetY();
this.control.mlastx = VirtualCursor()->GetX() - GetX();
this.control.mlasty = VirtualCursor()->GetY() - GetY();
}
public func TriggerHoldingControl()
@ -132,11 +137,10 @@ public func TriggerHoldingControl()
ctrl = CON_UseAlt;
ObjectControl(GetOwner(), ctrl, 0, 0, 0, true, CONS_Down);
}
}
func RemoveVirtualCursor()
{
if (virtual_cursor)
virtual_cursor->StopAim();
virtual_cursor->StopAim();
}

View File

@ -26,7 +26,7 @@
protected func Construction()
{
if(this.control == nil)
if (this.control == nil)
this.control = {};
this.control.menu = nil;
@ -42,7 +42,7 @@ protected func CrewSelection(bool unselect)
// if there is still a menu, cancel it too...
CancelMenu();
}
return _inherited(unselect,...);
return _inherited(unselect, ...);
}
protected func Destruction()
@ -67,7 +67,10 @@ func HasMenuControl()
}
// helper function that can be attached to a proplist to set callbacks on-the-fly
func GetTrue() { return true; }
func GetTrue()
{
return true;
}
/*
Sets the menu this Clonk currently has focus of. Old menus that have been opened via SetMenu will be closed, making sure that only one menu is open at a time.
@ -83,7 +86,8 @@ func SetMenu(new_menu, bool unclosable)
// no news?
if (new_menu) // if new_menu==nil, it is important that we still do the cleaning-up below even if we didn't have a menu before (see MenuClosed())
if (current_menu == new_menu) return;
if (current_menu == new_menu)
return;
// close old one!
if (current_menu != nil)
@ -103,16 +107,16 @@ func SetMenu(new_menu, bool unclosable)
this->~CancelUse();
// stop clonk
SetComDir(COMD_Stop);
if (this->~HasVirtualCursor())
{
this->~VirtualCursor()->StartAim(this, 0, new_menu);
}
else
{
if (GetType(new_menu) == C4V_C4Object && new_menu->~CursorUpdatesEnabled())
if (GetType(new_menu) == C4V_C4Object && new_menu->~CursorUpdatesEnabled())
SetPlayerControlEnabled(GetOwner(), CON_GUICursor, true);
SetPlayerControlEnabled(GetOwner(), CON_GUIClick1, true);
SetPlayerControlEnabled(GetOwner(), CON_GUIClick2, true);
}
@ -135,7 +139,7 @@ func SetMenu(new_menu, bool unclosable)
}
else
FatalError("Library_ClonkControl::SetMenu called with invalid parameter!");
// make sure the menu is unclosable even if it is just a GUI ID
if (unclosable)
{
@ -199,15 +203,18 @@ func CancelMenu()
// Tries to cancel a non-unclosable menu. Returns true when there is no menu left after this call (even if there never was one).
func TryCancelMenu()
{
if (!this.control.menu) return true;
if (this.control.menu->~Unclosable()) return false;
if (!this.control.menu)
return true;
if (this.control.menu->~Unclosable())
return false;
CancelMenu();
return true;
}
public func RejectShiftCursor()
{
if (this.control.menu && this.control.menu->~Unclosable()) return true;
if (this.control.menu && this.control.menu->~Unclosable())
return true;
return _inherited(...);
}

View File

@ -33,7 +33,7 @@
protected func Construction()
{
if(this.control == nil)
if (this.control == nil)
this.control = {};
this.control.current_object = nil;
@ -43,16 +43,32 @@ protected func Construction()
return _inherited(...);
}
public func GetUsedObject() { return this.control.current_object; }
public func GetUsedObject()
{
return this.control.current_object;
}
// The using-command hast to be canceled if the clonk is entered into
// or exited from a building.
protected func Entrance()
{
CancelUse();
return _inherited(...);
}
protected func Entrance() { CancelUse(); return _inherited(...); }
protected func Departure() { CancelUse(); return _inherited(...); }
protected func Departure()
{
CancelUse();
return _inherited(...);
}
// The same for vehicles
protected func AttachTargetLost() { CancelUse(); return _inherited(...); }
protected func AttachTargetLost()
{
CancelUse();
return _inherited(...);
}
// ...aaand the same for when the clonk is deselected
protected func CrewSelection(bool unselect)
@ -63,7 +79,7 @@ protected func CrewSelection(bool unselect)
CancelUse();
}
return _inherited(unselect,...);
return _inherited(unselect, ...);
}
protected func Destruction()
@ -85,30 +101,38 @@ protected func Death()
public func ShelveCommand(object condition_obj, string condition, object callback_obj, string callback, proplist data)
{
this.control.shelved_command = { cond = condition, cond_obj = condition_obj, callback = callback, callback_obj = callback_obj, data = data };
this.control.shelved_command =
{
cond = condition,
cond_obj = condition_obj,
callback = callback,
callback_obj = callback_obj,
data = data
};
AddEffect("ShelvedCommand", this, 1, 5, this);
}
public func StopShelvedCommand()
{
this.control.shelved_command = nil;
if(GetEffect("ShelvedCommand", this))
if (GetEffect("ShelvedCommand", this))
RemoveEffect("ShelvedCommand", this);
}
func FxShelvedCommandTimer(_, effect, time)
{
if(!this.control.shelved_command) return -1;
if(!this.control.shelved_command.callback_obj) return -1;
if(!this.control.shelved_command.cond_obj) return -1;
if(!this.control.shelved_command.cond_obj->Call(this.control.shelved_command.cond, this.control.shelved_command.data)) return 1;
if (!this.control.shelved_command) return -1;
if (!this.control.shelved_command.callback_obj) return -1;
if (!this.control.shelved_command.cond_obj) return -1;
if (!this.control.shelved_command.cond_obj->Call(this.control.shelved_command.cond, this.control.shelved_command.data)) return 1;
this.control.shelved_command.callback_obj->Call(this.control.shelved_command.callback, this.control.shelved_command.data);
return -1;
}
func FxShelvedCommandStop(target, effect, reason, temp)
{
if(temp) return;
if (temp)
return;
this.control.shelved_command = nil;
}
@ -132,7 +156,7 @@ public func CancelUse()
func PauseUse(object obj, string custom_condition, proplist data)
{
// cancel use first, since it removes old shelved commands
if(this.control.started_use)
if (this.control.started_use)
{
CancelUse();
this.control.started_use = false;
@ -140,12 +164,15 @@ func PauseUse(object obj, string custom_condition, proplist data)
var callback_obj = this;
if(custom_condition != nil)
if (custom_condition != nil)
{
callback_obj = obj;
}
else custom_condition = "CanReIssueCommand";
else
{
custom_condition = "CanReIssueCommand";
}
data = data ?? {};
data.obj = obj;
data.ctrl = CON_Use;
@ -154,7 +181,8 @@ func PauseUse(object obj, string custom_condition, proplist data)
func DetermineUsageType(object obj)
{
if(!obj) return nil;
if (!obj)
return nil;
// house
if (obj == Contained())
return C4D_Structure;
@ -174,29 +202,30 @@ func GetUseCallString(string action)
{
// Control... or Contained...
var control_string = "Control";
if (this.control.using_type == C4D_Structure)
if (this.control.using_type == C4D_Structure)
control_string = "Contained";
// ..Use.. or ..UseAlt...
var estr = "";
if (this.control.alt && this.control.using_type != C4D_Object)
if (this.control.alt && this.control.using_type != C4D_Object)
estr = "Alt";
// Action
if (!action)
if (!action)
action = "";
return Format("~%sUse%s%s", control_string, estr, action);
}
func CanReIssueCommand(proplist data)
{
if (!data.obj) return false;
if (!data.obj)
return false;
if(data.ctrl == CON_Use)
if (data.ctrl == CON_Use)
return !data.obj->~RejectUse(this);
}
func ReIssueCommand(proplist data)
{
if(data.ctrl == CON_Use)
if (data.ctrl == CON_Use)
return StartUseControl(data.ctrl, this.control.mlastx, this.control.mlasty, data.obj);
}
@ -204,7 +233,7 @@ func StartUseControl(int ctrl, int x, int y, object obj)
{
this.control.started_use = false;
if(obj->~RejectUse(this))
if (obj->~RejectUse(this))
{
// remember for later:
PauseUse(obj);
@ -213,7 +242,8 @@ func StartUseControl(int ctrl, int x, int y, object obj)
}
// Disable climb/hangle actions for the duration of this use
if (obj.ForceFreeHands && !GetEffect("IntControlFreeHands", this)) AddEffect("IntControlFreeHands", this, 130, 0, this);
if (obj.ForceFreeHands && !GetEffect("IntControlFreeHands", this))
AddEffect("IntControlFreeHands", this, 130, 0, this);
obj->SetController(GetController());
this.control.current_object = obj;
@ -223,7 +253,7 @@ func StartUseControl(int ctrl, int x, int y, object obj)
if (this->~HasVirtualCursor())
{
var cursor = this->~VirtualCursor(), angle;
if (!cursor->IsActive() && (angle = obj->~DefaultCrosshairAngle(this, GetDir()*2 - 1)))
if (!cursor->IsActive() && (angle = obj->~DefaultCrosshairAngle(this, GetDir() * 2 - 1)))
{
x = +Sin(angle, CURSOR_Radius, 10);
y = -Cos(angle, CURSOR_Radius, 10);
@ -232,15 +262,15 @@ func StartUseControl(int ctrl, int x, int y, object obj)
}
var hold_enabled = obj->Call("~HoldingEnabled");
if (hold_enabled)
SetPlayerControlEnabled(GetOwner(), CON_Aim, true);
// first call UseStart. If unhandled, call Use (mousecontrol)
var handled = obj->Call(GetUseCallString("Start"),this,x,y);
var handled = obj->Call(GetUseCallString("Start"), this, x, y);
if (!handled)
{
handled = obj->Call(GetUseCallString(),this,x,y);
handled = obj->Call(GetUseCallString(), this, x, y);
this.control.noholdingcallbacks = handled;
}
else
@ -263,7 +293,7 @@ func StartUseControl(int ctrl, int x, int y, object obj)
// add helper effect that prevents errors when objects are suddenly deleted by quickly cancelling their use beforehand
AddEffect("ItemRemovalCheck", GetUsedObject(), 1, 100, this, nil); // the slow timer is arbitrary and will just clean up the effect if necessary
}
return handled;
}
@ -274,25 +304,26 @@ func CancelUseControl(int x, int y)
// to horse first (if there is one)
var horse = GetActionTarget();
if(horse && GetProcedure() == "ATTACH" && GetUsedObject() != horse)
if (horse && GetProcedure() == "ATTACH" && GetUsedObject() != horse)
StopUseControl(x, y, horse, true);
return StopUseControl(x, y, GetUsedObject(), true);
}
func StopUseControl(int x, int y, object obj, bool cancel)
{
var stop = "Stop";
if (cancel) stop = "Cancel";
if (cancel)
stop = "Cancel";
// ControlUseStop, ControlUseAltStop, ContainedUseAltStop, ContainedUseCancel, etc...
var handled = obj->Call(GetUseCallString(stop),this,x,y);
var handled = obj->Call(GetUseCallString(stop), this, x, y);
if (obj == GetUsedObject())
{
// if ControlUseStop returned -1, the current object is kept as "used object"
// but no more callbacks except for ControlUseCancel are made. The usage of this
// object is finally cancelled on ControlUseCancel.
if(cancel || handled != -1)
if (cancel || handled != -1)
{
// look for correct removal helper effect and remove it
var effect_index = 0;
@ -300,13 +331,15 @@ func StopUseControl(int x, int y, object obj, bool cancel)
do
{
removal_helper = GetEffect("ItemRemovalCheck", GetUsedObject(), effect_index++);
if (!removal_helper) break;
if (removal_helper.CommandTarget != this) continue;
if (!removal_helper)
break;
if (removal_helper.CommandTarget != this)
continue;
break;
} while (true);
RemoveEffect("IntControlFreeHands", this); // make sure we can climb again
RemoveEffect("IntControlFreeHands", this); // make sure we can climb again
this.control.current_object = nil;
this.control.using_type = nil;
this.control.alt = false;
@ -314,7 +347,7 @@ func StopUseControl(int x, int y, object obj, bool cancel)
if (removal_helper)
{
RemoveEffect(nil, nil, removal_helper, true);
}
}
}
this.control.noholdingcallbacks = false;
@ -323,7 +356,7 @@ func StopUseControl(int x, int y, object obj, bool cancel)
if (this->~HasVirtualCursor())
this->~VirtualCursor()->StopAim();
}
return handled;
}
@ -331,7 +364,7 @@ func HoldingUseControl(int ctrl, int x, int y, object obj)
{
var mex = x;
var mey = y;
//Message("%d,%d",this,mex,mey);
// automatic adjustment of the direction
@ -342,17 +375,19 @@ func HoldingUseControl(int ctrl, int x, int y, object obj)
// a turning animation is the question. But after all, the clonk can turn
// by setting the dir too.
// not riding and not in building not while scaling
if (GetProcedure() != "ATTACH" && !Contained() && GetProcedure() != "SCALE")
if (GetProcedure() != "ATTACH" && !Contained() && GetProcedure() != "SCALE")
{
// pushing vehicle: object to turn is the vehicle
var dir_obj = GetActionTarget();
if (GetProcedure() != "PUSH") dir_obj = nil;
if (GetProcedure() != "PUSH")
dir_obj = nil;
// otherwise, turn the clonk
if (!dir_obj) dir_obj = this;
if (!dir_obj)
dir_obj = this;
if ((dir_obj->GetComDir() == COMD_Stop && dir_obj->GetXDir() == 0) || dir_obj->GetProcedure() == "FLIGHT")
{
if (dir_obj->GetDir() == DIR_Left)
@ -368,28 +403,34 @@ func HoldingUseControl(int ctrl, int x, int y, object obj)
}
}
var handled = obj->Call(GetUseCallString("Holding"),this,mex,mey);
var handled = obj->Call(GetUseCallString("Holding"), this, mex, mey);
return handled;
}
// very infrequent timer to prevent dangling effects, this is not necessary for correct functioning
func FxItemRemovalCheckTimer(object target, proplist effect, int time)
{
if (!effect.CommandTarget) return -1;
if (effect.CommandTarget->~GetUsedObject() != target) return -1;
if (!effect.CommandTarget)
return -1;
if (effect.CommandTarget->~GetUsedObject() != target)
return -1;
return 1;
}
// this will be called when an inventory object (that is in use) is suddenly removed
func FxItemRemovalCheckStop(object target, proplist effect, int reason, bool temporary)
{
if (temporary) return;
if (temporary)
return;
// only trigger when the object has been removed
if (reason != FX_Call_RemoveClear) return;
if (reason != FX_Call_RemoveClear)
return;
// safety
if (!effect.CommandTarget) return;
if (effect.CommandTarget->~GetUsedObject() != target) return;
if (!effect.CommandTarget)
return;
if (effect.CommandTarget->~GetUsedObject() != target)
return;
// quickly cancel use in a clean way while the object is still available
effect.CommandTarget->CancelUse();
return;
@ -398,13 +439,13 @@ func FxItemRemovalCheckStop(object target, proplist effect, int reason, bool tem
// Control use redirected to script
func ControlUse2Script(int ctrl, int x, int y, int strength, bool repeat, int status, object obj)
{
{
// standard use
if (ctrl == CON_Use || ctrl == CON_UseAlt)
{
if (status == CONS_Down && !repeat)
{
return StartUseControl(ctrl,x, y, obj);
return StartUseControl(ctrl, x, y, obj);
}
else if (status == CONS_Up && (obj == GetUsedObject() || obj == GetActionTarget()))
{
@ -426,6 +467,6 @@ func ControlUse2Script(int ctrl, int x, int y, int strength, bool repeat, int st
return HoldingUseControl(ctrl, x, y, obj);
}
}
return false;
}