352 lines
7.7 KiB
Text
352 lines
7.7 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 ( !hnd.usedamcolors ) hnd.usedamcolors = CVar.FindCVar('swwm_damnums_color');
|
|
if ( hnd.usedamcolors.GetBool() ) 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;
|
|
}
|
|
}
|