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.
This commit is contained in:
parent
7ced29e12d
commit
e422da7cc8
10 changed files with 178 additions and 93 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.3 KiB |
|
|
@ -1,2 +1,2 @@
|
|||
[default]
|
||||
SWWM_MODVER="\chSWWM \cwGZ\c- r441 (Thu 30 Jul 17:35:20 CEST 2020)";
|
||||
SWWM_MODVER="\chSWWM \cwGZ\c- r442 (Fri 31 Jul 16:14:00 CEST 2020)";
|
||||
|
|
|
|||
|
|
@ -15,6 +15,16 @@ enum ESWWMGZChannels
|
|||
CHAN_AMBEXTRA = 63211 // player ambience when submerged
|
||||
};
|
||||
|
||||
enum EDoExplosionFlags
|
||||
{
|
||||
DE_BLAST = 1, // sets BLASTED flag on pushed actors
|
||||
DE_NOBLEED = 2, // does not spawn blood decals on hit
|
||||
DE_NOSPLASH = 4, // like XF_NOSPLASH
|
||||
DE_THRUWALLS = 8, // damages through geometry (no sight check)
|
||||
DE_NOTMISSILE = 16, // instigator is the source itself (normally it'd be its target pointer)
|
||||
DE_EXTRAZTHRUST = 32, // applies a higher Z thrust to enemies on ground
|
||||
};
|
||||
|
||||
// Misc. Utility code
|
||||
Class SWWMUtility
|
||||
{
|
||||
|
|
@ -368,8 +378,8 @@ Class SWWMStats : Thinker
|
|||
{
|
||||
PlayerInfo myplayer;
|
||||
int lastspawn, dashcount, boostcount, stompcount, airtime, kills,
|
||||
deaths, damagedealt, damagetaken, mkill, hiscore, hhiscore,
|
||||
topdealt, toptaken, skill;
|
||||
deaths, damagedealt, hdamagedealt, damagetaken, hdamagetaken,
|
||||
mkill, hiscore, hhiscore, topdealt, toptaken, skill;
|
||||
double grounddist, airdist, fuelusage, topspeed;
|
||||
Array<WeaponUsage> wstats;
|
||||
Array<Class<Weapon> > 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<Weapon> 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<numpt; i++ )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -886,10 +886,31 @@ Class OnFireLight : DynamicLight
|
|||
|
||||
Class OnFire : Actor
|
||||
{
|
||||
OnFire prevfire, nextfire;
|
||||
Actor victim, instigator, lite;
|
||||
int amount, cnt, delay;
|
||||
double oangle;
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd )
|
||||
{
|
||||
hnd.fires_cnt--;
|
||||
if ( !prevfire )
|
||||
{
|
||||
hnd.fires = nextfire;
|
||||
if ( nextfire ) nextfire.prevfire = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevfire.nextfire = nextfire;
|
||||
if ( nextfire ) nextfire.prevfire = prevfire;
|
||||
}
|
||||
}
|
||||
Super.OnDestroy();
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
if ( !victim )
|
||||
|
|
@ -967,17 +988,25 @@ Class OnFire : Actor
|
|||
let t = bt.Thing;
|
||||
if ( !t || !t.bSHOOTABLE || (t.Health <= 0) || (t == victim) || ((t == instigator) && (delay > 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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue