1.2 update w/ GZDoom 4.9 features:

- Changeable player skins.
 - Ammo LEDs are now 1:1 with UT by using canvas textures.
 - Integrate some add-ons, including reskins.
 - Various fixes (some backported from Demolitionist).
 - Migrated from libeye to Gutamatics.
This commit is contained in:
Marisa the Magician 2022-11-05 23:59:16 +01:00
commit 602a89cc68
1761 changed files with 4461 additions and 1597 deletions

View file

@ -1,6 +1,27 @@
// wasn't placeable in UT99
Class WarheadAmmo : Ammo
{
int OldSkin;
void A_CheckSkin()
{
switch ( flak_oldredeemer )
{
case 1:
if ( OldSkin != 1 ) A_ChangeModel("WarheadAmmo220");
OldSkin = 1;
break;
case 2:
if ( OldSkin != 2 ) A_ChangeModel("WarheadAmmo222");
OldSkin = 2;
break;
default:
if ( OldSkin != 0 ) A_ChangeModel("WarheadAmmo");
OldSkin = 0;
break;
}
}
Default
{
Tag "$T_WARHEADAMMO";
@ -16,11 +37,15 @@ Class WarheadAmmo : Ammo
States
{
Spawn:
WMIS A -1;
Stop;
WMIS A 1 A_CheckSkin();
Wait;
}
}
// dummies so we can copy MODELDEF
Class WarheadAmmo220 : Actor abstract {}
Class WarheadAmmo222 : Actor abstract {}
Class ShockWave : Actor
{
double shocksize, olddmgradius;
@ -42,6 +67,18 @@ Class ShockWave : Actor
}
override void PostBeginPlay()
{
switch ( flak_oldredeemer )
{
case 1:
A_ChangeModel("",0,"","",0,"models/220","Shockt1.png");
break;
case 2:
A_ChangeModel("",0,"","",0,"models/222","Shockt1.png");
break;
default:
// change nothing
break;
}
lifespan = ReactionTime;
A_StartSound("warhead/explode",CHAN_VOICE,attenuation:ATTN_NONE);
A_QuakeEx(9,9,9,100,0,12000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:1200,rollIntensity:0.5);
@ -174,7 +211,7 @@ Class WarheadLight : DynamicLight
Destroy();
return;
}
Vector3 taildir = -(cos(target.angle)*cos(target.pitch),sin(target.angle)*cos(target.pitch),-sin(target.pitch));
Vector3 taildir = -dt_Utility.Vec3FromAngle(target.angle,target.pitch);
SetOrigin(level.Vec3Offset(pos,taildir*20),true);
args[LIGHT_INTENSITY] = Random[Warhead](6,8)*10;
}
@ -205,7 +242,7 @@ Class WarheadTrail : Actor
alpha *= FRandom[Puff](0.5,1.5);
ang = FRandom[Puff](0,360);
pt = FRandom[Puff](-90,90);
vel += (cos(pt)*cos(ang),cos(pt)*sin(ang),-sin(pt))*FRandom[Puff](0.2,0.8);
vel += dt_Utility.Vec3FromAngle(ang,pt)*FRandom[Puff](0.2,0.8);
roll = FRandom[Puff](0,360);
}
override void Tick()
@ -227,6 +264,7 @@ Class WarShell : Actor
{
double destangle, destpitch;
Actor l, b;
int OldSkin;
Default
{
@ -274,9 +312,29 @@ Class WarShell : Actor
else if ( vel.length() < 20 ) vel += vel.unit()*0.35;
}
}
void A_CheckSkin()
{
switch ( flak_oldredeemer )
{
case 1:
if ( OldSkin != 1 ) A_ChangeModel("Warshell220");
OldSkin = 1;
break;
case 2:
if ( OldSkin != 2 ) A_ChangeModel("Warshell222");
OldSkin = 2;
break;
default:
if ( OldSkin != 0 ) A_ChangeModel("Warshell");
OldSkin = 0;
break;
}
}
action void A_Trail()
{
Vector3 taildir = -(cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
invoker.A_CheckSkin();
Vector3 taildir = -dt_Utility.Vec3FromAngle(angle,pitch);
if ( waterlevel > 0 )
{
for ( int i=0; i<4; i++ )
@ -386,15 +444,15 @@ Class GuidedWarShell : WarShell
guideangle = lagangle2*0.95+lagangle*0.05;
guidepitch = lagpitch2*0.95+lagpitch*0.05;
guideroll = lagroll2*0.95+lagroll*0.05;
dt_Quat orient = dt_Quat.create_euler(pitch,angle,roll);
dt_Quat angles = dt_Quat.create_euler(guidepitch,guideangle,guideroll);
orient = orient.qmul(angles);
double npitch, nangle, nroll;
[npitch, nangle, nroll] = orient.to_euler();
dt_GM_Quaternion orient = dt_GM_Quaternion.createFromAngles(angle,pitch,roll);
dt_GM_Quaternion angles = dt_GM_Quaternion.createFromAngles(guideangle,guidepitch,guideroll);
orient = orient.multiplyQuat(angles);
double nangle, npitch, nroll;
[nangle, npitch, nroll] = orient.toAngles();
angle = nangle;
pitch = npitch;
roll = nroll;
vel = (vel+(cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch))*0.8).unit()*11;
vel = (vel+dt_Utility.Vec3FromAngle(angle,pitch)*0.8).unit()*11;
}
lagangle2 = lagangle2*0.95+lagangle*0.05;
lagpitch2 = lagpitch2*0.95+lagpitch*0.05;
@ -413,6 +471,10 @@ Class GuidedWarShell : WarShell
}
}
// dummies so we can copy MODELDEF
Class Warshell220 : Actor abstract {}
Class Warshell222 : Actor abstract {}
Class MidTracer : LineTracer
{
override ETraceStatus TraceCallback()
@ -427,31 +489,17 @@ Class MidTracer : LineTracer
}
}
Class TargetActor
{
Vector2 vpos;
String diststr;
}
Class RedeemerHUD : HUDMessageBase
{
Actor Camera;
Vector3 ViewPos;
double ViewAngle, ViewPitch, ViewRoll, LagRoll, LagRoll2;
double ViewAngle, ViewPitch, ViewRoll, LagRoll, LagRoll2, OldLagRoll2;
TextureID reticle1, reticle2, arrow, mark, readout;
Font whfont;
transient ThinkerIterator t;
transient MidTracer tr;
Array<TargetActor> ta;
Shape2D sshape, darrow;
bool dodim;
// libeye stuff
dtLe_ProjScreen proj;
dtLe_GLScreen gl_proj;
dtLe_SWScreen sw_proj;
dtLe_Viewport viewport;
bool can_project;
transient CVar cvar_renderer;
dt_ProjectionData projdata;
RedeemerHUD Init()
{
@ -461,72 +509,14 @@ Class RedeemerHUD : HUDMessageBase
mark = TexMan.CheckForTexture("Crosshr6",TexMan.Type_Any);
readout = TexMan.CheckForTexture("Readout",TexMan.Type_Any);
whfont = Font.GetFont('WHFONT');
sshape = new("Shape2D");
sshape.PushCoord((0,0));
sshape.PushCoord((1,0));
sshape.PushCoord((0,1));
sshape.PushCoord((1,1));
sshape.PushTriangle(0,3,1);
sshape.PushTriangle(0,2,3);
gl_proj = new("dtLe_GLScreen");
sw_proj = new("dtLe_SWScreen");
PrepareProjection();
return self;
}
void PrepareProjection()
{
if ( !cvar_renderer )
cvar_renderer = CVar.GetCVar("vid_rendermode",players[consoleplayer]);
if ( !cvar_renderer )
{
can_project = proj = gl_proj;
return;
}
switch ( cvar_renderer.GetInt() )
{
case 0:
case 1:
proj = sw_proj;
break;
default:
proj = gl_proj;
break;
}
can_project = proj;
}
override bool Tick()
{
PrepareProjection();
LagRoll = dt_Quat.Normalize180(ViewRoll-LagRoll2);
LagRoll2 += dt_Quat.Normalize180(LagRoll-LagRoll2)*0.1;
// shootable targetting
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && !CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() && can_project )
{
viewport.FromHud();
proj.CacheResolution();
proj.CacheFov(players[consoleplayer].fov);
proj.Reorient(ViewPos,(ViewAngle,ViewPitch,ViewRoll));
proj.BeginProjection();
if ( !t ) t = ThinkerIterator.Create("Actor");
if ( !tr ) tr = new("MidTracer");
t.Reinit();
ta.Clear();
Actor a;
Vector3 vdir = (cos(ViewAngle)*cos(ViewPitch),sin(ViewAngle)*cos(ViewPitch),-sin(ViewPitch));
while ( a = Actor(t.Next()) )
{
Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5));
if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue;
proj.ProjectWorldPos(ViewPos+tdir);
Vector2 npos = proj.ProjectToNormal();
if ( !proj.IsInFront() ) continue;
TargetActor te = new("TargetActor");
te.vpos = viewport.SceneToWindow(npos);
te.diststr = String.Format("%f",tdir.length());
te.diststr.Replace(".","");
ta.Push(te);
}
}
LagRoll = Actor.Normalize180(ViewRoll-LagRoll2);
OldLagRoll2 = LagRoll2;
LagRoll2 += Actor.Normalize180(LagRoll-LagRoll2)*0.1;
return !Camera;
}
override void Draw( int bottom, int visibility )
@ -534,71 +524,42 @@ Class RedeemerHUD : HUDMessageBase
if ( visibility != StatusBar.HUDMSGLayer_UnderHUD ) return;
if ( dodim ) Screen.Dim("C8 00 00",0.2,0,0,Screen.GetWidth(),Screen.GetHeight());
// shootable targetting
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && can_project )
if ( flak_redeemerreadout )
{
if ( CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() )
dt_Utility.PrepareProjData(projdata,ViewPos,ViewAngle,ViewPitch,ViewRoll,players[consoleplayer].fov);
if ( !t ) t = ThinkerIterator.Create("Actor");
else t.Reinit();
if ( !tr ) tr = new("MidTracer");
Actor a;
Vector3 vdir = dt_Utility.Vec3FromAngle(ViewAngle,ViewPitch);
while ( a = Actor(t.Next()) )
{
viewport.FromHud();
proj.CacheResolution();
proj.CacheFov(players[consoleplayer].fov);
proj.Reorient(ViewPos,(ViewAngle,ViewPitch,ViewRoll));
proj.BeginProjection();
if ( !t ) t = ThinkerIterator.Create("Actor");
if ( !tr ) tr = new("MidTracer");
t.Reinit();
ta.Clear();
Actor a;
Vector3 vdir = (cos(ViewAngle)*cos(ViewPitch),sin(ViewAngle)*cos(ViewPitch),-sin(ViewPitch));
while ( a = Actor(t.Next()) )
{
Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5));
if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue;
proj.ProjectWorldPos(ViewPos+tdir);
Vector2 npos = proj.ProjectToNormal();
if ( !proj.IsInFront() ) continue;
TargetActor te = new("TargetActor");
te.vpos = viewport.SceneToWindow(npos);
te.diststr = String.Format("%f",tdir.length());
te.diststr.Replace(".","");
ta.Push(te);
}
}
for ( int i=0; i<ta.Size(); i++ )
{
Screen.DrawTexture(mark,false,ta[i].vpos.x,ta[i].vpos.y,DTA_LegacyRenderStyle,STYLE_Add);
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_LegacyRenderStyle,STYLE_Add);
Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5));
if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue;
Vector3 ndc = dt_Utility.ProjectPoint(projdata,ViewPos+tdir);
if ( ndc.z >= 1. ) continue;
Vector2 vpos = dt_Utility.NDCToViewport(projdata,ndc);
String diststr = String.Format("%f",tdir.length());
diststr.Replace(".","");
Screen.DrawTexture(mark,false,vpos.x,vpos.y,DTA_LegacyRenderStyle,STYLE_Add);
Screen.DrawText(whfont,Font.CR_UNTRANSLATED,(vpos.x-whfont.StringWidth(diststr)/2)-12,vpos.y+8,diststr,DTA_LegacyRenderStyle,STYLE_Add);
}
}
// reticle
Vector2 vs = (640,640/Screen.GetAspectRatio());
Vector2 mid, siz, siz2;
[mid, siz] = Screen.VirtualToRealCoords(vs*0.5,(128,128),vs,false,false);
[mid, siz2] = Screen.VirtualToRealCoords(vs*0.5,(8,4),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);
sshape.Clear(Shape2D.C_Verts);
double rrot = -LagRoll2*2;
for ( int i=0; i<4; i++ )
sshape.PushVertex(mid+(verts[i].x*cos(rrot)-verts[i].y*sin(rrot),verts[i].x*sin(rrot)+verts[i].y*cos(rrot)));
Screen.DrawShape(reticle1,false,sshape,DTA_LegacyRenderStyle,STYLE_Add);
sshape.Clear(Shape2D.C_Verts);
verts[0] = (-siz2.x,siz.y+siz2.y);
verts[1] = (siz2.x,siz.y+siz2.y);
verts[2] = (-siz2.x,siz.y+3*siz2.y);
verts[3] = (siz2.x,siz.y+3*siz2.y);
for ( int i=0; i<4; i++ )
sshape.PushVertex(mid+(verts[i].x*cos(rrot)-verts[i].y*sin(rrot),verts[i].x*sin(rrot)+verts[i].y*cos(rrot)));
Screen.DrawShape(arrow,false,sshape,DTA_LegacyRenderStyle,STYLE_Add);
Screen.DrawTexture(reticle2,false,vs.x*0.5,vs.y*0.5,DTA_VirtualWidthF,vs.x,DTA_VirtualHeightF,vs.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Add);
double fractic = System.GetTimeFrac();
double rrot = -(LagRoll2*fractic+OldLagRoll2*(1.-fractic))*2;
double scl = Screen.GetWidth()/640.;
Screen.DrawTexture(reticle1,false,Screen.GetWidth()/2,Screen.GetHeight()/2,DTA_ScaleX,scl,DTA_ScaleY,scl,DTA_LegacyRenderStyle,STYLE_Add,DTA_Rotate,rrot);
Vector2 apos = Actor.AngleToVector(rrot+90,140*scl);
Screen.DrawTexture(arrow,false,Screen.GetWidth()/2+apos.x,Screen.GetHeight()/2+apos.y,DTA_ScaleX,scl,DTA_ScaleY,scl,DTA_LegacyRenderStyle,STYLE_Add,DTA_Rotate,-rrot);
Screen.DrawTexture(reticle2,false,Screen.GetWidth()/2,Screen.GetHeight()/2,DTA_ScaleX,scl,DTA_ScaleY,scl,DTA_LegacyRenderStyle,STYLE_Add);
// faux assembly readout
int numreadouts = int(vs.y/128+2);
for ( int i=0; i<numreadouts; i++ )
double scroll = ((gametic+fractic)*5.)%128;
double y = -scroll*scl;
while ( y < Screen.GetHeight() )
{
int scroll = (gametic*5)%128;
Screen.DrawTexture(readout,false,0,i*128-scroll,DTA_VirtualWidthF,vs.x,DTA_VirtualHeightF,vs.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Add);
Screen.DrawTexture(readout,false,0,y,DTA_ScaleX,scl,DTA_ScaleY,scl,DTA_LegacyRenderStyle,STYLE_Add);
y += 128*scl;
}
}
}
@ -621,44 +582,8 @@ Class RedeemerHUDStatic : HUDMessageBase
override void Draw( int bottom, int visibility )
{
if ( visibility != StatusBar.HUDMSGLayer_UnderHUD ) return;
double sw, sh;
sw = 256.;
sh = sw*(Screen.GetHeight()/double(Screen.GetWidth()));
Screen.DrawTexture(tx,true,0,0,DTA_VirtualWidthF,sw,DTA_VirtualHeightF,sh,DTA_KeepRatio,true);
}
}
Class RedeemerHUDHandler : EventHandler
{
ui RedeemerHUD rhud;
transient ui CVar deemershader;
override void RenderOverlay( RenderEvent e )
{
if ( !deemershader ) deemershader = CVar.GetCVar('flak_deemershader',players[consoleplayer]);
if ( e.Camera is 'GuidedWarShell' )
{
if ( !rhud )
{
rhud = new("RedeemerHUD").Init();
StatusBar.AttachMessage(rhud,0,StatusBar.HUDMSGLayer_UnderHUD);
}
rhud.Camera = e.Camera;
rhud.ViewPos = e.ViewPos;
rhud.ViewAngle = e.ViewAngle;
rhud.ViewPitch = e.ViewPitch;
rhud.ViewRoll = e.ViewRoll;
rhud.dodim = !deemershader.GetBool();
Shader.SetEnabled(players[consoleplayer],"RedeemerView",deemershader.GetBool());
Shader.SetUniform1f(players[consoleplayer],"RedeemerView","Timer",gametic+e.fractic);
}
else if ( rhud )
{
Shader.SetEnabled(players[consoleplayer],"RedeemerView",false);
StatusBar.DetachMessage(rhud);
rhud.Destroy();
StatusBar.AttachMessage(new("RedeemerHUDStatic").Init(),0,StatusBar.HUDMSGLayer_UnderHUD);
}
double scl = max(Screen.GetWidth()/256.,Screen.GetHeight()/256.);
Screen.DrawTexture(tx,true,0,0,DTA_ScaleX,scl,DTA_ScaleY,scl);
}
}
@ -666,9 +591,46 @@ Class WarheadLauncher : UTWeapon
{
transient CVar noswitchdeemer;
Actor guided;
int OldSkin;
override void Tick()
{
Super.Tick();
switch ( flak_oldredeemer )
{
case 1:
if ( OldSkin != 1 )
{
A_ChangeModel("",1,"","",1,"models/220","Jwhpick1.png");
A_ChangeModel("",0,"","",0,"models/220","Jwarhead1.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",1,"models/220","Jwarhead2.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",2,"models/220","Jwarhead3.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",3,"models/220","Jwarhead4.png",CMDL_USESURFACESKIN);
}
OldSkin = 1;
break;
case 2:
if ( OldSkin != 2 )
{
A_ChangeModel("",1,"","",1,"models/222","Jwhpick1.png");
A_ChangeModel("",0,"","",0,"models/222","Jwarhead1.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",1,"models/222","Jwarhead2.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",2,"models/222","Jwarhead3.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",3,"models/222","Jwarhead4.png",CMDL_USESURFACESKIN);
}
OldSkin = 2;
break;
default:
if ( OldSkin != 0 )
{
A_ChangeModel("",1,"","",1,"models","Jwhpick1.png");
A_ChangeModel("",0,"","",0,"models","Jwarhead1.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",1,"models","Jwarhead2.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",2,"models","Jwarhead3.png",CMDL_USESURFACESKIN);
A_ChangeModel("",0,"","",3,"models","Jwarhead4.png",CMDL_USESURFACESKIN);
}
OldSkin = 0;
break;
}
if ( !Owner || !Owner.player ) return;
if ( guided ) crosshair = 99;
else crosshair = 0;
@ -694,7 +656,7 @@ Class WarheadLauncher : UTWeapon
Actor p = Spawn("WarShell",origin);
p.angle = angle;
p.pitch = BulletSlope();
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
p.vel = dt_Utility.Vec3FromAngle(p.angle,p.pitch)*p.speed;
p.target = self;
}
action void A_WarheadSmoke()
@ -732,7 +694,7 @@ Class WarheadLauncher : UTWeapon
Actor p = Spawn("GuidedWarShell",origin);
p.angle = angle;
p.pitch = BulletSlope();
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
p.vel = dt_Utility.Vec3FromAngle(p.angle,p.pitch)*p.speed;
p.target = self;
p.master = invoker;
invoker.guided = p;
@ -774,6 +736,7 @@ Class WarheadLauncher : UTWeapon
+INVENTORY.IGNORESKILL;
+WEAPON.NOAUTOFIRE;
UTWeapon.DropAmmo 1;
UTWeapon.NameColor "FF 80 80";
}
States
{