swwmgz_m/zscript/hud/swwm_hudobjects.zsc

351 lines
7.6 KiB
Text

// hud-related storage objects
// (used to be thinkers, but this might be lighter on performance)
// floating scores
Class SWWMScoreObj play
{
Array<int> xtcolor;
Array<int> xscore;
Array<String> xstr;
int tcolor;
int score;
Vector3 pos;
int lifespan, initialspan;
int starttic, seed, seed2;
SWWMScoreObj next;
static SWWMScoreObj Spawn( int score, Vector3 pos, int tcolor = -1 )
{
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return null;
return SpawnFromHandler(hnd,score,pos,tcolor);
}
static SWWMScoreObj SpawnFromHandler( SWWMHandler hnd, int score, Vector3 pos, int tcolor = -1 )
{
let o = new("SWWMScoreObj");
o.score = score;
o.pos = pos;
o.lifespan = o.initialspan = 60;
if ( tcolor != -1 ) o.tcolor = tcolor;
else o.tcolor = Font.CR_GOLD;
o.starttic = level.maptime;
o.seed = Random[ScoreBits]();
o.seed2 = Random[ScoreBits]();
o.next = hnd.scorenums;
hnd.scorenums = o;
return o;
}
void AppendXString( String xstr, int xscore = 0, int xtcolor = int.min )
{
self.xscore.Push(xscore);
self.xstr.Push(xstr);
self.xtcolor.Push((xtcolor==int.min)?Font.CR_FIRE:xtcolor);
}
bool Tick()
{
lifespan--;
return (lifespan <= 0);
}
}
// damage/health/armor numbers
Class SWWMDamNum play
{
int tcolor;
int damage;
Vector3 pos;
int lifespan, initialspan;
int starttic, seed, seed2;
SWWMDamNum next;
static SWWMDamNum Spawn( int damage, Vector3 pos, Name type = '' )
{
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return null;
return SpawnFromHandler(hnd,damage,pos,type);
}
static SWWMDamNum SpawnFromHandler( SWWMHandler hnd, int damage, Vector3 pos, Name type = '' )
{
let o = new("SWWMDamNum");
o.damage = damage;
o.pos = pos;
o.tcolor = Font.FindFontColor("MiniRed");
if ( swwm_damnums_color ) for ( int i=0; i<hnd.damtypes.Size(); i++ )
{
if ( hnd.damtypes[i] != type ) continue;
o.tcolor = Font.FindFontColor(hnd.damcolors[i]);
break;
}
o.lifespan = o.initialspan = 60;
o.starttic = level.maptime;
o.seed = Random[ScoreBits]();
o.seed2 = Random[ScoreBits]();
o.next = hnd.damnums;
hnd.damnums = o;
return o;
}
bool Tick()
{
lifespan--;
return (lifespan <= 0);
}
}
enum EInterestType
{
INT_Key,
INT_Exit
};
Class SWWMInterestMarker : MapMarker
{
Default
{
Scale 2.;
Args 0, 0, 1;
+DORMANT;
}
States
{
Spawn:
EIXT ABCD -1;
Stop;
}
}
Class SWWMInterest play
{
int type, exittype;
Key trackedkey;
Line trackedline;
Actor marker;
Vector3 pos;
SWWMInterest next;
String keytag;
static SWWMInterest Spawn( SWWMHandler hnd, Vector3 pos = (0,0,0), Key thekey = null, Line theline = null, int theexit = 0 )
{
if ( (!thekey && !theline) || (thekey && theline) ) return null;
let i = new("SWWMInterest");
i.trackedkey = thekey;
i.trackedline = theline;
if ( thekey )
{
i.type = INT_Key;
i.keytag = thekey.GetTag();
i.marker = Actor.Spawn("SWWMInterestMarker",thekey.pos);
if ( thekey is 'SWWMKey' )
{
Class<Key> k = thekey.species;
let def = GetDefaultByType(k);
i.marker.picnum = def.SpawnState.GetSpriteTexture(0);
}
else i.marker.picnum = thekey.SpawnState.GetSpriteTexture(0);
i.marker.target = thekey;
i.marker.scale = thekey.scale;
i.marker.bDORMANT = !level.allmap;
}
else if ( theline )
{
i.type = INT_Exit;
i.exittype = theexit;
i.marker = Actor.Spawn("SWWMInterestMarker",pos);
i.marker.SetState(i.marker.SpawnState+theexit);
i.marker.bDORMANT = !level.allmap;
}
else
{
i.Destroy();
return null;
}
i.pos = thekey?thekey.Vec3Offset(0,0,thekey.height/2):pos;
i.next = hnd.intpoints;
hnd.intpoints = i;
return i;
}
bool Tick()
{
// update
if ( (type == INT_Key) && (!trackedkey || trackedkey.Owner) )
{
marker.Destroy();
return true;
}
if ( trackedkey )
{
pos = trackedkey.Vec3Offset(0,0,trackedkey.height/2);
marker.SetOrigin(pos,true);
}
return false;
}
}
Class SWWMItemSense play
{
Actor item;
String tag;
int updated;
bool scoreitem, vipitem;
Demolitionist parent;
SWWMItemSense next;
Vector3 pos;
static SWWMItemSense Spawn( Demolitionist parent, Actor item )
{
if ( !parent || !item ) return null;
// only refresh the updated time if existing
for ( SWWMItemSense s=parent.itemsense; s; s=s.next )
{
if ( s.item != item ) continue;
s.updated = level.maptime+35;
s.pos = item.Vec3Offset(0,0,item.height);
return s;
}
let i = new("SWWMItemSense");
i.item = item;
if ( item is 'SWWMRespawnTimer' )
{
i.scoreitem = SWWMUtility.IsScoreItem(item.tracer);
i.vipitem = SWWMUtility.IsVipItem(item.tracer);
}
else
{
i.scoreitem = SWWMUtility.IsScoreItem(item);
i.vipitem = SWWMUtility.IsVipItem(item);
}
i.parent = parent;
i.updated = level.maptime+35;
i.UpdateTag();
i.pos = item.Vec3Offset(0,0,item.height);
i.next = parent.itemsense;
parent.itemsense = i;
return i;
}
void UpdateTag()
{
let i = item;
if ( i is 'SWWMRespawnTimer' ) i = i.tracer;
if ( !i ) return;
// our ammo types use the pickup message, as it's amount-aware
if ( (i is 'SWWMAmmo') || (i is 'MagAmmo') )
tag = Inventory(i).PickupMessage();
else tag = i.GetTag();
}
bool Tick()
{
// expire
if ( !parent || (level.maptime > updated+70) ) return true;
return false;
}
}
// ultralight trackers for certain things
Class SWWMSimpleTracker play
{
Actor target;
double radius;
double angle;
Vector3 pos;
bool isplayer;
Color playercol;
bool ismonster;
bool friendly;
bool countkill;
bool shootable;
bool isitem;
bool countitem;
bool vipitem;
bool expired;
bool ismissile;
bool isbeam, isybeam;
int lastupdate;
ui double smoothalpha; // smoothened alpha, for ui
SWWMSimpleTracker next;
void Update()
{
if ( !target ) return;
isbeam = SWWMUtility.IsBeamProj(target);
isybeam = isbeam&&SWWMUtility.IsYBeam(target);
radius = isybeam?(target.speed*cos(target.pitch+90)):isbeam?(target.speed*cos(target.pitch)):target.radius;
angle = target.angle;
pos = target.pos;
isplayer = target.player;
if ( isplayer ) playercol = target.player.GetColor();
ismonster = target.bISMONSTER;
friendly = target.IsFriend(players[consoleplayer].mo);
countkill = target.bCOUNTKILL;
shootable = target.default.bSHOOTABLE;
ismissile = isbeam||target.default.bMISSILE;
isitem = (target is 'Inventory');
countitem = SWWMUtility.IsScoreItem(target);
vipitem = SWWMUtility.IsVipItem(target);
lastupdate = level.maptime;
if ( isitem )
{
if ( !target.bSPECIAL || Inventory(target).Owner )
expired = true;
else
{
expired = false;
lastupdate += 35;
if ( countitem ) lastupdate += 35;
if ( vipitem ) lastupdate += 70;
}
}
else if ( vipitem )
{
if ( (target is 'Chancebox') && (target.CurState != target.SpawnState) )
expired = true;
else
{
expired = false;
lastupdate += 70;
}
}
else if ( friendly )
{
expired = target.bKILLED;
if ( expired ) lastupdate += 35;
else lastupdate += 140;
}
else if ( ismonster )
{
expired = target.bKILLED||target.bUnmorphed;
if ( !expired )
{
lastupdate += 35;
if ( target.target == players[consoleplayer].mo )
lastupdate += 70;
}
}
else if ( ismissile && !isbeam )
expired = !target.bMISSILE;
else if ( target.default.bSHOOTABLE )
expired = (target.Health<=0);
}
static SWWMSimpleTracker Track( SWWMHandler hnd, Actor target )
{
SWWMSimpleTracker t;
for ( t=hnd.strackers; t; t=t.next )
{
if ( t.target != target ) continue;
t.Update();
return t;
}
t = new("SWWMSimpleTracker");
t.target = target;
t.Update();
t.next = hnd.strackers;
hnd.strackers = t;
return t;
}
}