From e422da7cc855a2468bd2723b73a25979cd507aa8 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Fri, 31 Jul 2020 16:14:00 +0200 Subject: [PATCH] Various things here and there: - Allow total damage dealt/taken stat to go beyond int.max. - Reduce thinker iterator usage in some places (most notably for fire debuffs). - Fix untouchable spree stat tracking. - Allow paying respects when erased by Ynykron. - Correct use of wrong flag (CANNOTPUSH instead of DONTTHRUST) in several spots. - Use LARGE_MASS const instead of its value where needed. - Add flags to DoExplosion, for various things. - Fix missing splashes on DoExplosion. - Allow DoExplosion to set the BLASTED flag, used by ground pound shockwaves. - Add flag to re-enable the higher Z thrust on DoExplosion knockback. - Added a "sweet spot" to berserk shockwaves. - Explodium splash deals more Z thrust, allowing it to send enemies flying when aiming at the feet, as intended. - Adjust a couple things related to player dashing. - Fix player being yeeted when killing a large enemy by stomping. - Tweaked ground pound shockwaves. The ring shockwave only spawns on solid ground now. --- graphics/Achievements/MxWorldwide.png | Bin 7697 -> 7498 bytes language.version | 2 +- zscript/swwm_common.zsc | 144 +++++++++++++++++--------- zscript/swwm_deepdarkimpact.zsc | 2 +- zscript/swwm_inventory.zsc | 2 +- zscript/swwm_menu.zsc | 6 +- zscript/swwm_player.zsc | 45 ++++---- zscript/swwm_shot.zsc | 60 ++++++++--- zscript/swwm_splode.zsc | 4 +- zscript/swwm_tastytreat.zsc | 6 +- 10 files changed, 178 insertions(+), 93 deletions(-) diff --git a/graphics/Achievements/MxWorldwide.png b/graphics/Achievements/MxWorldwide.png index c92b53487a292854c4204f2fe5d38ae96816e175..5816f7406efd9141a26302ce0971f09703a0bcf3 100644 GIT binary patch delta 7292 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 pcL_l wstats; Array > alreadygot; @@ -385,6 +395,39 @@ Class SWWMStats : Thinker return false; } + void AddDamageDealt( int dmg ) + { + int upper = dmg/1000000000; + int lower = dmg%1000000000; + if ( hdamagedealt+upper < hdamagedealt ) hdamagedealt = 999999999; + else hdamagedealt += upper; + damagedealt += lower; + if ( damagedealt > 999999999 ) + { + upper = damagedealt/1000000000; + lower = damagedealt%1000000000; + if ( hdamagedealt+upper < hdamagedealt ) hdamagedealt = 999999999; + else hdamagedealt += upper; + damagedealt = lower; + } + } + void AddDamageTaken( int dmg ) + { + int upper = dmg/1000000000; + int lower = dmg%1000000000; + if ( hdamagetaken+upper < hdamagetaken ) hdamagetaken = 999999999; + else hdamagetaken += upper; + damagetaken += lower; + if ( damagetaken > 999999999 ) + { + upper = damagetaken/1000000000; + lower = damagetaken%1000000000; + if ( hdamagetaken+upper < hdamagetaken ) hdamagetaken = 999999999; + else hdamagetaken += upper; + damagetaken = lower; + } + } + void AddWeaponKill( Actor inflictor ) { Class which = myplayer.ReadyWeapon?myplayer.ReadyWeapon.GetClass():null; @@ -829,6 +872,8 @@ Class SWWMScoreObj : Thinker static SWWMScoreObj Spawn( int score, Vector3 pos, int tcolor = Font.CR_GOLD, Actor acc = null ) { + let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); + if ( !hnd ) return null; let o = new("SWWMScoreObj"); o.ChangeStatNum(STAT_USER); o.score = score; @@ -841,23 +886,19 @@ Class SWWMScoreObj : Thinker o.damnum = (tcolor == Font.CR_RED) || (tcolor == Font.CR_GREEN) || (tcolor == Font.CR_BLUE); o.xcnt = 0; o.acc = acc; - let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); - if ( hnd ) + if ( o.damnum ) { - 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++; - } + 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; } @@ -914,6 +955,8 @@ Class SWWMInterest : Thinker static SWWMInterest Spawn( Vector3 pos = (0,0,0), Key thekey = null, Line theline = null ) { + let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); + if ( !hnd ) return null; if ( (!thekey && !theline) || (thekey && theline) ) return null; let i = new("SWWMInterest"); i.ChangeStatNum(STAT_USER); @@ -931,14 +974,10 @@ Class SWWMInterest : Thinker return null; } i.pos = thekey?thekey.Vec3Offset(0,0,thekey.height/2):pos; - let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); - if ( hnd ) - { - i.next = hnd.intpoints; - if ( hnd.intpoints ) hnd.intpoints.prev = i; - hnd.intpoints = i; - hnd.intpoints_cnt++; - } + i.next = hnd.intpoints; + if ( hnd.intpoints ) hnd.intpoints.prev = i; + hnd.intpoints = i; + hnd.intpoints_cnt++; return i; } @@ -993,9 +1032,10 @@ Class SWWMCombatTracker : Thinker static SWWMCombatTracker Spawn( Actor target ) { - let ti = ThinkerIterator.Create("SWWMCombatTracker",STAT_USER); + let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); + if ( !hnd ) return null; SWWMCombatTracker t; - while ( t = SWWMCombatTracker(ti.Next()) ) + for ( t=hnd.trackers; t; t=t.next ) { if ( t.mytarget != target ) continue; return t; @@ -1018,14 +1058,10 @@ Class SWWMCombatTracker : Thinker t.oldprev = target.prev; t.intp = DynamicValueInterpolator.Create(t.lasthealth,.5,1,100); t.myplayer = target.player; - let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); - if ( hnd ) - { - t.next = hnd.trackers; - if ( hnd.trackers ) hnd.trackers.prev = t; - hnd.trackers = t; - hnd.trackers_cnt++; - } + t.next = hnd.trackers; + if ( hnd.trackers ) hnd.trackers.prev = t; + hnd.trackers = t; + hnd.trackers_cnt++; return t; } @@ -2202,6 +2238,10 @@ Class SWWMHandler : EventHandler transient CVar lang; transient String curlang; + // optimization + OnFire fires; + int fires_cnt; + static void HealthFlash( int p ) { let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); @@ -2825,15 +2865,13 @@ Class SWWMHandler : EventHandler { tookdamage[e.Thing.PlayerNumber()] = true; let s = SWWMStats.Find(e.Thing.player); - if ( s.damagetaken+e.Damage < s.damagetaken ) s.damagetaken = int.max; - else s.damagetaken += e.Damage; + s.AddDamageTaken(e.Damage); if ( e.Damage > s.toptaken ) s.toptaken = e.Damage; } if ( e.DamageSource && e.DamageSource.player ) { let s = SWWMStats.Find(e.DamageSource.player); - if ( s.damagedealt+e.Damage < s.damagedealt ) s.damagedealt = int.max; - else s.damagedealt += e.Damage; + s.AddDamageDealt(e.Damage); if ( e.Damage > s.topdealt ) s.topdealt = e.Damage; } } @@ -2966,7 +3004,7 @@ Class SWWMHandler : EventHandler SWWMScoreObj.Spawn(2000,e.DamageSource.Vec3Offset(0,0,e.DamageSource.Height/2)); } spreecount[pnum]++; - if ( s && spreecount[pnum] > s.skill ) + if ( s && (spreecount[pnum] > s.skill) && !tookdamage[pnum] ) s.skill = spreecount[pnum]; } } @@ -3084,7 +3122,9 @@ Class SWWMHandler : EventHandler if ( e.KeyScan == 33 ) // assuming that's the F key on all keyboards (hopefully) { let demo = Demolitionist(players[consoleplayer].mo); - if ( demo && (demo.Health <= 0) && (demo.deadtimer > 40) ) + let gone = PlayerGone(players[consoleplayer].mo); + if ( (demo && (demo.Health <= 0) && (demo.deadtimer > 40)) + || (gone && (gone.Health <= 0) && (gone.deadtimer > 40)) ) { // pay respects int numf = Random[FInTheChat](1,6); @@ -3660,7 +3700,7 @@ Class SWWMHandler : EventHandler if ( a.bNORADIUSDMG && !Source.bFORCERADIUSDMG && !forceblast ) continue; // massive, no knockback - if ( a.bCANNOTPUSH || (a.Mass >= 10000000) ) + if ( a.bDONTTHRUST || (a.Mass >= Actor.LARGE_MASS) ) continue; // check the DONTHARMCLASS/DONTHARMSPECIES flags if ( !a.player && ((Source.bDONTHARMCLASS && (a.GetClass() == Source.GetClass())) || (Source.bDONTHARMSPECIES && (a.GetSpecies() == Source.GetSpecies()))) ) @@ -3695,7 +3735,7 @@ Class SWWMHandler : EventHandler return; if ( !Victim.bSHOOTABLE && !Victim.bVULNERABLE ) return; - if ( Victim.bCANNOTPUSH || (Victim.Mass >= 10000000) ) + if ( Victim.bDONTTHRUST || (Victim.Mass >= Actor.LARGE_MASS) ) return; Vector3 Momentum = HitDirection*MomentumTransfer; if ( (Victim.pos.z <= Victim.floorz) || !Victim.TestMobjZ() ) @@ -3706,7 +3746,7 @@ Class SWWMHandler : EventHandler // complete spherical and more accurate replacement of A_Explode // 100% free of the buggery GZDoom's own splash damage has - static void DoExplosion( Actor Source, double Damage, double MomentumTransfer, double ExplosionRadius, double FullDamageRadius = 0., Name DamageType = '', Actor ignoreme = null ) + static void DoExplosion( Actor Source, double Damage, double MomentumTransfer, double ExplosionRadius, double FullDamageRadius = 0., int flags = 0, Name DamageType = '', Actor ignoreme = null ) { // debug, display radius sphere if ( swwm_explosiondebug ) @@ -3721,8 +3761,9 @@ Class SWWMHandler : EventHandler s.SetShade("Red"); } } + if ( !(flags&DE_NOSPLASH) ) Source.CheckSplash(ExplosionRadius); double brange = 1./(ExplosionRadius-FullDamageRadius); - Actor Instigator = Source.bMISSILE?Source.target:Source; + Actor Instigator = (flags&DE_NOTMISSILE)?Source:Source.target; BlockThingsIterator bi = BlockThingsIterator.Create(Source,ExplosionRadius*2); // test with doubled radius, just to be sure while ( bi.Next() ) { @@ -3740,7 +3781,7 @@ Class SWWMHandler : EventHandler if ( !a.player && ((Source.bDONTHARMCLASS && (a.GetClass() == Source.GetClass())) || (Source.bDONTHARMSPECIES && (a.GetSpecies() == Source.GetSpecies()))) ) continue; // can we see it - if ( !Source.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) + if ( !(flags&DE_THRUWALLS) && !Source.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; // intersecting? if ( !SWWMUtility.SphereIntersect(a,Source.pos,ExplosionRadius) ) @@ -3760,19 +3801,20 @@ Class SWWMHandler : EventHandler double damagescale = 1.-clamp((dist-a.Radius)*brange,0.,1.); double mm = MomentumTransfer*damagescale; // no knockback if massive/unpushable - if ( (abs(mm) > 0.) && !a.bCANNOTPUSH && (a.Mass < 10000000) ) + if ( (abs(mm) > 0.) && !a.bDORMANT && !a.bDONTTHRUST && (a.Mass < Actor.LARGE_MASS) ) { Vector3 Momentum = dir*mm; if ( (a.pos.z <= a.floorz) || !a.TestMobjZ() ) - Momentum.z = max(Momentum.z,.1*Momentum.length()); + Momentum.z = max(Momentum.z,(flags&DE_EXTRAZTHRUST?.4:.1)*Momentum.length()); Momentum /= Thinker.TICRATE*max(50,a.Mass); // prevent tiny things from getting yeeted at warp speed a.vel += Momentum; + if ( (flags&DE_BLAST) && a.bCANBLAST && !a.bDONTBLAST ) a.bBLASTED = true; } // hit it int dmg = int(Damage*damagescale); if ( dmg <= 0 ) continue; // no harm - int ndmg = a.DamageMobj(Instigator,Source,dmg,(DamageType=='')?Source.DamageType:DamageType,DMG_EXPLOSION,atan2(-dir.y,-dir.x)); - a.TraceBleed((ndmg>0)?ndmg:dmg,Source); + int ndmg = a.DamageMobj(Instigator,Source,dmg,(DamageType!='')?Source.DamageType:DamageType,DMG_EXPLOSION,atan2(-dir.y,-dir.x)); + if ( !(flags&DE_NOBLEED) ) a.TraceBleed((ndmg>0)?ndmg:dmg,Source); } // TODO destructible geometry support } diff --git a/zscript/swwm_deepdarkimpact.zsc b/zscript/swwm_deepdarkimpact.zsc index 5da35c1a2..70488b591 100644 --- a/zscript/swwm_deepdarkimpact.zsc +++ b/zscript/swwm_deepdarkimpact.zsc @@ -355,7 +355,7 @@ Class DeepImpact : SWWMWeapon Vector3 avgdir = list[i].avgdir/list[i].nhits; double avgdist = list[i].avgdist/list[i].nhits; double dmg = 4000.*(1.-clamp(avgdist/300.,0.,1.)); - if ( !list[i].a.bCANNOTPUSH && (list[i].a.mass < LARGE_MASS) ) + if ( !list[i].a.bDONTTHRUST && (list[i].a.mass < LARGE_MASS) ) list[i].a.vel += ((avgdir+(0,0,.35))*dmg/max(50,list[i].a.mass)); list[i].a.DamageMobj(self,self,int(dmg/500.),'Push',DMG_THRUSTLESS); } diff --git a/zscript/swwm_inventory.zsc b/zscript/swwm_inventory.zsc index 871923a6b..a909df559 100644 --- a/zscript/swwm_inventory.zsc +++ b/zscript/swwm_inventory.zsc @@ -572,7 +572,7 @@ Class BigPunchSplash : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - SWWMHandler.DoExplosion(self,special1,40000,120,ignoreme:target); + SWWMHandler.DoExplosion(self,special1,40000,120,60,ignoreme:target); Destroy(); } } diff --git a/zscript/swwm_menu.zsc b/zscript/swwm_menu.zsc index 2123d10f1..2ea861139 100644 --- a/zscript/swwm_menu.zsc +++ b/zscript/swwm_menu.zsc @@ -1959,10 +1959,12 @@ Class SWWMKnowledgeBaseMenu : GenericMenu str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDEATHS"),stats.deaths); Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); yy += 16; - str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDDEALT"),stats.damagedealt); + if ( stats.hdamagedealt > 0 ) str = str = String.Format("\cx%s\c-%d%09d",StringTable.Localize("$SWWM_STATDDEALT"),stats.hdamagedealt,stats.damagedealt); + else str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDDEALT"),stats.damagedealt); Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); yy += 16; - str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDTAKEN"),stats.damagetaken); + if ( stats.hdamagetaken > 0 ) str = String.Format("\cx%s\c-%d%09d",StringTable.Localize("$SWWM_STATDTAKEN"),stats.hdamagetaken,stats.damagetaken); + else str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDTAKEN"),stats.damagetaken); Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); yy += 16; str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATTDEALT"),stats.topdealt); diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index a508d0eff..ea5797500 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -555,7 +555,8 @@ Class Demolitionist : PlayerPawn else { // launch in movement direction (useful for moving platforms) - if ( oldencroached && (dashboost <= 0.) && (lastvelz >= -25) ) vel += oldencroached.vel+level.Vec3Diff(oldencroachedpos,oldencroached.pos); + // make sure we're not getting launched because an enemy just died under our feet, because that can cause some issues + if ( oldencroached && (dashboost <= 0.) && (lastvelz >= -25) && (!oldencroached.bISMONSTER || (oldencroached.Health > 0)) ) vel += oldencroached.vel+level.Vec3Diff(oldencroachedpos,oldencroached.pos); oldencroached = null; } if ( encroached && encroached.bSHOOTABLE && !encroached.bNODAMAGE && (lastvelz <= 0) && !(encroached is 'Demolitionist') ) @@ -614,7 +615,7 @@ Class Demolitionist : PlayerPawn } Vector3 dir = vel+dashdir*dashboost; double spd = dir.length(); - dir = dir.unit(); + dir = dir/spd; Vector3 viewdir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); // look for things we could potentially bump into let bi = BlockThingsIterator.Create(self,500); @@ -623,9 +624,11 @@ Class Demolitionist : PlayerPawn { a = bi.Thing; if ( !a || (a == self) || !a.bSHOOTABLE || a.bTHRUACTORS ) continue; - Vector3 diff = level.Vec3Diff(pos,a.pos); if ( !SWWMUtility.ExtrudeIntersect(self,a,dir*spd,8,16) ) continue; if ( !CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; + Vector3 diff = level.Vec3Diff(pos,a.pos); + Vector3 dirto = diff.unit(); + if ( dir dot dirto < 0 ) continue; // large monsters will stop the player (unless hit from above if we're going at ground pound speed) A_QuakeEx(4,4,4,10,0,128,"",QF_RELATIVE|QF_SCALEDOWN); A_StartSound("demolitionist/bump",CHAN_DAMAGE,CHANF_OVERLAP); @@ -640,15 +643,16 @@ Class Demolitionist : PlayerPawn vel.z += 5+(spd*(10/mass)); dashboost *= .3; } - Vector3 pushdir = Vec3To(a).unit()*.1+dir*.9; + Vector3 pushdir = dirto*.1+dir*.9; if ( !a.bDONTTHRUST && (a.Mass < Mass*1.5) ) { a.vel += pushdir*(15+(spd*20/max(50,a.mass))); - a.vel.z += 5+(spd*(5/max(50,a.mass))); + if ( (a.pos.z <= a.floorz) || !a.TestMobjZ() ) + a.vel.z += 5+(spd*(5/max(50,a.mass))); } int flg = DMG_THRUSTLESS; if ( FindInventory("RagekitPower") ) flg |= DMG_FOILINVUL; - if ( !a.player ) a.bBLASTED = true; + if ( !a.player && !a.bDONTBLAST ) a.bBLASTED = true; int dmg = int(15+spd*2.5); if ( dir dot viewdir < -.3 ) dmg *= 2; // BUTTSLAM dmg = a.DamageMobj(self,self,dmg,'Dash',flg); @@ -1861,7 +1865,7 @@ Class DemolitionistRadiusShockwaveTail : Actor Spawn: SDST A 1 { - A_FadeOut(0.08); + A_FadeOut(.02); A_SetScale(scale.x,scale.y*0.98); } Wait; @@ -1898,8 +1902,9 @@ Class DemolitionistRadiusShockwave : Actor if ( damage <= 0 ) return damage; if ( (target.mass < LARGE_MASS) && !target.bDONTTHRUST ) { - target.vel.xy += vel.xy.unit()*(7000./max(50,target.mass))*alpha; - target.vel.z += (800./max(50,target.mass))*alpha; + target.vel.xy += vel.xy.unit()*(14000./max(50,target.mass))*alpha; + if ( (target.pos.z <= floorz) || !target.TestMobjZ() ) + target.vel.z += (1500./max(50,target.mass))*alpha; } return damage; } @@ -1911,7 +1916,7 @@ Class DemolitionistRadiusShockwave : Actor SetZ(floorz); Spawn("InvisibleSplasher",Vec3Offset(0,0,2)); let s = Spawn("DemolitionistRadiusShockwaveTail",pos); - s.vel = vel*.2; + s.vel = vel*.1; s.scale = scale; s.alpha = alpha; s.angle = angle; @@ -1951,16 +1956,7 @@ Class DemolitionistShockwave : Actor A_StartSound("demolitionist/hardland",CHAN_FOOTSTEP,CHANF_OVERLAP,attenuation:.2,pitch:.7); A_StartSound("demolitionist/hardland",CHAN_FOOTSTEP,CHANF_OVERLAP,attenuation:.1,pitch:.4); } - target.A_Blast(BF_AFFECTBOSSES,200+min(special1*3,100),100+min(special1*2,130),10+min(special1/10,20),"SWWMNothing",""); - A_Explode(40+min(special1,120),100+min(special1*2,130),XF_EXPLICITDAMAGETYPE,damagetype:'GroundPound'); - for ( int i=0; i<360; i+=5 ) - { - let r = Spawn("DemolitionistRadiusShockwave",Vec3Angle(10,i)); - r.target = target; - r.angle = i; - r.vel.xy = (cos(i),sin(i))*(r.speed+min(special1*.15,20)); - r.alpha *= .1+min(special1*.03,.9); - } + SWWMHandler.DoExplosion(self,40+min(special1,120),100000+min(special1*2000,150000),100+min(special1*2,130),80,DE_BLAST|DE_EXTRAZTHRUST,'GroundPound',target); for ( int i=0; i<360; i+=5 ) { Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,3); @@ -1971,6 +1967,15 @@ Class DemolitionistShockwave : Actor s.scale *= 1.5; s.alpha *= .4; } + if ( pos.z > floorz+16 ) return; + for ( int i=0; i<360; i+=5 ) + { + let r = Spawn("DemolitionistRadiusShockwave",Vec3Angle(10,i)); + r.target = target; + r.angle = i; + r.vel.xy = (cos(i),sin(i))*(r.speed+min(special1*.15,20)); + r.alpha *= .1+min(special1*.03,.9); + } int numpt = Random[ExploS](10,20); for ( int i=0; i 0)) || (victim.Distance3D(t) > victim.radius+t.radius+40) || !victim.CheckSight(t) ) continue; int amt = max(1,amount/10); - if ( IsOnFire(t) ) amt = min(5,amt); - Apply(t,instigator,amt); + OnFire of = IsOnFire(t); + if ( of ) + { + amt = min(5,amt); + if ( instigator ) of.instigator = instigator; + of.amount = min(500,of.amount+amt); + of.cnt = min(of.cnt,5); + } + else Apply(t,instigator,amt); } } static OnFire Apply( Actor victim, Actor instigator, int amount, int delay = 0 ) { if ( amount <= 0 ) return null; - let ti = ThinkerIterator.Create("OnFire"); + let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); + if ( !hnd ) return null; OnFire t; - while ( t = OnFire(ti.Next()) ) + for ( t=hnd.fires; t; t=t.nextfire ) { if ( t.victim != victim ) continue; if ( instigator ) t.instigator = instigator; @@ -1000,19 +1029,26 @@ Class OnFire : Actor t.lite = Actor.Spawn("OnFireLight",victim.pos); OnFireLight(t.lite).of = t; t.oangle = victim.angle; + // append + t.nextfire = hnd.fires; + if ( hnd.fires ) hnd.fires.prevfire = t; + hnd.fires = t; + hnd.fires_cnt++; return t; } - static bool IsOnFire( Actor victim ) + static OnFire IsOnFire( Actor victim ) { - let ti = ThinkerIterator.Create("OnFire"); + let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); + if ( !hnd ) return null; OnFire t; - while ( t = OnFire(ti.Next()) ) + for ( t=hnd.fires; t; t=t.nextfire ) { if ( t.victim != victim ) continue; - return (t.amount>0); + if ( t.amount <= 0 ) return null; + return t; } - return false; + return null; } Default @@ -1619,7 +1655,7 @@ Class GoldenImpact : Actor { Super.PostBeginPlay(); A_AlertMonsters(40000); - SWWMHandler.DoExplosion(self,7777,40000,600,500); + SWWMHandler.DoExplosion(self,7777,40000,600,500,DE_EXTRAZTHRUST); A_QuakeEx(9,9,9,40,0,5000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:500,rollintensity:1.5); A_StartSound("spreadgun/goldexpl",CHAN_VOICE,attenuation:.3); A_StartSound("spreadgun/goldexpl",CHAN_WEAPON,attenuation:.15); @@ -1746,7 +1782,7 @@ Class GoldenSubImpact : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - SWWMHandler.DoExplosion(self,777,30000,400,300); + SWWMHandler.DoExplosion(self,777,30000,400,300,DE_EXTRAZTHRUST); A_QuakeEx(7,7,7,20,0,2000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollintensity:.8); A_SprayDecal("BigScorch",-172); Scale *= FRandom[ExploS](0.8,1.1); @@ -1871,7 +1907,7 @@ Class GoldenSubSubImpact : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - SWWMHandler.DoExplosion(self,77,20000,200,100); + SWWMHandler.DoExplosion(self,77,20000,200,100,DE_EXTRAZTHRUST); A_QuakeEx(4,4,4,15,0,1000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:100,rollintensity:.4); A_SprayDecal("Scorch",-172); Scale *= FRandom[ExploS](0.8,1.1); diff --git a/zscript/swwm_splode.zsc b/zscript/swwm_splode.zsc index 6cffc1fc5..4a338d27b 100644 --- a/zscript/swwm_splode.zsc +++ b/zscript/swwm_splode.zsc @@ -135,7 +135,7 @@ Class ExplodiumMagProj : Actor A_SetRenderStyle(1.,STYLE_Add); Scale *= 2.+.2*special1; A_AlertMonsters(6000); - SWWMHandler.DoExplosion(self,20+15*special1,80000+8000*special1,90+10*special1,60); + SWWMHandler.DoExplosion(self,20+15*special1,80000+8000*special1,90+10*special1,60,DE_EXTRAZTHRUST); A_QuakeEx(9,9,9,30,0,400+80*special1,"",QF_RELATIVE|QF_SCALEDOWN,falloff:300,rollintensity:2.); A_StartSound("explodium/maghit",CHAN_VOICE,attenuation:.35); A_StartSound("explodium/maghit",CHAN_WEAPON,attenuation:.2); @@ -229,7 +229,7 @@ Class ExplodiumBulletImpact : Actor { Super.PostBeginPlay(); A_AlertMonsters(3000); - SWWMHandler.DoExplosion(self,25,80000,90,40); + SWWMHandler.DoExplosion(self,25,80000,90,40,DE_EXTRAZTHRUST); A_QuakeEx(4,4,4,10,0,250,"",QF_RELATIVE|QF_SCALEDOWN,falloff:150,rollintensity:0.2); A_StartSound("explodium/hit",CHAN_VOICE,attenuation:.6); A_StartSound("explodium/hit",CHAN_WEAPON,attenuation:.3); diff --git a/zscript/swwm_tastytreat.zsc b/zscript/swwm_tastytreat.zsc index ee7eefc9f..634b21265 100644 --- a/zscript/swwm_tastytreat.zsc +++ b/zscript/swwm_tastytreat.zsc @@ -529,7 +529,7 @@ Class CandyGunProj : Actor A_SetRenderStyle(1.,STYLE_Add); Scale *= 6.+.2*special1; A_AlertMonsters(40000); - SWWMHandler.DoExplosion(self,3500+500*special1,80000+8000*special1,300+20*special1,120); + SWWMHandler.DoExplosion(self,3500+500*special1,80000+8000*special1,300+20*special1,120,DE_EXTRAZTHRUST); A_QuakeEx(9,9,9,70,0,1500+100*special1,"",QF_RELATIVE|QF_SCALEDOWN,falloff:1200,rollintensity:2.); A_StartSound("candygun/gunhit",CHAN_VOICE,attenuation:.24); A_StartSound("candygun/gunhit",CHAN_WEAPON,attenuation:.12); @@ -639,7 +639,7 @@ Class CandyMagProj : Actor A_SetRenderStyle(1.,STYLE_Add); Scale *= 3.+.2*special1; A_AlertMonsters(20000); - SWWMHandler.DoExplosion(self,700+600*special1,80000+8000*special1,150+15*special1,90); + SWWMHandler.DoExplosion(self,700+600*special1,80000+8000*special1,150+15*special1,90,DE_EXTRAZTHRUST); A_QuakeEx(9,9,9,30,0,500+80*special1,"",QF_RELATIVE|QF_SCALEDOWN,falloff:500,rollintensity:2.); A_StartSound("candygun/maghit",CHAN_VOICE,attenuation:.24); A_StartSound("candygun/maghit",CHAN_WEAPON,attenuation:.12); @@ -733,7 +733,7 @@ Class CandyBulletImpact : Actor { Super.PostBeginPlay(); A_AlertMonsters(9000); - SWWMHandler.DoExplosion(self,700,48000,200,80); + SWWMHandler.DoExplosion(self,700,48000,200,80,DE_EXTRAZTHRUST); A_QuakeEx(6,6,6,15,0,300,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollintensity:0.2); A_StartSound("candygun/hit",CHAN_VOICE,attenuation:.25); A_StartSound("candygun/hit",CHAN_WEAPON,attenuation:.5);