One half of "swinger" recoil system added.

This commit is contained in:
Marisa the Magician 2018-09-15 14:14:34 +02:00
commit c15847a10a
7 changed files with 141 additions and 5 deletions

View file

@ -1156,6 +1156,90 @@ Class ShredCorpseHitbox : Actor
}
}
Enum ESwingMode
{
SWING_Straight, // constant increment
SWING_Spring, // bounces back after a delay
SWING_Spring2, // ... returning at half speed
SWING_Spring3, // ... returning at third speed
};
Class Swinger : Thinker
{
Actor target;
Vector2 dir;
double inc;
int steps, mode, delay;
double str, tstr;
int cnt, cstate;
Enum ESwingerState
{
STATE_Initial,
STATE_Wait,
STATE_Return,
STATE_ReturnSlow,
STATE_ReturnSlower,
};
override void Tick()
{
if ( !target ) cstate = -1;
switch ( cstate )
{
case STATE_Initial:
target.A_SetAngle(target.angle+dir.x*str,SPF_INTERPOLATE);
target.A_SetPitch(target.pitch+dir.y*str,SPF_INTERPOLATE);
str += inc;
if ( ++cnt >= steps )
{
cnt = 0;
str = tstr/steps;
cstate = (mode==SWING_Straight)?(-1):(delay>0)?STATE_Wait:(mode==SWING_Spring3)?STATE_ReturnSlower:(mode==SWING_Spring2)?STATE_ReturnSlow:STATE_Return;
}
else tstr += str;
break;
case STATE_Wait:
if ( ++cnt >= delay )
{
cnt = 0;
cstate = (mode==SWING_Spring3)?STATE_ReturnSlower:(mode==SWING_Spring2)?STATE_ReturnSlow:STATE_Return;
}
break;
case STATE_Return:
target.A_SetAngle(target.angle-dir.x*str,SPF_INTERPOLATE);
target.A_SetPitch(target.pitch-dir.y*str,SPF_INTERPOLATE);
if ( ++cnt >= steps )
{
cnt = 0;
cstate = -1;
}
break;
case STATE_ReturnSlow:
target.A_SetAngle(target.angle-dir.x*str/2.,SPF_INTERPOLATE);
target.A_SetPitch(target.pitch-dir.y*str/2.,SPF_INTERPOLATE);
if ( ++cnt >= steps*2 )
{
cnt = 0;
cstate = -1;
}
break;
case STATE_ReturnSlower:
target.A_SetAngle(target.angle-dir.x*str/3.,SPF_INTERPOLATE);
target.A_SetPitch(target.pitch-dir.y*str/3.,SPF_INTERPOLATE);
if ( ++cnt >= steps*3 )
{
cnt = 0;
cstate = -1;
}
break;
default:
Destroy();
return;
}
}
}
Class GenericFlash : HUDMessageBase
{
Color col;
@ -1555,4 +1639,20 @@ Class UTMainHandler : StaticEventHandler
if ( !Victim ) return;
Victim.vel += HitDirection*(MomentumTransfer/(Thinker.TICRATE*Victim.Mass));
}
static void DoSwing( Actor target, Vector2 dir, double initial, double inc, int steps, int mode = 0, int delay = 0 )
{
let s = new("Swinger");
s.ChangeStatNum(Thinker.STAT_USER);
s.target = target;
s.dir = dir;
s.inc = inc;
s.steps = steps;
s.mode = mode;
s.delay = delay;
s.cnt = 0;
s.cstate = 0;
s.str = initial;
s.tstr = initial;
}
}