From 0e12ca15c872e2fdac79187a69936c062fceed2b Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Thu, 18 Feb 2021 20:53:28 +0100 Subject: [PATCH] Remove global 50% damage reduction for players (a bit too cheap). Add 50% crusher damage reduction + chance to break crushers. Don't spawn gibs when using 'kill monsters'. Allow player to "fake pick up" unsupported vanilla armor, so specials and item counters can still work. --- FuturePlans.md | 1 - README.md | 2 +- language.version | 4 +- zscript/swwm_handler.zsc | 4 +- zscript/swwm_player.zsc | 48 ++++++++++++++++-- zscript/swwm_thinkers.zsc | 102 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 10 deletions(-) diff --git a/FuturePlans.md b/FuturePlans.md index d6d707ee1..5454ddb06 100644 --- a/FuturePlans.md +++ b/FuturePlans.md @@ -20,7 +20,6 @@ This is just a bit of *"future planning"* for stuff that I ***might*** add after - Manarock *("A delicacy for gods, but instantly deadly for mortals")* - Rubber Duck *("Is this some kind of convoluted joke from those two?")* * ***(Maybe)* Fake livestream chat overlay, with dynamic reactions to all sorts of stuff** -* **Crusher breaking *(if possible)*** * **Replace all hitscan with *"light projectiles"*** * **Leaning and a lot of other stuff involving ViewAngles and ViewPos** * **Crouch sliding *(+ proper crouch dashing)*** diff --git a/README.md b/README.md index d9337dbea..26a95e5fb 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Additional features: - **Glowing color tags:** Located around various parts of your body, allows quick and easy differentiation between multiple units (color not directly configurable due to *engine limitations™*). - **Lucky Collar:** A little something that your creator gives to all of her creations. Reduces incoming damage by 75% when you're below 25% health. Plus an additional 50% reduction to any damage from your own weapons. - - **High-Resonant Almasteel Plating:** Your chassis is built from one of the hardest alloys known across the universe. Thus, your body is practically indestructible, but not impervious to damage. All direct damage is reduced by 50%, and all explosive damage is reduced by 80%. + - **High-Resonant Almasteel Plating:** Your chassis is built from one of the hardest alloys known across the universe. Thus, your body is practically indestructible, but not impervious to damage. All splash damage is reduced by 80%, and you only take half damage from crushers (and may cause them to break, permanently). - **User Menu:** With the press of a button, open a dedicated menu to see all your stats in detail, info on carried items and weapons, check out a grand library of information on things you come across, and access the store for buying extra items with your score points. - **Magnetic Utility Belt:** Holds important equipment tightly, and is also the secret to how you can reload some weapons so damn fast. - **Keychain:** A lil' something to bring some extra good luck charms with you. diff --git a/language.version b/language.version index 0d4e54b69..3d5cfa4df 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r286 \cu(Thu 18 Feb 00:55:57 CET 2021)\c-"; -SWWM_SHORTVER="\cw0.9.11b-pre r286 \cu(2021-02-18 00:55:57)\c-"; +SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r287 \cu(Thu 18 Feb 20:53:28 CET 2021)\c-"; +SWWM_SHORTVER="\cw0.9.11b-pre r287 \cu(2021-02-18 20:53:28)\c-"; diff --git a/zscript/swwm_handler.zsc b/zscript/swwm_handler.zsc index 5cf4700a6..4e334623c 100644 --- a/zscript/swwm_handler.zsc +++ b/zscript/swwm_handler.zsc @@ -1486,8 +1486,8 @@ Class SWWMHandler : EventHandler // gibbing private void DoGibThing( WorldEvent e ) { - // no gib if it was erased - if ( e.DamageType == 'Ynykron' ) return; + // no gib if it was erased or used the kill monsters cheat + if ( (e.DamageType == 'Ynykron') || (e.DamageType == 'Massacre') ) return; int gibhealth = e.Thing.GetGibHealth(); bool gotgibbed = (!e.Thing.bDONTGIB && ((e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.DamageSource && e.DamageSource.bEXTREMEDEATH) || (e.DamageType == 'Extreme') || (e.Thing.Health < gibhealth)) && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH) && (!e.DamageSource || !e.DamageSource.bNOEXTREMEDEATH)); bool forcegibbed = false; diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index c7f6d6e11..72c50d16e 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -89,7 +89,6 @@ Class Demolitionist : PlayerPawn DamageFactor "Poison", 0.; DamageFactor "PoisonCloud", 0.; DamageFactor "Falling", 0.; - DamageFactor "Crush", .25; Demolitionist.DashFuel 240.; +NOBLOOD; +DONTGIB; @@ -2634,15 +2633,56 @@ Class AlmasteelPlating : Inventory { if ( inflictor && (inflictor is 'CorrodeDebuff') ) dbf = Inventory(inflictor); if ( (damage <= 0) || (flags&(DMG_FORCED|DMG_NO_ARMOR)) ) return; - // 50% reduction for normal damage, 80% reduction for explosions - if ( flags&DMG_EXPLOSION ) newdamage = max(1,damage/5); - else newdamage = max(1,damage/2); + newdamage = damage; + // 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); + } + } } override bool HandlePickup( Inventory item ) { // disallow vanilla armors if ( (item is 'BasicArmor') || (item is 'BasicArmorBonus') || (item is 'BasicArmorPickup') || (item is 'HexenArmor') ) + { + item.bPickupGood = true; // but act as if we picked them up return true; + } return false; } override void AttachToOwner( Actor other ) diff --git a/zscript/swwm_thinkers.zsc b/zscript/swwm_thinkers.zsc index 2bf384e10..ca5a6fe3d 100644 --- a/zscript/swwm_thinkers.zsc +++ b/zscript/swwm_thinkers.zsc @@ -1205,3 +1205,105 @@ Class SWWMDamageAccumulator : Thinker return 0; } } + +// prevents floors/ceilings from ever moving again, as they're "broken crushers" +Class SWWMCrusherBroken : Thinker +{ + Sector fsec, csec; + double diffh; + int fphase, cphase; + int ftics, ctics; + + static void Create( Sector f, Sector c, double diffh ) + { + if ( !f && !c ) return; + let ti = ThinkerIterator.Create("SWWMCrusherBroken",STAT_USER); + SWWMCrusherBroken cb; + while ( cb = SWWMCrusherBroken(ti.Next()) ) + { + if ( (cb.fsec == f) && (cb.csec == c) ) + return; // we already have this + if ( cb.fsec && (cb.fsec == f) ) + { + cb.Destroy(); // we override this one + continue; + } + if ( cb.csec && (cb.csec == c) ) + { + cb.Destroy(); // we override this one + continue; + } + } + cb = new("SWWMCrusherBroken"); + cb.fsec = f; + cb.csec = c; + cb.ChangeStatNum(STAT_USER); + cb.diffh = diffh; + if ( f && f.floordata ) f.floordata.Destroy(); + if ( c && c.ceilingdata ) c.ceilingdata.Destroy(); + } + + override void Tick() + { + if ( fsec ) + { + if ( cphase <= 0 ) + { + if ( level.CreateFloor(fsec,Floor.floorLowerByValue,null,16.,diffh*.4) ) + { + ftics = int(diffh*.4/16.)+40; + fphase = 1; + } + } + else if ( fphase == 1 ) + { + ftics--; + if ( (ftics <= 0) && level.CreateFloor(fsec,Floor.floorLowerByValue,null,1.,diffh*.6) ) + { + ftics = int(diffh*.6)+8; + fphase = 2; + } + } + else if ( fphase == 2 ) + { + ftics--; + if ( ftics <= 0 ) fphase = 3; + } + else if ( (fphase >= 3) && fsec.floordata ) + { + fsec.floordata.Destroy(); + fsec.StopSoundSequence(CHAN_WEAPON); + } + } + if ( csec ) + { + if ( cphase <= 0 ) + { + if ( level.CreateCeiling(csec,Ceiling.ceilRaiseByValue,null,16.,16.,diffh*.4) ) + { + ctics = int(diffh*.4/16.)+40; + cphase = 1; + } + } + else if ( cphase == 1 ) + { + ctics--; + if ( (ctics <= 0) && level.CreateCeiling(csec,Ceiling.ceilRaiseByValue,null,1.,1.,diffh*.6) ) + { + ctics = int(diffh*.6)+10; + cphase = 2; + } + } + else if ( cphase == 2 ) + { + ctics--; + if ( ctics <= 0 ) cphase = 3; + } + else if ( (cphase >= 3) && csec.ceilingdata ) + { + csec.ceilingdata.Destroy(); + csec.StopSoundSequence(CHAN_VOICE); + } + } + } +}