Implemented "six degrees of freedom" movement for guided redeemer missiles (reload/zoom for manual tilt control).

Made part of the guided redeemer reticle rotate according to the missile's roll just to show off Shape2D.
This commit is contained in:
Marisa the Magician 2018-08-14 02:57:44 +02:00
commit b24ee842ba
5 changed files with 144 additions and 21 deletions

View file

@ -355,15 +355,13 @@ Class WarShell : Actor
Class GuidedWarShell : WarShell
{
double lagangle, lagpitch, lagangle2, lagpitch2;
double guideangle, guidepitch, lastguideroll;
double lagangle, lagpitch, lagroll, lagangle2, lagpitch2, lagroll2,
guideangle, guidepitch, guideroll;
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( target && target.player ) target.player.camera = self;
guideangle = angle;
guidepitch = pitch;
}
override void Tick()
{
@ -385,22 +383,25 @@ Class GuidedWarShell : WarShell
{
lagangle = target.player.cmd.yaw/128.;
lagpitch = -target.player.cmd.pitch/128.;
guideangle += lagangle2*0.95+lagangle*0.05;
guidepitch += lagpitch2*0.95+lagpitch*0.05;
guidepitch = Clamp(guidepitch,-89,89);
double guideroll = -lagangle2*15;
Vector3 dir = (cos(guideangle)*cos(guidepitch),sin(guideangle)*cos(guidepitch),-sin(guidepitch));
destangle = atan2(dir.y,dir.x);
destpitch = asin(-dir.z);
double destroll = lastguideroll*0.9+guideroll*0.1;
A_SetAngle(destangle,SPF_INTERPOLATE);
A_SetPitch(destpitch,SPF_INTERPOLATE);
A_SetRoll(destroll,SPF_INTERPOLATE);
if ( target.player.cmd.buttons&BT_RELOAD ) lagroll = 5;
else if ( target.player.cmd.buttons&BT_ZOOM ) lagroll = -5;
else lagroll = 0;
guideangle = lagangle2*0.95+lagangle*0.05;
guidepitch = lagpitch2*0.95+lagpitch*0.05;
guideroll = lagroll2*0.95+lagroll*0.05;
Quat orient = Quat.create_euler(pitch,angle,roll);
Quat angles = Quat.create_euler(guidepitch,guideangle,guideroll);
orient = orient.qmul(angles);
double npitch, nangle, nroll;
[npitch, nangle, nroll] = orient.to_euler();
A_SetAngle(nangle,SPF_INTERPOLATE);
A_SetPitch(npitch,SPF_INTERPOLATE);
A_SetRoll(nroll,SPF_INTERPOLATE);
vel = (vel+(cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch))*0.8).unit()*11;
}
lagangle2 = lagangle2*0.95+lagangle*0.05;
lagpitch2 = lagpitch2*0.95+lagpitch*0.05;
lastguideroll = roll*0.98;
lagroll2 = lagroll2*0.95+lagroll*0.05;
}
States
{
@ -439,25 +440,36 @@ Class RedeemerHUD : HUDMessageBase
{
Actor Camera;
Vector3 ViewPos;
double ViewAngle, ViewPitch, ViewRoll;
TextureID reticle, mark, readout;
double ViewAngle, ViewPitch, ViewRoll, LagRoll, LagRoll2;
TextureID reticle1, reticle2, mark, readout;
Font whfont;
ThinkerIterator t;
MidTracer tr;
Array<TargetActor> ta;
Shape2D rreticle;
RedeemerHUD Init()
{
reticle = TexMan.CheckForTexture("GuidedX",TexMan.Type_Any);
reticle1 = TexMan.CheckForTexture("GuidedX1",TexMan.Type_Any);
reticle2 = TexMan.CheckForTexture("GuidedX2",TexMan.Type_Any);
mark = TexMan.CheckForTexture("Crosshr6",TexMan.Type_Any);
readout = TexMan.CheckForTexture("Readout",TexMan.Type_Any);
whfont = Font.GetFont('WHFONT');
t = ThinkerIterator.Create("Actor");
tr = new("MidTracer");
rreticle = new("Shape2D");
rreticle.PushCoord((0,0));
rreticle.PushCoord((1,0));
rreticle.PushCoord((0,1));
rreticle.PushCoord((1,1));
rreticle.PushTriangle(0,3,1);
rreticle.PushTriangle(0,2,3);
return self;
}
override bool Tick()
{
LagRoll = Quat.Normalize180(ViewRoll-LagRoll2);
LagRoll2 += Quat.Normalize180(LagRoll-LagRoll2)*0.1;
// shootable targetting
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() )
{
@ -494,8 +506,21 @@ Class RedeemerHUD : HUDMessageBase
Screen.DrawText(whfont,Font.CR_UNTRANSLATED,(ta[i].vpos.x-whfont.StringWidth(ta[i].diststr)/2)-12,ta[i].vpos.y+8,ta[i].diststr,DTA_RenderStyle,(1|2<<8|1<<16));
}
}
// other stuff
Screen.DrawTexture(reticle,false,320,240,DTA_VirtualWidth,640,DTA_VirtualHeight,480,DTA_RenderStyle,(1|2<<8|1<<16));
// reticle
Vector2 vs = (640,640/Screen.GetAspectRatio());
Vector2 mid, siz;
[mid, siz] = Screen.VirtualToRealCoords(vs*0.5,(128,128),vs,false,false);
Vector2 verts[4];
verts[0] = (-siz.x,-siz.y);
verts[1] = (siz.x,-siz.y);
verts[2] = (-siz.x,siz.y);
verts[3] = (siz.x,siz.y);
rreticle.Clear(Shape2D.C_Verts);
for ( int i=0; i<4; i++ )
rreticle.PushVertex(mid+(verts[i].x*cos(LagRoll2)-verts[i].y*sin(LagRoll2),verts[i].x*sin(LagRoll2)+verts[i].y*cos(LagRoll2)));
Screen.DrawShape(reticle1,false,rreticle,DTA_RenderStyle,(1|2<<8|1<<16));
Screen.DrawTexture(reticle2,false,vs.x*0.5,vs.y*0.5,DTA_VirtualWidthF,vs.x,DTA_VirtualHeightF,vs.y,DTA_KeepRatio,true,DTA_RenderStyle,(1|2<<8|1<<16));
// faux assembly readout
int numreadouts = Screen.GetHeight()/128+2;
for ( int i=0; i<numreadouts; i++ )
{