diff --git a/FuturePlans.md b/FuturePlans.md index c23267638..eef27f6a3 100644 --- a/FuturePlans.md +++ b/FuturePlans.md @@ -111,6 +111,7 @@ All the hard stuff *(some of these aren't guaranteed)*. - Layers of White *(Summon the White Lady)* - Fluffy Moth *(Pet the White Lady 50 times)* - Ara Ara *(Have the White Lady kill a total of 100 enemies)* +* **Re-animate all base models with IK *(important for consistency)*** * **Additional gestures + gesture menu** - Clap - The Bird diff --git a/language.version b/language.version index 896fa342f..bb54c9ace 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.2pre r174 \cu(Mon 28 Feb 17:31:35 CET 2022)\c-"; -SWWM_SHORTVER="\cw1.2pre r174 \cu(2022-02-28 17:31:35)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.2pre r176 \cu(Mon 28 Feb 23:45:18 CET 2022)\c-"; +SWWM_SHORTVER="\cw1.2pre r176 \cu(2022-02-28 23:45:18)\c-"; diff --git a/models/Demolitionist_IK.blend b/models/Demolitionist_IK.blend new file mode 100644 index 000000000..69da8ae7c Binary files /dev/null and b/models/Demolitionist_IK.blend differ diff --git a/models/GibBreast.png b/models/GibBreast.png new file mode 100644 index 000000000..0e8713283 Binary files /dev/null and b/models/GibBreast.png differ diff --git a/models/GibBreast_a.3d b/models/GibBreast_a.3d new file mode 100644 index 000000000..ccd2a102c Binary files /dev/null and b/models/GibBreast_a.3d differ diff --git a/models/GibBreast_d.3d b/models/GibBreast_d.3d new file mode 100644 index 000000000..20f66c5eb Binary files /dev/null and b/models/GibBreast_d.3d differ diff --git a/models/GibDrumstick.png b/models/GibDrumstick.png new file mode 100644 index 000000000..a2d7493f6 Binary files /dev/null and b/models/GibDrumstick.png differ diff --git a/models/GibDrumstick_a.3d b/models/GibDrumstick_a.3d new file mode 100644 index 000000000..e9d4c22e5 Binary files /dev/null and b/models/GibDrumstick_a.3d differ diff --git a/models/GibDrumstick_d.3d b/models/GibDrumstick_d.3d new file mode 100644 index 000000000..9533fb649 Binary files /dev/null and b/models/GibDrumstick_d.3d differ diff --git a/models/GibModels.blend b/models/GibModels.blend new file mode 100644 index 000000000..b1ce7ebfa Binary files /dev/null and b/models/GibModels.blend differ diff --git a/models/GibSteak.png b/models/GibSteak.png new file mode 100644 index 000000000..444457040 Binary files /dev/null and b/models/GibSteak.png differ diff --git a/models/GibSteak_a.3d b/models/GibSteak_a.3d new file mode 100644 index 000000000..454c16317 Binary files /dev/null and b/models/GibSteak_a.3d differ diff --git a/models/GibSteak_d.3d b/models/GibSteak_d.3d new file mode 100644 index 000000000..07932d77a Binary files /dev/null and b/models/GibSteak_d.3d differ diff --git a/zscript.txt b/zscript.txt index d0723b6dc..5a090bdcf 100644 --- a/zscript.txt +++ b/zscript.txt @@ -20,7 +20,6 @@ version "4.7.1" #include "zscript/swwm_handler.zsc" #include "zscript/swwm_statichandler.zsc" #include "zscript/swwm_thinkers.zsc" -#include "zscript/swwm_thinkers_hud.zsc" #include "zscript/swwm_thinkers_player.zsc" #include "zscript/swwm_player.zsc" #include "zscript/swwm_player_fx.zsc" @@ -60,6 +59,7 @@ version "4.7.1" // hud #include "zscript/hud/swwm_hud.zsc" #include "zscript/hud/swwm_hudextra.zsc" +#include "zscript/hud/swwm_hudobjects.zsc" // kbase #include "zscript/kbase/swwm_kbase.zsc" #include "zscript/kbase/swwm_kbase_priv.zsc" diff --git a/zscript/handler/swwm_handler_damage.zsc b/zscript/handler/swwm_handler_damage.zsc index 3c0c835cf..93ecaf0f7 100644 --- a/zscript/handler/swwm_handler_damage.zsc +++ b/zscript/handler/swwm_handler_damage.zsc @@ -277,79 +277,39 @@ extend Class SWWMHandler if ( e.DamageType == 'Push' ) { score += 500; - if ( scr ) - { - scr.xscore[ofs] = 0; - scr.xstr[ofs] = StringTable.Localize("$SWWM_SHAMEFUL"); - scr.xcnt = ++ofs; - } + if ( scr ) scr.AppendXString(StringTable.Localize("$SWWM_SHAMEFUL")); } else if ( e.DamageType == 'Buttslam' ) { score += 300; - if ( scr ) - { - scr.xscore[ofs] = 0; - scr.xstr[ofs] = StringTable.Localize("$SWWM_BUTTSLAM"); - scr.xcnt = ++ofs; - } + if ( scr ) scr.AppendXString(StringTable.Localize("$SWWM_BUTTSLAM")); } else if ( e.DamageType == 'Love' ) { score += 600; - if ( scr ) - { - scr.xscore[ofs] = 0; - scr.xtcolor[ofs] = Font.FindFontColor('BlushPink'); - scr.xstr[ofs] = StringTable.Localize(((e.Thing is 'WolfensteinSS')||(e.Thing.Species=='WolfensteinSS'))?"$SWWM_LOVED_ALT":"$SWWM_LOVED"); - scr.xcnt = ++ofs; - } + if ( scr ) scr.AppendXString(StringTable.Localize(((e.Thing is 'WolfensteinSS')||(e.Thing.Species=='WolfensteinSS'))?"$SWWM_LOVED_ALT":"$SWWM_LOVED"),0,Font.FindFontColor('BlushPink')); } else if ( e.Inflictor is 'FroggyChair' ) { score += 1440; - if ( scr ) - { - scr.xscore[ofs] = 0; - scr.xtcolor[ofs] = Font.CR_GREEN; - scr.xstr[ofs] = StringTable.Localize("$SWWM_FROGGED"); - scr.xcnt = ++ofs; - } + if ( scr ) scr.AppendXString(StringTable.Localize("$SWWM_FROGGED"),0,Font.CR_GREEN); } Inventory pb; if ( e.Inflictor && (pb = e.Inflictor.FindInventory('ParriedBuff')) ) { score += 200; if ( pb.special1&1 ) score += 200; - if ( scr ) - { - scr.xscore[ofs] = 0; - if ( pb.special1&1 ) scr.xstr[ofs] = StringTable.Localize("$SWWM_PPARRY"); - else scr.xstr[ofs] = StringTable.Localize("$SWWM_PARRY"); - scr.xcnt = ++ofs; - } + if ( scr ) scr.AppendXString(StringTable.Localize((pb.special1&1)?"$SWWM_PPARRY":"$SWWM_PARRY")); } if ( (e.Damage >= e.Thing.GetSpawnHealth()*2) || (((e.Thing.Health <= e.Thing.GetGibHealth()) || (src.bEXTREMEDEATH) || (e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.DamageType == 'Extreme')) && !src.bNOEXTREMEDEATH && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH)) ) { score *= 2; - if ( scr ) - { - scr.xscore[ofs] = 0; - scr.xstr[ofs] = StringTable.Localize("$SWWM_OVERKILL"); - scr.xcnt = ++ofs; - } + if ( scr ) scr.AppendXString(StringTable.Localize("$SWWM_OVERKILL")); SWWMUtility.AchievementProgressInc("gib",1,src.player); } score = int(score*(1.+.5*min(multilevel[pnum],16))); if ( (multilevel[pnum] > 0) && scr ) - { - if ( scr ) - { - scr.xscore[ofs] = (multilevel[pnum]>=16)?int.max:(multilevel[pnum]+1); - scr.xstr[ofs] = StringTable.Localize("$SWWM_MULTIKILL"); - scr.xcnt = ++ofs; - } - } + scr.AppendXString(StringTable.Localize("$SWWM_MULTIKILL"),(multilevel[pnum]>=16)?int.max:(multilevel[pnum]+1)); spreecount[pnum]++; if ( s && (spreecount[pnum] > s.skill) && !tookdamage[pnum] ) s.skill = spreecount[pnum]; @@ -360,21 +320,12 @@ extend Class SWWMHandler if ( spreecount[pnum] > 10 ) spreebonus = int(10*((spreecount[pnum]/10.)**.25)); score += 100+spreebonus; if ( (spreecount[pnum] > 0) && scr ) - { - scr.xscore[ofs] = spreecount[pnum]; - scr.xstr[ofs] = StringTable.Localize("$SWWM_SPREEKILL"); - scr.xcnt = ++ofs; - } + scr.AppendXString(StringTable.Localize("$SWWM_SPREEKILL"),spreecount[pnum]); } if ( e.Thing.bBOSS || e.Thing.FindInventory("BossMarker") ) { score += 2000; - if ( scr ) - { - scr.xscore[ofs] = 0; - scr.xstr[ofs] = StringTable.Localize("$SWWM_BOSSKILL"); - scr.xcnt = ++ofs; - } + if ( scr ) scr.AppendXString(StringTable.Localize("$SWWM_BOSSKILL")); } SWWMCredits.Give(src.player,score); if ( scr ) scr.score = score; // update final score diff --git a/zscript/handler/swwm_handler_process.zsc b/zscript/handler/swwm_handler_process.zsc index cbb115706..df4c94722 100644 --- a/zscript/handler/swwm_handler_process.zsc +++ b/zscript/handler/swwm_handler_process.zsc @@ -153,7 +153,13 @@ extend Class SWWMHandler if ( swwm_notrack ) { int n = trackers_cnt; - while ( trackers ) trackers.Destroy(); // wow that's simple, all in one line + while ( trackers ) + { + let next = trackers.next; + trackers.Destroy(); // wow that's simple, all in one line + trackers = next; + } + trackers_cnt = 0; Console.Printf("%d trackers removed.",n); } else @@ -717,5 +723,4 @@ extend Class SWWMHandler } return false; } - } diff --git a/zscript/handler/swwm_handler_worldtick.zsc b/zscript/handler/swwm_handler_worldtick.zsc index e994720a2..54785f37c 100644 --- a/zscript/handler/swwm_handler_worldtick.zsc +++ b/zscript/handler/swwm_handler_worldtick.zsc @@ -223,6 +223,77 @@ extend Class SWWMHandler SWWMUtility.MarkAchievement("wantdie",players[consoleplayer]); } + private void UpdateHUDObjects() + { + // score objects + SWWMScoreObj so = scorenums; + SWWMScoreObj soprev = null, sonext; + while ( so ) + { + sonext = so.next; + if ( so.Tick() ) + { + if ( soprev ) soprev.next = sonext; + else scorenums = sonext; + so.Destroy(); + scorenums_cnt--; + } + else soprev = so; + so = sonext; + } + so = damnums; + soprev = null; + while ( so ) + { + sonext = so.next; + if ( so.Tick() ) + { + if ( soprev ) soprev.next = sonext; + else damnums = sonext; + so.Destroy(); + scorenums_cnt--; + } + else soprev = so; + so = sonext; + } + // interest markers + SWWMInterest ip = intpoints; + SWWMInterest ipprev = null, ipnext; + while ( ip ) + { + ipnext = ip.next; + if ( ip.Tick() ) + { + if ( ipprev ) ipprev.next = ipnext; + else intpoints = ipnext; + ip.Destroy(); + intpoints_cnt--; + } + else ipprev = ip; + ip = ipnext; + } + // combat trackers + SWWMCombatTracker trk = trackers; + SWWMCombatTracker trkprev = null, trknext; + int dbar = swwm_damagetarget; + int mxdist = swwm_maxtargetdist; + while ( trk ) + { + trknext = trk.next; + trk.dbar = dbar; + trk.mxdist = mxdist; + if ( trk.Tick() ) + { + if ( trkprev ) trkprev.next = trknext; + else trackers = trknext; + trk.Destroy(); + trackers_cnt--; + } + else trkprev = trk; + trk = trknext; + } + } + // "simple" tracking (used by the minimap) private void SimpleTracking() { @@ -348,9 +419,10 @@ extend Class SWWMHandler } } SWWMSimpleTracker trk = strackers; + SWWMSimpleTracker prev = null, next; while ( trk ) { - SWWMSimpleTracker next = trk.next; + next = trk.next; // minimize lifespan of destroyed targets if ( !trk.target ) trk.lastupdate = min(trk.lastupdate,level.maptime); else if ( !trk.expired ) @@ -366,12 +438,12 @@ extend Class SWWMHandler // prune expired trackers if ( trk.lastupdate+140 < level.maptime ) { - if ( !trk.prev ) strackers = trk.next; - else trk.prev.next = trk.next; - if ( trk.next ) trk.next.prev = trk.prev; + if ( !prev ) strackers = trk.next; + else prev.next = trk.next; trk.Destroy(); strackers_cnt--; } + else prev = trk; trk = next; } } diff --git a/zscript/hud/swwm_hud.zsc b/zscript/hud/swwm_hud.zsc index b12f45286..80fe09e28 100644 --- a/zscript/hud/swwm_hud.zsc +++ b/zscript/hud/swwm_hud.zsc @@ -1373,7 +1373,7 @@ Class SWWMStatusBar : BaseStatusBar // extra strings (if available) if ( !swwm_scorebonus ) continue; fo.y += smallfont2.GetHeight(); - for ( int i=0; i level.maptime) ) { diff --git a/zscript/swwm_thinkers_hud.zsc b/zscript/hud/swwm_hudobjects.zsc similarity index 78% rename from zscript/swwm_thinkers_hud.zsc rename to zscript/hud/swwm_hudobjects.zsc index 989e254cb..0c1310db5 100644 --- a/zscript/swwm_thinkers_hud.zsc +++ b/zscript/hud/swwm_hudobjects.zsc @@ -1,32 +1,5 @@ -// thinkers related to the hud - -// "Full History" contains all messages since session start, nothing is flushed -// this can be accessed from a section of the knowledge base -Class SWWMFullHistory : Thinker -{ - Array msg; - - static clearscope SWWMFullHistory Get() - { - let fh = SWWMFullHistory(ThinkerIterator.Create("SWWMFullHistory",STAT_STATIC).Next()); - return fh; - } - - static void PushMessage( String str, int tic, int type ) - { - let fh = SWWMFullHistory(ThinkerIterator.Create("SWWMFullHistory",STAT_STATIC).Next()); - if ( !fh ) - { - fh = new("SWWMFullHistory"); - fh.ChangeStatNum(STAT_STATIC); - } - MsgLine m = new("MsgLine"); - m.str = str; - m.tic = tic; - m.type = type; - fh.msg.Push(m); - } -} +// hud-related storage objects +// (used to be thinkers, but this might be lighter on performance) Enum EScoreObjType { @@ -37,18 +10,17 @@ Enum EScoreObjType }; // floating scores -Class SWWMScoreObj : Thinker +Class SWWMScoreObj play { - int xcnt; - int xtcolor[6]; - int xscore[6]; - String xstr[6]; + Array xtcolor; + Array xscore; + Array xstr; int tcolor; int score; Vector3 pos; int lifespan, initialspan; int starttic, seed, seed2; - SWWMScoreObj prev, next; + SWWMScoreObj next; bool damnum; Actor acc; @@ -60,7 +32,6 @@ Class SWWMScoreObj : Thinker let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); if ( !hnd ) return null; let o = new("SWWMScoreObj"); - o.ChangeStatNum(STAT_USER); o.score = score; o.pos = pos; o.lifespan = o.initialspan = 60; @@ -84,58 +55,33 @@ Class SWWMScoreObj : Thinker o.seed = Random[ScoreBits](); o.seed2 = Random[ScoreBits](); o.damnum = (type > ST_Score); - o.xcnt = 0; - for ( int i=0; i<6; i++ ) o.xtcolor[i] = swwm_numcolor_bonus; o.acc = acc; if ( o.damnum ) { o.next = hnd.damnums; - if ( hnd.damnums ) hnd.damnums.prev = o; hnd.damnums = o; hnd.damnums_cnt++; } else { o.next = hnd.scorenums; - if ( hnd.scorenums ) hnd.scorenums.prev = o; hnd.scorenums = o; hnd.scorenums_cnt++; } return o; } - override void OnDestroy() + void AppendXString( String xstr, int xscore = 0, int xtcolor = int.min ) { - let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); - if ( hnd ) - { - if ( damnum ) - { - hnd.damnums_cnt--; - if ( !prev ) hnd.damnums = next; - } - else - { - hnd.scorenums_cnt--; - if ( !prev ) hnd.scorenums = next; - } - if ( !prev ) - { - if ( next ) next.prev = null; - } - else - { - prev.next = next; - if ( next ) next.prev = prev; - } - } - Super.OnDestroy(); + self.xscore.Push(xscore); + self.xstr.Push(xstr); + self.xtcolor.Push((xtcolor==int.min)?swwm_numcolor_bonus:xtcolor); } - override void Tick() + bool Tick() { lifespan--; - if ( lifespan <= 0 ) Destroy(); + return (lifespan <= 0); } } @@ -161,14 +107,14 @@ Class SWWMInterestMarker : MapMarker } } -Class SWWMInterest : Thinker +Class SWWMInterest play { int type, exittype; Key trackedkey; Line trackedline; Actor marker; Vector3 pos; - SWWMInterest prev, next; + SWWMInterest next; String keytag; static SWWMInterest Spawn( Vector3 pos = (0,0,0), Key thekey = null, Line theline = null, int theexit = 0 ) @@ -177,7 +123,6 @@ Class SWWMInterest : Thinker if ( !hnd ) return null; if ( (!thekey && !theline) || (thekey && theline) ) return null; let i = new("SWWMInterest"); - i.ChangeStatNum(STAT_USER); i.trackedkey = thekey; i.trackedline = theline; if ( thekey ) @@ -211,56 +156,36 @@ Class SWWMInterest : Thinker } i.pos = thekey?thekey.Vec3Offset(0,0,thekey.height/2):pos; i.next = hnd.intpoints; - if ( hnd.intpoints ) hnd.intpoints.prev = i; hnd.intpoints = i; hnd.intpoints_cnt++; return i; } - override void OnDestroy() - { - let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); - if ( hnd ) - { - hnd.intpoints_cnt--; - if ( !prev ) - { - hnd.intpoints = next; - if ( next ) next.prev = null; - } - else - { - prev.next = next; - if ( next ) next.prev = prev; - } - } - Super.OnDestroy(); - } - - override void Tick() + bool Tick() { // update if ( (type == INT_Key) && (!trackedkey || trackedkey.Owner) ) { marker.Destroy(); - Destroy(); + return true; } - else if ( trackedkey ) + if ( trackedkey ) { pos = trackedkey.Vec3Offset(0,0,trackedkey.height/2); marker.SetOrigin(pos,true); } + return false; } } -Class SWWMItemSense : Thinker +Class SWWMItemSense play { Actor item; String tag; int updated; bool scoreitem, vipitem; Demolitionist parent; - SWWMItemSense prev, next; + SWWMItemSense next; Vector3 pos; static SWWMItemSense Spawn( Demolitionist parent, Actor item ) @@ -275,7 +200,6 @@ Class SWWMItemSense : Thinker return s; } let i = new("SWWMItemSense"); - i.ChangeStatNum(STAT_USER); i.item = item; if ( item is 'SWWMRespawnTimer' ) { @@ -292,7 +216,6 @@ Class SWWMItemSense : Thinker i.UpdateTag(); i.pos = item.Vec3Offset(0,0,item.height); i.next = parent.itemsense; - if ( parent.itemsense ) parent.itemsense.prev = i; parent.itemsense = i; parent.itemsense_cnt++; return i; @@ -309,39 +232,16 @@ Class SWWMItemSense : Thinker else tag = i.GetTag(); } - override void OnDestroy() + bool Tick() { - if ( parent ) - { - parent.itemsense_cnt--; - if ( !prev ) - { - parent.itemsense = next; - if ( next ) next.prev = null; - } - else - { - prev.next = next; - if ( next ) next.prev = prev; - } - } - Super.OnDestroy(); - } - - override void Tick() - { - if ( !parent ) - { - Destroy(); - return; - } // expire - if ( level.maptime > updated+70 ) Destroy(); + if ( !parent || (level.maptime > updated+70) ) return true; + return false; } } // enemy combat tracker -Class SWWMCombatTracker : Thinker +Class SWWMCombatTracker play { Actor mytarget; String mytag; @@ -349,7 +249,7 @@ Class SWWMCombatTracker : Thinker DynamicValueInterpolator intp; Vector3 pos, prevpos, oldpos, oldprev; PlayerInfo myplayer; - SWWMCombatTracker prev, next; + SWWMCombatTracker next; bool legged, mutated; int tcnt; double height; @@ -388,7 +288,6 @@ Class SWWMCombatTracker : Thinker return t; } t = new("SWWMCombatTracker"); - t.ChangeStatNum(STAT_USER); t.mytarget = target; t.UpdateTag(); if ( target.player ) @@ -408,51 +307,13 @@ Class SWWMCombatTracker : Thinker t.next = hnd.trackers; t.bBOSS = target.bBOSS; t.bFRIENDLY = target.IsFriend(players[consoleplayer].mo); - if ( hnd.trackers ) - { - hnd.trackers.prev = t; - // propagate cvar values - t.mxdist = hnd.trackers.mxdist; - t.dbar = hnd.trackers.dbar; - } hnd.trackers = t; hnd.trackers_cnt++; return t; } - override void OnDestroy() + bool Tick() { - let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); - if ( hnd ) - { - hnd.trackers_cnt--; - if ( !prev ) - { - hnd.trackers = next; - if ( next ) next.prev = null; - } - else - { - prev.next = next; - if ( next ) next.prev = prev; - } - } - Super.OnDestroy(); - } - - override void Tick() - { - // only the first tracker accesses the CVars, saves on perf - if ( !prev ) - { - dbar = swwm_damagetarget; - mxdist = swwm_maxtargetdist; - } - if ( next ) - { - next.dbar = dbar; - next.mxdist = mxdist; - } // is target gone or dead? if ( !mytarget || (mytarget.Health <= 0) ) { @@ -461,12 +322,12 @@ Class SWWMCombatTracker : Thinker lasthealth = 0; prevpos = pos; // prevent stuttering intp.Update(lasthealth); - if ( level.maptime > updated+35 ) Destroy(); - return; + if ( level.maptime > updated+35 ) return true; + return false; } // don't update dormant targets if ( mytarget.bDORMANT ) - return; + return false; // only update height/position while alive bool heightchanged = false; if ( height != mytarget.height ) heightchanged = true; @@ -504,8 +365,7 @@ Class SWWMCombatTracker : Thinker t.bUpdateMorph = true; t.unmorphedtag = t.mytag; t.mytag = String.Format("%s (%s)",mytag,t.unmorphedtag); - Destroy(); - return; + return true; } } } @@ -542,9 +402,9 @@ Class SWWMCombatTracker : Thinker if ( dbar && !mytarget.player ) { if ( (dbar == 2) && (lasthealth >= maxhealth) ) - return; + return false; else if ( (dbar == 1) && !firsthit ) - return; + return false; } if ( (mytarget.bISMONSTER || mytarget.player) && !mytarget.bINVISIBLE && !mytarget.bCORPSE ) { @@ -567,11 +427,12 @@ Class SWWMCombatTracker : Thinker // special stuff, only if visible if ( ((mxdist <= 0) || (mytarget.Vec3To(players[consoleplayer].Camera).length() < (mxdist/4))) && players[consoleplayer].Camera.CheckSight(mytarget,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) updated = level.maptime; } + return false; } } // ultralight trackers for certain things -Class SWWMSimpleTracker : Thinker +Class SWWMSimpleTracker play { Actor target; double radius; @@ -591,7 +452,7 @@ Class SWWMSimpleTracker : Thinker bool isbeam; int lastupdate; ui double smoothalpha; // smoothened alpha, for ui - SWWMSimpleTracker prev, next; + SWWMSimpleTracker next; void Update() { @@ -667,11 +528,9 @@ Class SWWMSimpleTracker : Thinker return t; } t = new("SWWMSimpleTracker"); - t.ChangeStatNum(STAT_INFO); t.target = target; t.Update(); t.next = hnd.strackers; - if ( hnd.strackers ) hnd.strackers.prev = t; hnd.strackers = t; hnd.strackers_cnt++; return t; diff --git a/zscript/swwm_handler.zsc b/zscript/swwm_handler.zsc index 9ef70efea..54d6098f6 100644 --- a/zscript/swwm_handler.zsc +++ b/zscript/swwm_handler.zsc @@ -145,6 +145,7 @@ Class SWWMHandler : EventHandler ItemCountTrack(); CombatTrack(); OneHundredPercentCheck(); + UpdateHUDObjects(); SimpleTracking(); VanillaBossTick(); if ( !profiling ) return; diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index aa5b16b9d..572da3468 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -521,18 +521,36 @@ Class Demolitionist : PlayerPawn } void SenseItems() { - let bt = BlockThingsIterator.Create(self,800); - while ( bt.Next() ) + if ( player.cmd.buttons&BT_USER3 ) { - let i = bt.Thing; - if ( !i || (!(i is 'Inventory') && !(i is 'Chancebox') && !(i is 'SWWMRespawnTimer')) ) continue; - if ( (i is 'Inventory') && (i.bINVISIBLE || !i.bSPECIAL || Inventory(i).Owner) ) continue; - if ( (i is 'Chancebox') && (i.CurState != i.SpawnState) ) continue; - if ( !SWWMUtility.SphereIntersect(i,pos,800) ) continue; - if ( !level.allmap && !CheckSight(i,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; - SWWMItemSense.Spawn(self,i); + let bt = BlockThingsIterator.Create(self,800); + while ( bt.Next() ) + { + let i = bt.Thing; + if ( !i || (!(i is 'Inventory') && !(i is 'Chancebox') && !(i is 'SWWMRespawnTimer')) ) continue; + if ( (i is 'Inventory') && (i.bINVISIBLE || !i.bSPECIAL || Inventory(i).Owner) ) continue; + if ( (i is 'Chancebox') && (i.CurState != i.SpawnState) ) continue; + if ( !SWWMUtility.SphereIntersect(i,pos,800) ) continue; + if ( !level.allmap && !CheckSight(i,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; + SWWMItemSense.Spawn(self,i); + } + bt.Destroy(); + } + SWWMItemsense itm = itemsense; + SWWMItemsense prev = null, next; + while ( itm ) + { + next = itm.next; + if ( itm.Tick() ) + { + if ( prev ) prev.next = next; + else itemsense = next; + itm.Destroy(); + itemsense_cnt--; + } + else prev = itm; + itm = next; } - bt.Destroy(); } void CheckDefaceTexture() { @@ -1070,7 +1088,7 @@ Class Demolitionist : PlayerPawn } else mystats.swimdist += traveldist; CheckUnderwaterAmb(); - if ( player.cmd.buttons&BT_USER3 ) SenseItems(); + SenseItems(); if ( vel.length() > mystats.topspeed ) mystats.topspeed = vel.length(); if ( vel.length() > ((3600*GameTicRate)/32000.) ) SWWMUtility.AchievementProgress("sanic",int((vel.length()*3600*GameTicRate)/32000.),player); diff --git a/zscript/swwm_thinkers_player.zsc b/zscript/swwm_thinkers_player.zsc index b2f1c1316..4fd8c5a55 100644 --- a/zscript/swwm_thinkers_player.zsc +++ b/zscript/swwm_thinkers_player.zsc @@ -1,5 +1,33 @@ // player-specific thinkers +// "Full History" contains all messages since session start, nothing is flushed +// this can be accessed from a section of the knowledge base +Class SWWMFullHistory : Thinker +{ + Array msg; + + static clearscope SWWMFullHistory Get() + { + let fh = SWWMFullHistory(ThinkerIterator.Create("SWWMFullHistory",STAT_STATIC).Next()); + return fh; + } + + static void PushMessage( String str, int tic, int type ) + { + let fh = SWWMFullHistory(ThinkerIterator.Create("SWWMFullHistory",STAT_STATIC).Next()); + if ( !fh ) + { + fh = new("SWWMFullHistory"); + fh.ChangeStatNum(STAT_STATIC); + } + MsgLine m = new("MsgLine"); + m.str = str; + m.tic = tic; + m.type = type; + fh.msg.Push(m); + } +} + // Stats Class WeaponUsage {