Add option to only allow one emergency reboot per map (enforced on nightmare difficulties).
Make Elemental Coating shader less eye-straining. Leave "ashen remains" when a target is erased by the Ynykron. Fix crushers not breaking if player isn't taking damage.
This commit is contained in:
parent
fb003f702e
commit
ea7775119d
10 changed files with 128 additions and 51 deletions
|
|
@ -22,6 +22,7 @@ Class Demolitionist : PlayerPawn
|
|||
SWWMStats mystats;
|
||||
int cairtime;
|
||||
bool hasteleported;
|
||||
bool hasrevived;
|
||||
|
||||
int lastmpain;
|
||||
|
||||
|
|
@ -1328,6 +1329,41 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
}
|
||||
}
|
||||
private void CheckBreakCrusher()
|
||||
{
|
||||
double gaph = (ceilingz-floorz);
|
||||
if ( gaph > height*.6 ) return;
|
||||
// the smaller the gap, the more likely the crusher will snap
|
||||
if ( Random[Demolitionist](0,3) && (FRandom[Demolitionist](0,gaph/height) > .1) ) return;
|
||||
double diffh = 8.+(default.height-gaph); // how much the crusher will have to "snap" after breaking
|
||||
let ceil = ceilingsector;
|
||||
let flor = floorsector;
|
||||
let ceilse = ceil.ceilingdata;
|
||||
let florse = flor.floordata;
|
||||
if ( ceilse && florse )
|
||||
{
|
||||
// snap both planes
|
||||
let q = Spawn("BustedQuake",(ceil.centerspot.x,ceil.centerspot.y,ceil.ceilingplane.ZAtPoint(ceil.centerspot)));
|
||||
q.special1 = 6;
|
||||
q = Spawn("BustedQuake",(flor.centerspot.x,flor.centerspot.y,flor.floorplane.ZAtPoint(flor.centerspot)));
|
||||
q.special1 = 6;
|
||||
SWWMCrusherBroken.Create(flor,ceil,diffh/2.);
|
||||
}
|
||||
else if ( ceilse )
|
||||
{
|
||||
// snap ceiling
|
||||
let q = Spawn("BustedQuake",(ceil.centerspot.x,ceil.centerspot.y,ceil.ceilingplane.ZAtPoint(ceil.centerspot)));
|
||||
q.special1 = 10;
|
||||
SWWMCrusherBroken.Create(null,ceil,diffh);
|
||||
}
|
||||
else if ( florse )
|
||||
{
|
||||
// snap floor
|
||||
let q = Spawn("BustedQuake",(flor.centerspot.x,flor.centerspot.y,flor.floorplane.ZAtPoint(flor.centerspot)));
|
||||
q.special1 = 10;
|
||||
SWWMCrusherBroken.Create(flor,null,diffh);
|
||||
}
|
||||
}
|
||||
override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle )
|
||||
{
|
||||
// we still have to ENSURE ENTIRELY that this gets nullified (TELEFRAG_DAMAGE overrides damage factors somehow)
|
||||
|
|
@ -1338,6 +1374,9 @@ Class Demolitionist : PlayerPawn
|
|||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd ) hnd.tookdamage[PlayerNumber()] = true;
|
||||
}
|
||||
// check if we can break any active crushers
|
||||
if ( (mod == 'Crush') && !inflictor && !source )
|
||||
CheckBreakCrusher();
|
||||
// no damage whatsoever
|
||||
if ( scriptedinvul )
|
||||
return 0;
|
||||
|
|
@ -1832,8 +1871,9 @@ Class Demolitionist : PlayerPawn
|
|||
else if ( (player.cmd.buttons&BT_ATTACK) && (deadtimer > 120) && swwm_revive )
|
||||
{
|
||||
// reboot (if possible)
|
||||
if ( !FindInventory("ReviveCooldown") )
|
||||
if ( !FindInventory("ReviveCooldown") && (((swwm_revivecooldown >= 0) && (G_SkillPropertyInt(SKILLP_ACSReturn) < 4)) || !hasrevived) )
|
||||
{
|
||||
hasrevived = true;
|
||||
player.Resurrect();
|
||||
player.damagecount = 0;
|
||||
player.bonuscount = 0;
|
||||
|
|
@ -1857,7 +1897,7 @@ Class Demolitionist : PlayerPawn
|
|||
SWWMHandler.DoFlash(self,Color(255,128,192,255),30);
|
||||
SWWMScoreObj.Spawn(default.health,Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+Height/2),ST_Health);
|
||||
if ( special1 > 2 ) special1 = 0;
|
||||
if ( swwm_revivecooldown > 0 )
|
||||
if ( (swwm_revivecooldown > 0) && (G_SkillPropertyInt(SKILLP_ACSReturn) < 4) )
|
||||
GiveInventory("ReviveCooldown",1);
|
||||
}
|
||||
else if ( level.maptime > revivefail )
|
||||
|
|
@ -2429,6 +2469,7 @@ Class Demolitionist : PlayerPawn
|
|||
dashfuel = default.dashfuel;
|
||||
last_boost = 0;
|
||||
last_kick = 0;
|
||||
hasrevived = false;
|
||||
// cancel dash/boost
|
||||
A_StopSound(CHAN_JETPACK);
|
||||
fuelcooldown = 0.;
|
||||
|
|
|
|||
|
|
@ -71,43 +71,7 @@ Class AlmasteelPlating : Inventory
|
|||
// 80% reduction for explosions
|
||||
if ( flags&DMG_EXPLOSION ) newdamage = newdamage/5;
|
||||
// 50% reduction for crushing
|
||||
if ( damageType == 'Crush' )
|
||||
{
|
||||
newdamage = newdamage/2;
|
||||
// additionally, check if we can break any active crushers
|
||||
double gaph = (Owner.ceilingz-Owner.floorz);
|
||||
if ( gaph > Owner.height*.6 ) return;
|
||||
// the smaller the gap, the more likely the crusher will snap
|
||||
if ( Random[Demolitionist](0,3) && (FRandom[Demolitionist](0,gaph/Owner.height) > .1) ) return;
|
||||
double diffh = 8.+(Owner.default.height-gaph); // how much the crusher will have to "snap" after breaking
|
||||
let ceil = Owner.ceilingsector;
|
||||
let flor = Owner.floorsector;
|
||||
let ceilse = ceil.ceilingdata;
|
||||
let florse = flor.floordata;
|
||||
if ( ceilse && florse )
|
||||
{
|
||||
// snap both planes
|
||||
let q = Spawn("BustedQuake",(ceil.centerspot.x,ceil.centerspot.y,ceil.ceilingplane.ZAtPoint(ceil.centerspot)));
|
||||
q.special1 = 6;
|
||||
q = Spawn("BustedQuake",(flor.centerspot.x,flor.centerspot.y,flor.floorplane.ZAtPoint(flor.centerspot)));
|
||||
q.special1 = 6;
|
||||
SWWMCrusherBroken.Create(flor,ceil,diffh/2.);
|
||||
}
|
||||
else if ( ceilse )
|
||||
{
|
||||
// snap ceiling
|
||||
let q = Spawn("BustedQuake",(ceil.centerspot.x,ceil.centerspot.y,ceil.ceilingplane.ZAtPoint(ceil.centerspot)));
|
||||
q.special1 = 10;
|
||||
SWWMCrusherBroken.Create(null,ceil,diffh);
|
||||
}
|
||||
else if ( florse )
|
||||
{
|
||||
// snap floor
|
||||
let q = Spawn("BustedQuake",(flor.centerspot.x,flor.centerspot.y,flor.floorplane.ZAtPoint(flor.centerspot)));
|
||||
q.special1 = 10;
|
||||
SWWMCrusherBroken.Create(flor,null,diffh);
|
||||
}
|
||||
}
|
||||
if ( damageType == 'Crush' ) newdamage = newdamage/2;
|
||||
}
|
||||
override bool HandlePickup( Inventory item )
|
||||
{
|
||||
|
|
@ -142,7 +106,7 @@ Class ReviveCooldown : Powerup
|
|||
Default
|
||||
{
|
||||
Inventory.Icon "graphics/HUD/Icons/I_Revive.png";
|
||||
Powerup.Duration -30;
|
||||
Powerup.Duration -60;
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
|
|
@ -156,7 +120,7 @@ Class ReviveCooldown : Powerup
|
|||
{
|
||||
Super.InitEffect();
|
||||
// adjust the duration
|
||||
EffectTics = max(0,swwm_revivecooldown)*GameTicRate;
|
||||
EffectTics = clamp(swwm_revivecooldown*60,0,300)*GameTicRate;
|
||||
}
|
||||
override void EndEffect()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,47 @@
|
|||
// Ynykron projectiles and effects
|
||||
|
||||
// there was an enemy here, but it's gone now
|
||||
Class AshenRemains : Actor
|
||||
{
|
||||
override void Tick()
|
||||
{
|
||||
double fz = CurSector.floorplane.ZAtPoint(pos.xy);
|
||||
if ( fz != pos.z ) SetOrigin((pos.x,pos.y,fz),true);
|
||||
if ( isFrozen() ) return;
|
||||
special1++;
|
||||
if ( special1 > 350 ) A_FadeOut(0.01);
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
if ( (waterlevel > 0) || GetFloorTerrain().isliquid )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
double fz = CurSector.floorplane.ZAtPoint(pos.xy);
|
||||
SetZ(fz);
|
||||
prev.z = fz;
|
||||
SWWMUtility.SetToSlope(self,FRandom[Ynykron](0,360));
|
||||
}
|
||||
default
|
||||
{
|
||||
RenderStyle "Shaded";
|
||||
StencilColor "000000";
|
||||
Radius .1;
|
||||
Height 0.;
|
||||
+NOBLOCKMAP;
|
||||
+NOINTERACTION;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
XZW1 A -1;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
// cheap way to let players know they just got fucking erased from existence
|
||||
Class PlayerGone : PlayerChunk
|
||||
{
|
||||
|
|
@ -360,7 +402,15 @@ Class YnykronImpact : Actor
|
|||
{
|
||||
// voodoo dolls just get erased (how convenient)
|
||||
// otherwise instantly vaporize the fucker
|
||||
if ( tracer.player && (tracer.player.mo != tracer) ) tracer.Destroy();
|
||||
if ( tracer.player && (tracer.player.mo != tracer) )
|
||||
{
|
||||
if ( tracer.pos.z < (tracer.floorz+64) )
|
||||
{
|
||||
let r = Spawn("AshenRemains",tracer.pos);
|
||||
r.scale *= tracer.radius/16.;
|
||||
}
|
||||
tracer.Destroy();
|
||||
}
|
||||
else if ( tracer.CountInv("GrilledCheeseSandwich") > 0 )
|
||||
{
|
||||
// force use the sandwich
|
||||
|
|
@ -382,6 +432,11 @@ Class YnykronImpact : Actor
|
|||
tracer.A_ChangeLinkFlags(true); // remove from blockmap, should guarantee archviles not raising this
|
||||
IDontFeelSoGood.DeletThis(tracer); // ensures corpse is deleted too
|
||||
}
|
||||
if ( tracer.pos.z < (tracer.floorz+64) )
|
||||
{
|
||||
let r = Spawn("AshenRemains",tracer.pos);
|
||||
r.scale *= tracer.radius/16.;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( YnykronShot(master) )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue