forked from Mirrors/openclonk
Crosshair: Use analog stick input properly
- Crosshair doesn't work with a dpad anymore. Supporting dpads adds unnecessary complexity, as a gamepad user with dpad will never be competitive with mouse users. - Crosshair isn't bound to item usage anymore, but will always show when the analog stick is outside of a deadzone. Future planned feature: Also use the actual strength to allow distance input in addition to direction. This is used heavily by Knüppeln.c4s.qteditor^2
parent
93dcb1d729
commit
b8c8bf825c
|
@ -5,61 +5,69 @@
|
|||
Virtual cursor for gamepad controls
|
||||
*/
|
||||
|
||||
local crew, angle, dirx, diry, xpos,ypos, analogaim, aiming, menu;
|
||||
local crew, angle, xpos, ypos, aiming, menu;
|
||||
|
||||
static const CURSOR_Radius = 100;
|
||||
// This is supposed to be a constant, but C4Script doesn't allow constant expressions there.
|
||||
private func CURSOR_Deadzone() { return PLRCON_MaxStrength / 5; }
|
||||
|
||||
protected func Initialize()
|
||||
{
|
||||
this["Visibility"] = VIS_None;
|
||||
dirx = diry = xpos = ypos = 0;
|
||||
SetVisibility(false);
|
||||
xpos = ypos = 0;
|
||||
aiming = false;
|
||||
}
|
||||
|
||||
public func FxMoveTimer()
|
||||
{
|
||||
var speed = 0;
|
||||
var dpad_rotatespeed = 35;
|
||||
var target_angle = Angle(0,0,xpos,ypos)*10;
|
||||
|
||||
// dpad mode
|
||||
if(diry)
|
||||
if (!Visible() && !InDeadzone())
|
||||
{
|
||||
if (diry < 0) speed = -Sin(angle,100,10);
|
||||
else if (diry > 0) speed = +Sin(angle,100,10);
|
||||
angle += dpad_rotatespeed*speed/100;
|
||||
UpdateAnalogpadPos();
|
||||
// The player moved the aiming stick while the crosshair wasn't visible: Use angle directly.
|
||||
angle = target_angle;
|
||||
SetVisibility(true);
|
||||
}
|
||||
if(dirx)
|
||||
else if (!InDeadzone())
|
||||
{
|
||||
if (dirx < 0) speed = -Cos(angle,100,10);
|
||||
else if (dirx > 0) speed = +Cos(angle,100,10);
|
||||
angle += dpad_rotatespeed*speed/100;
|
||||
UpdateAnalogpadPos();
|
||||
}
|
||||
// analog pad mode
|
||||
if(!dirx && !diry)
|
||||
{
|
||||
var target_angle = Angle(0,0,xpos,ypos)*10;
|
||||
var analog_strength = BoundBy(Sqrt(xpos*xpos+ypos*ypos),0,100);
|
||||
|
||||
// Smooth small movements of the stick while the crosshair is visible.
|
||||
var angle_diff = Normalize(target_angle - angle, -1800, 10);
|
||||
if (angle_diff == 0) angle_diff = 1;
|
||||
|
||||
angle = angle + angle_diff * analog_strength / 100 / 8;
|
||||
if (Abs(angle_diff) < 450)
|
||||
angle = angle + angle_diff / 8;
|
||||
else
|
||||
angle = target_angle;
|
||||
}
|
||||
else if (!aiming)
|
||||
{
|
||||
// The player doesn't touch the stick and no item is using the crosshair right now.
|
||||
SetVisibility(false);
|
||||
}
|
||||
|
||||
UpdatePosition();
|
||||
if(aiming) crew->TriggerHoldingControl();
|
||||
crew->TriggerHoldingControl();
|
||||
}
|
||||
|
||||
private func UpdateAnalogpadPos()
|
||||
private func AnalogStrength() { return BoundBy(Sqrt(xpos*xpos+ypos*ypos), 0, PLRCON_MaxStrength); }
|
||||
private func InDeadzone() { return AnalogStrength() < CURSOR_Deadzone(); }
|
||||
private func Visible() { return this.Visibility != VIS_None; }
|
||||
|
||||
// Updates the visibility, returing true if it was changed.
|
||||
private func SetVisibility(bool visible)
|
||||
{
|
||||
xpos = Sin(angle/10,100);
|
||||
ypos = Cos(angle/10,-100);
|
||||
var newvis, oldvis;
|
||||
if (visible)
|
||||
newvis = VIS_Owner;
|
||||
else
|
||||
newvis = VIS_None;
|
||||
oldvis = this.Visibility;
|
||||
this.Visibility = newvis;
|
||||
return newvis != oldvis;
|
||||
}
|
||||
|
||||
public func StartAim(object clonk, bool stealth, object GUImenu)
|
||||
{
|
||||
aiming = true;
|
||||
|
||||
// only reinitialize angle if the crosshair hasn't been there before
|
||||
if(!GetEffect("Move",this))
|
||||
{
|
||||
|
@ -79,22 +87,15 @@ public func StartAim(object clonk, bool stealth, object GUImenu)
|
|||
SetCategory(C4D_StaticBack | C4D_IgnoreFoW);
|
||||
menu = nil;
|
||||
}
|
||||
|
||||
// set starting position for analog pad
|
||||
UpdateAnalogpadPos();
|
||||
|
||||
// Aim somewhere useful if the crosshair wasn't visible before.
|
||||
if (SetVisibility(true))
|
||||
angle = 800*(clonk->GetDir()*2-1);
|
||||
|
||||
crew = clonk;
|
||||
UpdatePosition();
|
||||
RemoveEffect("Move",this);
|
||||
AddEffect("Move",this,1,1,this);
|
||||
|
||||
if(!stealth)
|
||||
{
|
||||
this["Visibility"] = VIS_Owner;
|
||||
crew->SetComDir(COMD_Stop);
|
||||
aiming = true;
|
||||
EnableKeyAimControls(true);
|
||||
}
|
||||
}
|
||||
|
||||
private func UpdatePosition()
|
||||
|
@ -112,65 +113,34 @@ private func UpdatePosition()
|
|||
|
||||
private func MirrorCursor()
|
||||
{
|
||||
return;
|
||||
angle = -Normalize(angle,-1800,10);
|
||||
UpdateAnalogpadPos();
|
||||
}
|
||||
|
||||
public func StopAim()
|
||||
{
|
||||
RemoveEffect("Move",this);
|
||||
this["Visibility"] = VIS_None;
|
||||
dirx = 0;
|
||||
diry = 0;
|
||||
EnableKeyAimControls(false);
|
||||
analogaim = false;
|
||||
aiming = false;
|
||||
}
|
||||
|
||||
private func EnableKeyAimControls(bool enable)
|
||||
{
|
||||
SetPlayerControlEnabled(GetOwner(), CON_AimUp, enable);
|
||||
SetPlayerControlEnabled(GetOwner(), CON_AimDown, enable);
|
||||
SetPlayerControlEnabled(GetOwner(), CON_AimLeft, enable);
|
||||
SetPlayerControlEnabled(GetOwner(), CON_AimRight, enable);
|
||||
}
|
||||
|
||||
public func IsAiming()
|
||||
{
|
||||
return aiming;
|
||||
}
|
||||
|
||||
public func Aim(int ctrl, object clonk, int strength, int repeat, int release)
|
||||
public func Aim(int ctrl, object clonk, int strength, int repeat, int status)
|
||||
{
|
||||
// start (stealth) aiming
|
||||
if(!GetEffect("Move",this))
|
||||
StartAim(clonk,true);
|
||||
|
||||
// aiming with analog pad
|
||||
if (ctrl == CON_AimAxisUp || ctrl == CON_AimAxisDown || ctrl == CON_AimAxisLeft || ctrl == CON_AimAxisRight)
|
||||
if (status == CONS_Moved &&
|
||||
(ctrl == CON_AimAxisUp || ctrl == CON_AimAxisDown || ctrl == CON_AimAxisLeft || ctrl == CON_AimAxisRight))
|
||||
{
|
||||
dirx = diry = 0;
|
||||
|
||||
if(ctrl == CON_AimAxisUp) ypos = -strength;
|
||||
if(ctrl == CON_AimAxisDown) ypos = strength;
|
||||
if(ctrl == CON_AimAxisLeft) xpos = -strength;
|
||||
if(ctrl == CON_AimAxisRight) xpos = strength;
|
||||
analogaim = true;
|
||||
return true;
|
||||
}
|
||||
// stop
|
||||
else if (release && !analogaim)
|
||||
{
|
||||
if(ctrl == CON_AimUp || ctrl == CON_AimDown) diry = 0;
|
||||
else if(ctrl == CON_AimLeft || ctrl == CON_AimRight) dirx = 0;
|
||||
return true;
|
||||
}
|
||||
else if(!release /*&& !repeat */ && !analogaim)
|
||||
{
|
||||
if(ctrl == CON_AimUp) diry = -1;
|
||||
else if(ctrl == CON_AimDown) diry = 1;
|
||||
else if(ctrl == CON_AimLeft) dirx = -1;
|
||||
else if(ctrl == CON_AimRight) dirx = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -239,8 +239,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
|
|||
CON_Left is still called afterwards. So if the clonk finally starts to
|
||||
aim, the virtual cursor already aims into the direction in which he ran
|
||||
*/
|
||||
if (ctrl == CON_AimAxisUp || ctrl == CON_AimAxisDown || ctrl == CON_AimAxisLeft || ctrl == CON_AimAxisRight
|
||||
|| ctrl == CON_AimUp || ctrl == CON_AimDown || ctrl == CON_AimLeft || ctrl == CON_AimRight)
|
||||
if (ctrl == CON_AimAxisUp || ctrl == CON_AimAxisDown || ctrl == CON_AimAxisLeft || ctrl == CON_AimAxisRight)
|
||||
{
|
||||
var success = VirtualCursor()->Aim(ctrl,this,strength,repeat,status);
|
||||
// in any case, CON_Aim* is called but it is only successful if the virtual cursor is aiming
|
||||
|
|
|
@ -59,26 +59,6 @@
|
|||
DefaultDisabled=1
|
||||
CoordinateSpace=Viewport
|
||||
|
||||
[ControlDef]
|
||||
Identifier=AimUp
|
||||
DefaultDisabled=1
|
||||
Hold=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=AimDown
|
||||
DefaultDisabled=1
|
||||
Hold=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=AimLeft
|
||||
DefaultDisabled=1
|
||||
Hold=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=AimRight
|
||||
DefaultDisabled=1
|
||||
Hold=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=AimAxisUp
|
||||
GUIName=$CON_AimAxisUp$
|
||||
|
|
Loading…
Reference in New Issue