From 4182e3465a7d147c0df44f47886b10a8b8185051 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Wed, 10 Feb 2021 18:39:08 +0100 Subject: [PATCH] I have no idea what I did here. --- README.md | 28 +++---- language.version | 4 +- zscript/dlc1/swwm_dlcammo.zsc | 44 +++++++++++ zscript/swwm_armor.zsc | 21 ++++++ zscript/swwm_compat.zsc | 10 +++ zscript/swwm_handler.zsc | 137 +++++++++++++++++----------------- zscript/swwm_health.zsc | 21 ++++++ zscript/swwm_hud.zsc | 2 +- zscript/swwm_player.zsc | 27 +++++-- zscript/swwm_thinkers.zsc | 70 ----------------- zscript/swwm_utility.zsc | 101 +++++++++++++++++++++++++ 11 files changed, 303 insertions(+), 162 deletions(-) diff --git a/README.md b/README.md index 5953e8d6e..d9337dbea 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ All weapons also have a quick melee attack using the **Weapon State 1** button, If a weapon has no actions on either the reload or zoom buttons, it may be replaced with some special idle action, such as spinning or fiddling around with it. -For now, the following are all weapons planned for the first release. More will be added afterwards (until then I'll tease you with some empty ZScript files :P). +For now, the following are all weapons planned for the first release. More will be added afterwards, in a future update (oh boy). ### Deep Impact (slot 1) ~ Replaces Fist, Staff, Hexen starting weapons ![](docimg/deepimpact.png) @@ -287,17 +287,17 @@ Healing items restore health (duh), armor items do exactly what you'd expect, an All of these can be carried in your inventory indefinitely before use, except in deathmatch, where they're activated immediately. Healing items are automatically used whenever possible (with the lowest tier healing items taking priority). Armor is immediately carried if you don't have any of that type on you, or if your existing armor drains and you have a spare. Most powerups can be toggled, unless specified otherwise. -### Health Nugget ~ Replaces Health Bonus, Crystal Vial +### Health Nugget ~ Replaces Health Bonus, Timebomb of the Ancients, Disc of Repulsion, Flechette, Mystic Ambit Incant ![](docimg/nuggethealth.png) -+1 health boost, up to a cap of 200 points. ++1 health boost, up to a cap of 200 points. Comes in bundles when replacing things other than health bonuses. -### Health Tetrahedron ~ Replaces Stimpak, Quartz Flask +### Health Tetrahedron ~ Replaces Stimpack, Crystal Vial ![](docimg/tetrahealth.png) +10 health boost, up to a cap of 100 points. -### Health Cube ~ Replaces Medkit, Quartz Flask +### Health Cube ~ Replaces Medikit, Quartz Flask ![](docimg/cubehealth.png) +20 health boost, up to a cap of 100 points. @@ -307,19 +307,19 @@ All of these can be carried in your inventory indefinitely before use, except in This artifact provides a +100 health boost plus a regeneration effect that heals +10 every 5 seconds, for up to 50 seconds, thus it doubles as a powerup. Its overhealing effects cap at 500 points (including the regen). Once its effects wear out, however, your excess health will gradually settle towards the typical 200 point cap. Unlike other health items, the **Refresher** auto-activates only if you're about to die. This usually prevents such a grim outcome... unless the damage is too high to counter. -### Armor Nugget ~ Replaces Armor Bonus, Timebomb of the Ancients, Disc of Repulsion, Flechette +### Armor Nugget ~ Replaces Armor Bonus, Timebomb of the Ancients, Disc of Repulsion, Flechette, Mystic Ambit Incant ![](docimg/nuggetarmor.png) -Cumulative armor items that can increase resistance to all damage by as much as you can find. Each nugget adds 1% to the total. Above 100%, damage gets turned into additional health (up to the standard 100% cap). The upper cap for these is 200%. +Cumulative armor items that can increase resistance to all damage by as much as you can find. Each nugget adds 1% to the total. Above 100%, damage gets turned into additional health (up to the standard 100% cap). The upper cap for these is 200%. Comes in bundles when replacing things other than armor bonuses. -### Blast Suit ~ Replaces Green Armor, Silver Shield, Mesh Armor +### Blast Suit ~ Replaces Green Armor, Silver Shield, Platinum Helm, Amulet of Warding ![](docimg/blastsuit.png) The blast suit is a nice little light armor which provides a 30% reduction to damage and an additional 50% to splash damage. Can handle a total of 150 damage points before breaking. -### War Armor ~ Replaces Blue Armor, Enchanted Shield, Falcon Shield +### War Armor ~ Replaces Blue Armor, Enchanted Shield, Mesh Armor, Falcon Shield ![](docimg/wararmor.png) Decent armor, protects very well against all damage. Reduction factors are as follows: @@ -330,12 +330,12 @@ Decent armor, protects very well against all damage. Reduction factors are as fo Can eat up a total of 250 damage points before breaking. -### Grilled Cheese Sandwich ~ Replaces Megasphere, Morph Ovum, Platinum Helm +### Grilled Cheese Sandwich ~ Replaces Megasphere, Morph Ovum, Dragonskin Bracers ![](docimg/sandwich.png) The ultimate meal. Grants a full 1000 health and magically gives you a full stack of **Armor Nuggets**, a **Blast Suit** and a **War Armor**. In addition it prevents you from dying at all when it activates automatically (this wondrous artifact can even save you from the destruction of the **Ynykron Artifact**). Keep in mind that this overhealing above 500 points fades away much quicker than the **Refresher**'s, and you can't use another sandwich again until the overheal fades. -### Ghost Artifact ~ Replaces Blur Sphere, Shadowsphere, Amulet of Warding +### Ghost Artifact ~ Replaces Blur Sphere, Shadowsphere ![](docimg/ghost.png) Actual 100% invisibility, a relic from the old **UnSX** days. @@ -397,7 +397,9 @@ Reveals the entire layout of the map and shows key locations in the HUD. Also al ## The Collectibles ![](docimg/chancebox.png) -Every now and then you will find these strange ***"Lucky Chance Boxes"*** in secret areas, which you can open by pressing Use. While some will drop very useful goodies, one among them will provide you instead with a randomly selected item from a pool of various *"collectibles"*. On pickup, these will give you a nice extra score based on their estimated market price. Some of these collectibles will only appear when you play specific IWADs (or those that go chronologically after them, e.g.: Heretic collectibles appearing in Hexen). +Every now and then you will find these strange ***"Lucky Chance Boxes"*** in secret areas, which you can open by pressing Use. In Hexen, they will also replace Dark Servants and Chaos Devices (as the game generally doesn't have secret areas). + +While some will drop very useful goodies, one among them will provide you instead with a randomly selected item from a pool of various *"collectibles"*. On pickup, these will give you a nice extra score based on their estimated market price. Some of these collectibles will only appear when you play specific IWADs (or those that go chronologically after them, e.g.: Heretic collectibles appearing in Hexen). ***(Do note that this feature is currently not fully implemented, there may be missing models)*** @@ -483,7 +485,7 @@ The scoring system is pretty straightforward. Each enemy you kill will give you You are also given +100 points for each secret found, +1000 if it's the final secret. Countable items give +10 points each or +500 if it's the final item. In addition, +5000 will be given to all players if the level is fully cleared (100% kills/items/secrets). -Score can be used to buy items on the in-game store, and it is preserved between hubs, but pistol starts will reset it. +Score can be used to buy items on the in-game store (or gained from selling them), and it is preserved between hubs, but pistol starts will reset it. In **Doom** and **Heretic**, collected keys will be displayed below the score box. diff --git a/language.version b/language.version index fffeb3861..726d07ee3 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r261 \cu(Wed 10 Feb 11:37:30 CET 2021)\c-"; -SWWM_SHORTVER="\cw0.9.11b-pre r261 \cu(2021-02-10 11:37:30)\c-"; +SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r262 \cu(Wed 10 Feb 18:39:08 CET 2021)\c-"; +SWWM_SHORTVER="\cw0.9.11b-pre r262 \cu(2021-02-10 18:39:08)\c-"; diff --git a/zscript/dlc1/swwm_dlcammo.zsc b/zscript/dlc1/swwm_dlcammo.zsc index 279cf7d87..17c8036eb 100644 --- a/zscript/dlc1/swwm_dlcammo.zsc +++ b/zscript/dlc1/swwm_dlcammo.zsc @@ -28,6 +28,28 @@ Class SMW05Ammo : Ammo } } +Class SMW05BundleSpawn : Actor +{ + override void PostBeginPlay() + { + if ( bCOUNTSECRET ) level.total_secrets--; + int bnd = Random[Bundle](2,3); + for ( int i=0; i 1 ) ng++; - } - if ( np > 0 ) return (ng < np); - for ( int i=0; i 1 ) ng++; - } - return (ng < np); - } + override void CheckReplacement( ReplaceEvent e ) { @@ -2335,27 +2317,24 @@ Class SWWMHandler : EventHandler else if ( e.Replacee is 'KeyBlue' ) e.Replacement = 'SWWMKeyBlue'; else if ( e.Replacee is 'KeyYellow' ) e.Replacement = 'SWWMKeyYellow'; else if ( e.Replacee.GetClassName() == 'KeyRed' ) e.Replacement = 'SWWMKeyRed'; - else if ( (e.Replacee is 'Chainsaw') || (e.Replacee is 'Gauntlets') || (e.Replacee is 'FWeapAxe') ) - { - if ( ShouldSpawnDualExpl() && Random[Replacements](0,1) ) e.Replacement = 'ExplodiumGun'; - else e.Replacement = 'PusherWeapon'; - } + else if ( (e.Replacee is 'Chainsaw') || (e.Replacee is 'Gauntlets') || (e.Replacee is 'FWeapAxe') ) e.Replacement = SWWMUtility.PickSWWMSlot1(); else if ( (e.Replacee is 'Fist') || (e.Replacee is 'Staff') ) e.Replacement = 'DeepImpact'; - else if ( (e.Replacee is 'Pistol') || (e.Replacee is 'GoldWand') || (e.Replacee is 'FWeapFist') || (e.Replacee is 'CWeapMace') || (e.Replacee is 'MWeapWand') || (e.Replacee.GetClassName() == 'TangoPistol') ) e.Replacement = 'ExplodiumGun'; - else if ( (e.Replacee is 'Shotgun') || (e.Replacee is 'CWeapStaff') || (e.Replacee.GetClassName() == 'TangoShotgun') ) e.Replacement = 'Spreadgun'; - else if ( (e.Replacee is 'SuperShotgun') || (e.Replacee is 'MWeapFrost') || (e.Replacee.GetClassName() == 'TangoSuperShotgun') ) e.Replacement = 'Wallbuster'; - else if ( (e.Replacee is 'Crossbow') || (e.Replacee.GetClassName() == 'TangoScrapGun') ) e.Replacement = SWWMPairedSpawns.PickSpreadBuster(); - else if ( (e.Replacee is 'Chaingun') || (e.Replacee is 'Blaster') || (e.Replacee is 'FWeaponPiece3') || (e.Replacee.GetClassName() == 'TangoAssaultRifle') || (e.Replacee.GetClassName() == 'TangoChaingun') ) e.Replacement = 'Eviscerator'; - else if ( (e.Replacee is 'RocketLauncher') || (e.Replacee is 'PhoenixRod') || (e.Replacee is 'FWeapHammer') || (e.Replacee.GetClassName() == 'TangoStomper') ) e.Replacement = 'Hellblazer'; - else if ( (e.Replacee is 'PlasmaRifle') || (e.Replacee is 'SkullRod') ) e.Replacement = SWWMPairedSpawns.PickSparkSilver(); - else if ( e.Replacee is 'CWeapFlame' ) e.Replacement = 'Sparkster'; - else if ( e.Replacee is 'MWeapLightning' ) e.Replacement = 'SilverBullet'; - else if ( (e.Replacee is 'BFG9000') || (e.Replacee is 'Mace') ) e.Replacement = SWWMPairedSpawns.PickCandyFury(); - else if ( e.Replacee is 'CWeaponPiece2' ) e.Replacement = 'CandyGun'; - else if ( e.Replacee is 'MWeaponPiece1' ) e.Replacement = 'Ynykron'; + else if ( (e.Replacee is 'Pistol') || (e.Replacee is 'GoldWand') || (e.Replacee is 'FWeapFist') || (e.Replacee is 'CWeapMace') || (e.Replacee is 'MWeapWand') || (e.Replacee.GetClassName() == 'TangoPistol') ) e.Replacement = SWWMUtility.PickSWWMSlot2(); + else if ( (e.Replacee is 'Shotgun') || (e.Replacee is 'CWeapStaff') || (e.Replacee.GetClassName() == 'TangoShotgun') ) e.Replacement = SWWMUtility.PickSWWMSlot3(); + else if ( (e.Replacee is 'SuperShotgun') || (e.Replacee is 'MWeapFrost') || (e.Replacee.GetClassName() == 'TangoSuperShotgun') ) e.Replacement = SWWMUtility.PickSWWMSlot4(); + else if ( (e.Replacee is 'Crossbow') || (e.Replacee.GetClassName() == 'TangoScrapGun') ) e.Replacement = SWWMUtility.PickHereticSlot3(); + else if ( (e.Replacee is 'Chaingun') || (e.Replacee is 'Blaster') || (e.Replacee is 'FWeaponPiece3') || (e.Replacee.GetClassName() == 'TangoAssaultRifle') || (e.Replacee.GetClassName() == 'TangoChaingun') ) e.Replacement = SWWMUtility.PickSWWMSlot5(); + else if ( (e.Replacee is 'RocketLauncher') || (e.Replacee is 'PhoenixRod') || (e.Replacee is 'FWeapHammer') || (e.Replacee.GetClassName() == 'TangoStomper') ) e.Replacement = SWWMUtility.PickSWWMSlot6(); + else if ( (e.Replacee is 'PlasmaRifle') || (e.Replacee is 'SkullRod') ) e.Replacement = SWWMUtility.PickDoomSlot6(); + else if ( e.Replacee is 'CWeapFlame' ) e.Replacement = SWWMUtility.PickSWWMSlot7(); + else if ( e.Replacee is 'MWeapLightning' ) e.Replacement = SWWMUtility.PickSWWMSlot8(); + else if ( (e.Replacee is 'BFG9000') || (e.Replacee is 'Mace') ) e.Replacement = SWWMUtility.PickDoomSlot7(); + else if ( e.Replacee is 'CWeaponPiece2' ) e.Replacement = SWWMUtility.PickSWWMSlot9(); + else if ( e.Replacee is 'MWeaponPiece1' ) e.Replacement = SWWMUtility.PickSWWMSlot0(); else if ( (e.Replacee is 'ShellBox') || (e.Replacee is 'CrossbowHefty') || (e.Replacee.GetClassName() == 'TangoShellBox') || (e.Replacee.GetClassName() == 'TangoScrapDrumPack') ) { - switch( Random[Replacements](0,14) ) + /*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'SMW05SmallAmmo':'SMW05BigAmmo'; + else */switch( Random[Replacements](0,14) ) { case 0: case 1: @@ -2388,7 +2367,8 @@ Class SWWMHandler : EventHandler } else if ( (e.Replacee is 'Shell') || (e.Replacee is 'CrossbowAmmo') || (e.Replacee.GetClassName() == 'TangoShell') || (e.Replacee.GetClassName() == 'TangoScrapDrum') ) { - switch( Random[Replacements](0,13) ) + /*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'SMW05SmallAmmo':'SMW05BundleSpawn'; + else */switch( Random[Replacements](0,13) ) { case 0: case 1: @@ -2418,13 +2398,26 @@ Class SWWMHandler : EventHandler break; } } - else if ( e.Replacee is 'ClipBox' ) e.Replacement = Random[Replacements](0,4)?'EvisceratorShell':Random[Replacements](0,6)?'EvisceratorTrioSpawn':'EvisceratorSixPack'; - else if ( (e.Replacee is 'Clip') || (e.Replacee is 'GoldWandAmmo') ) e.Replacement = 'SWWMNothing'; - else if ( e.Replacee is 'BlasterHefty' ) e.Replacement = Random[Replacements](0,6)?'EvisceratorTrioSpawn':'EvisceratorSixPack'; - else if ( (e.Replacee is 'BlasterAmmo') || (e.Replacee.GetClassName() == 'TangoBulletClipHalf') ) e.Replacement = 'EvisceratorShell'; + else if ( e.Replacee is 'ClipBox' ) + { + /*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'SheenSmallAmmo':'SheenBigAmmo'; + else */e.Replacement = Random[Replacements](0,4)?'EvisceratorShell':Random[Replacements](0,6)?'EvisceratorTrioSpawn':'EvisceratorSixPack'; + } + else if ( (e.Replacee is 'Clip') || (e.Replacee is 'GoldWandAmmo') ) e.Replacement = /*(e.Replacee is 'GoldWandHefty')?'SheenSmallAmmo':'SheenTinyAmmo'*/'SWWMNothing'; + else if ( e.Replacee is 'BlasterHefty' ) + { + /*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'SheenBigAmmo':'SheenSmallAmmo'; + else */e.Replacement = Random[Replacements](0,6)?'EvisceratorTrioSpawn':'EvisceratorSixPack'; + } + else if ( (e.Replacee is 'BlasterAmmo') || (e.Replacee.GetClassName() == 'TangoBulletClipHalf') ) + { + /*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'SheenSmallAmmo':'SheenTinyAmmo'; + else */e.Replacement = 'EvisceratorShell'; + } else if ( (e.Replacee is 'RocketBox') || (e.Replacee is 'PhoenixRodHefty') || (e.Replacee is 'MaceHefty')|| (e.Replacee.GetClassName() == 'TangoStomperBox') ) { - switch ( Random[Replacements](0,11) ) + /*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'QuadravolAmmo':'QuadravolAmmoBundleSpawn'; + else */switch ( Random[Replacements](0,11) ) { case 0: case 1: @@ -2453,10 +2446,20 @@ Class SWWMHandler : EventHandler break; } } - else if ( (e.Replacee is 'RocketAmmo') || (e.Replacee is 'PhoenixRodAmmo') || (e.Replacee is 'MaceAmmo') || (e.Replacee.GetClassName() == 'TangoStomperAmmo') ) e.Replacement = Random[Replacements](0,2)?'HellblazerMissiles':'HellblazerCrackshots'; + else if ( (e.Replacee is 'RocketAmmo') || (e.Replacee is 'PhoenixRodAmmo') || (e.Replacee is 'MaceAmmo') || (e.Replacee.GetClassName() == 'TangoStomperAmmo') ) + { + /*if ( Random[Replacements](0,1) ) e.Replacement = 'QuadravolAmmo'; + else */e.Replacement = Random[Replacements](0,2)?'HellblazerMissiles':'HellblazerCrackshots'; + } else if ( (e.Replacee is 'CellPack') || (e.Replacee is 'SkullRodHefty') ) { - if ( !Random[Replacements](0,2) ) + /*if ( Random[Replacements](0,1) ) + { + if ( !Random[Replacements](0,2) ) e.Replacement = Random[Replacements](0,3)?'EMPCoreBundleSpawn':'EMPCore'; + else if ( Random[Replacements](0,2) ) e.Replacement = 'RayBoltBundleSpawn'; + else e.Replacement = 'RayAmmo'; + } + else */if ( !Random[Replacements](0,2) ) { if ( Random[Replacements](0,3) ) e.Replacement = Random[Replacements](0,2)?'SilverBulletsBundleSpawn':'SilverBullets2BundleSpawn'; else e.Replacement = Random[Replacements](0,2)?'SilverBulletAmmo':'SilverBulletAmmo2'; @@ -2466,42 +2469,38 @@ Class SWWMHandler : EventHandler } else if ( (e.Replacee is 'Cell') || (e.Replacee is 'SkullRodAmmo') ) { - if ( !Random[Replacements](0,2) ) e.Replacement = Random[Replacements](0,2)?'HellblazerRavagers':'HellblazerWarheads'; - else if ( Random[Replacements](0,2) ) e.Replacement = 'SparkUnit'; - else if ( !Random[Replacements](0,3) ) e.Replacement = 'CandyGunBullets'; - else e.Replacement = Random[Replacements](0,2)?'SilverBullets':'SilverBullets2'; + if ( !Random[Replacements](0,2) ) e.Replacement = /*!Random[Replacements](0,2)?'RayBattery':*/Random[Replacements](0,2)?'HellblazerRavagers':'HellblazerWarheads'; + else if ( Random[Replacements](0,2) ) e.Replacement = /*Random[Replacements](0,1)?'DarkCanister':*/'SparkUnit'; + else if ( !Random[Replacements](0,3) ) e.Replacement = /*Random[Replacements](0,1)?'RayBolt':*/'CandyGunBullets'; + else e.Replacement = /*Random[Replacements](0,1)?'EMPCore':*/Random[Replacements](0,2)?'SilverBullets':'SilverBullets2'; } else if ( e.Replacee is 'Mana1' ) e.Replacement = 'FabricatorTier1'; else if ( e.Replacee is 'Mana2' ) e.Replacement = 'FabricatorTier2'; else if ( e.Replacee is 'Mana3' ) e.Replacement = 'FabricatorTier3'; else if ( e.Replacee is 'ArtiBoostMana' ) e.Replacement = 'FabricatorTier4'; - else if ( (e.Replacee is 'Backpack') || (e.Replacee is 'BagOfHolding') || (e.Replacee is 'ArtiBoostArmor') ) e.Replacement = 'HammerspaceEmbiggener'; + else if ( (e.Replacee is 'Backpack') || (e.Replacee is 'BagOfHolding') || (e.Replacee is 'ArtiPork') ) e.Replacement = 'HammerspaceEmbiggener'; else if ( (e.Replacee is 'FWeaponPiece1') || (e.Replacee is 'FWeaponPiece2') || (e.Replacee is 'CWeaponPiece1') || (e.Replacee is 'CWeaponPiece3') - || (e.Replacee is 'MWeaponPiece2') || (e.Replacee is 'MWeaponPiece3') ) - { - if ( Random[Replacements](0,1) ) e.Replacement = 'SWWMNothing'; - else if ( Random[Replacements](0,5) ) e.Replacement = 'HammerspaceEmbiggener'; - else e.Replacement = 'GoldShell'; - } - else if ( (e.Replacee is 'ArmorBonus') || (e.Replacee is 'ArtiTimeBomb') || (e.Replacee is 'ArtiBlastRadius') || (e.Replacee is 'ArtiPoisonBag') ) e.Replacement = 'ArmorNuggetItem'; - else if ( (e.Replacee is 'HealthBonus') || (e.Replacee is 'CrystalVial') ) e.Replacement = 'HealthNuggetItem'; - else if ( e.Replacee is 'Stimpack' ) e.Replacement = 'TetraHealthItem'; - else if ( e.Replacee is 'Medikit' ) e.Replacement = 'CubeHealthItem'; - else if ( e.Replacee is 'ArtiHealth' ) e.Replacement = Random[Replacements](0,1)?'CubeHealthItem':'TetraHealthItem'; + || (e.Replacee is 'MWeaponPiece2') || (e.Replacee is 'MWeaponPiece3') ) e.Replacement = 'SWWMNothing'; + else if ( e.Replacee is 'ArmorBonus' ) e.Replacement = 'ArmorNuggetItem'; + else if ( e.Replacee is 'HealthBonus' ) e.Replacement = 'HealthNuggetItem'; + else if ( (e.Replacee is 'ArtiTimeBomb') || (e.Replacee is 'ArtiBlastRadius') || (e.Replacee is 'ArtiPoisonBag') || (e.Replacee is 'ArtiHealingRadius') ) e.Replacement = (nugflip=!nugflip)?'HealthNuggetBundleSpawn':'ArmorNuggetBundleSpawn'; + else if ( (e.Replacee is 'HealthBonus') ) e.Replacement = 'HealthNuggetItem'; + else if ( (e.Replacee is 'Stimpack') || (e.Replacee is 'CrystalVial') ) e.Replacement = 'TetraHealthItem'; + else if ( (e.Replacee is 'Medikit') || (e.Replacee is 'ArtiHealth') ) e.Replacement = 'CubeHealthItem'; else if ( (e.Replacee is 'Soulsphere') || (e.Replacee is 'ArtiSuperHealth') ) e.Replacement = 'RefresherItem'; - else if ( e.Replacee is 'ArtiHealingRadius' ) e.Replacement = 'SWWMNothing'; - else if ( (e.Replacee is 'Megasphere') || (e.Replacee is 'ArtiEgg') || (e.Replacee is 'PlatinumHelm') ) e.Replacement = 'GrilledCheeseSandwich'; - else if ( (e.Replacee is 'Blursphere') || (e.Replacee is 'ArtiInvisibility') || (e.Replacee is 'AmuletOfWarding') ) e.Replacement = 'GhostArtifact'; + else if ( (e.Replacee is 'Megasphere') || (e.Replacee is 'ArtiEgg') || (e.Replacee is 'ArtiBoostArmor') ) e.Replacement = 'GrilledCheeseSandwich'; + else if ( (e.Replacee is 'Blursphere') || (e.Replacee is 'ArtiInvisibility') ) e.Replacement = 'GhostArtifact'; else if ( e.Replacee is 'Radsuit' ) e.Replacement = 'EBarrier'; else if ( (e.Replacee is 'ArtiFly') ) e.Replacement = 'GravitySuppressor'; else if ( (e.Replacee is 'InvulnerabilitySphere') || (e.Replacee is 'ArtiInvulnerability') || (e.Replacee is 'ArtiInvulnerability2') ) e.Replacement = 'FuckingInvinciball'; else if ( (e.Replacee is 'Berserk') || (e.Replacee == 'ArtiTomeOfPower') || (e.Replacee == 'ArtiSpeedBoots') ) e.Replacement = 'Ragekit'; else if ( (e.Replacee is 'AllMap') || (e.Replacee is 'SuperMap') ) e.Replacement = 'Omnisight'; else if ( (e.Replacee is 'Infrared') || (e.Replacee is 'ArtiTorch') ) e.Replacement = 'SWWMLamp'; - else if ( (e.Replacee is 'GreenArmor') || (e.Replacee is 'SilverShield') || (e.Replacee is 'MeshArmor') ) e.Replacement = 'BlastSuitItem'; - else if ( (e.Replacee is 'BlueArmor') || (e.Replacee is 'FalconShield') || (e.Replacee is 'EnchantedShield') ) e.Replacement = 'WarArmorItem'; - else if ( (e.Replacee is 'ArtiPork') || (e.Replacee is 'ArtiDarkServant') || (e.Replacee is 'ArtiTeleport') || (e.Replacee == 'ArtiTeleportOther') ) e.Replacement = 'ChanceboxSpawner'; + else if ( (e.Replacee is 'GreenArmor') || (e.Replacee is 'SilverShield') || (e.Replacee is 'PlatinumHelm') || (e.Replacee is 'AmuletOfWarding') ) e.Replacement = 'BlastSuitItem'; + else if ( (e.Replacee is 'BlueArmor') || (e.Replacee is 'EnchantedShield') || (e.Replacee is 'MeshArmor') || (e.Replacee is 'FalconShield') ) e.Replacement = 'WarArmorItem'; + else if ( (e.Replacee is 'ArtiDarkServant') || (e.Replacee == 'ArtiTeleportOther') ) e.Replacement = 'ChanceboxSpawner'; + else if ( e.Replacee is 'ArtiTeleport' ) e.Replacement = (gameinfo.GameType&GAME_Hexen)?'ChanceboxSpawner':'SWWMNothing'; else return; // this last part is kind of ugly, but it works // guarantees that OUR replacements are all final diff --git a/zscript/swwm_health.zsc b/zscript/swwm_health.zsc index bbdf5f5f9..7888921d6 100644 --- a/zscript/swwm_health.zsc +++ b/zscript/swwm_health.zsc @@ -99,6 +99,27 @@ Class HealthNuggetItem : SWWMHealth Stop; } } +Class HealthNuggetBundleSpawn : Actor +{ + override void PostBeginPlay() + { + if ( bCOUNTSECRET ) level.total_secrets--; + int bnd = Random[Bundle](2,3); + for ( int i=0; i 8) && !Random[DemoLines](0,max(0,12-failcounter/3)) && (gametic > failcooldown) ) + { + failcooldown = SWWMHandler.AddOneliner("puzzfail",2,20); + failcounter = max(4,failcounter-10); + } + } + else if ( gametic > lastuse+50 ) failcounter = 0; oldlagangle = lagangle; oldlagpitch = lagpitch; lagangle = lagangle*.8+angle*.2; @@ -1164,11 +1179,7 @@ Class Demolitionist : PlayerPawn // no damage whatsoever if ( scriptedinvul ) return 0; - if ( damage <= 0 ) - { - lastdamage = 0; - return Super.DamageMobj(inflictor,source,damage,mod,flags,angle); - } + if ( damage <= 0 ) return Super.DamageMobj(inflictor,source,damage,mod,flags,angle); if ( !inflictor && !source && (FloorSector.flags&Sector.SECF_ENDLEVEL) ) { // end level hax @@ -1178,9 +1189,10 @@ Class Demolitionist : PlayerPawn } int oldpchance = PainChance; if ( damage < 5 ) PainChance = 0; - lastdamage = Super.DamageMobj(inflictor,source,damage,mod,flags,angle); + int realdmg = Super.DamageMobj(inflictor,source,damage,mod,flags,angle); // hotfix damagecount overflow until proper fix is in stable gzdoom if ( player && (player.damagecount < 0) ) player.damagecount = 100; + lastdamage = max(lastdamage,realdmg); lastdamagetic = max(lastdamagetic,gametic+clamp(lastdamage/2,10,40)); if ( (lastdamage > 0) && (PainChance == 0) && (level.maptime>lastmpain) ) { @@ -1188,7 +1200,7 @@ Class Demolitionist : PlayerPawn A_DemoPain(); } PainChance = oldpchance; - return lastdamage; + return realdmg; } override void CalcHeight() { @@ -1934,6 +1946,7 @@ Class Demolitionist : PlayerPawn if ( (player == players[consoleplayer]) && mute && myvoice && (mute.GetInt() < 4) ) A_StartSound(String.Format("voice/%s/lopain",myvoice.GetString()),CHAN_DEMOVOICE,CHANF_OVERLAP); } + lastdamage = 0; } void A_DemoScream() { diff --git a/zscript/swwm_thinkers.zsc b/zscript/swwm_thinkers.zsc index bbede77d7..2bf384e10 100644 --- a/zscript/swwm_thinkers.zsc +++ b/zscript/swwm_thinkers.zsc @@ -1,75 +1,5 @@ // various stat tracking thinkers and others -// weapon spawn mgmt -Class SWWMPairedSpawns : Thinker -{ - // 0 - spawn former, 1 - spawn latter, 2 - random - int spreadbuster; // spreadgun/wallbuster pair (Ethereal Crossbow) - int sparksilver; // sparkster/silverbullet pair (Plasma Rifle, Skull Rod) - int candyfury; // candygun/ynykron pair (BFG9000, Mace) - - // when the DLC weaponset lands, this will also have to account for more weapon pairs (or quartets) - - private static SWWMPairedSpawns Instance() - { - let s = SWWMPairedSpawns(ThinkerIterator.Create("SWWMPairedSpawns",STAT_STATIC).Next()); - if ( !s ) - { - s = new("SWWMPairedSpawns"); - s.ChangeStatNum(STAT_STATIC); - } - return s; - } - - static Class PickSpreadBuster() - { - let s = Instance(); - if ( s.spreadbuster == 0 ) - { - s.spreadbuster = 1; - return 'Spreadgun'; - } - if ( s.spreadbuster == 1 ) - { - s.spreadbuster = 2; - return 'Wallbuster'; - } - return Random[Replacements](0,2)?'Spreadgun':'Wallbuster'; - } - - static Class PickSparkSilver() - { - let s = Instance(); - if ( s.sparksilver == 0 ) - { - s.sparksilver = 1; - return 'Sparkster'; - } - if ( s.sparksilver == 1 ) - { - s.sparksilver = 2; - return 'SilverBullet'; - } - return Random[Replacements](0,2)?'Sparkster':'SilverBullet'; - } - - static Class PickCandyFury() - { - let s = Instance(); - if ( s.candyfury == 0 ) - { - s.candyfury = 1; - return 'CandyGun'; - } - if ( s.candyfury == 1 ) - { - s.candyfury = 2; - return 'Ynykron'; - } - return Random[Replacements](0,2)?'CandyGun':'Ynykron'; - } -} - // Stats Class WeaponUsage { diff --git a/zscript/swwm_utility.zsc b/zscript/swwm_utility.zsc index 0784044c1..3934ffeee 100644 --- a/zscript/swwm_utility.zsc +++ b/zscript/swwm_utility.zsc @@ -1342,6 +1342,107 @@ Class SWWMUtility p.mo.BringUpWeapon(); p.health = p.mo.Health = p.mo.SpawnHealth(); } + + // check that all players can get enough of this if needed + // multi: check for multiple copies, not just single instances + // (useful e.g. for dual wieldable weapons) + static bool CheckNeedsItem( Class itm, bool multi = false ) + { + int np = 0; + for ( int i=0; i0); + } + + // multi-weapon spawn stuff + static private Class PickPair( Class a, Class b, int weight = 1 ) + { + if ( CheckNeedsItem(a) ) return a; + if ( CheckNeedsItem(b) ) return b; + return Random[Replacements](weight,0)?a:b; + } + + static Class PickSWWMSlot1() + { + if ( CheckNeedsItem('ExplodiumGun',true) && Random[Replacements](0,1) ) return 'ExplodiumGun'; + /*if ( CheckNeedsItem('PlasmaBlast',true) && Random[Replacements](0,1) ) return 'PlasmaBlast'; + return PickPair('PusherWeapon','ItamexHammer');*/ + return 'PusherWeapon'; + } + static Class PickSWWMSlot2() + { + //return PickPair('ExplodiumGun','PlasmaBlast'); + return 'ExplodiumGun'; + } + static Class PickSWWMSlot3() + { + //return PickPair('Spreadgun','PuntzerBeta'); + return 'Spreadgun'; + } + static Class PickSWWMSlot4() + { + //return PickPair('Wallbuster','PuntzerGamma'); + return 'Wallbuster'; + } + static Class PickSWWMSlot5() + { + //return PickPair('Eviscerator','HeavyMahSheenGun'); + return 'Eviscerator'; + } + static Class PickSWWMSlot6() + { + //return PickPair('Hellblazer','Quadravol'); + return 'Hellblazer'; + } + static Class PickSWWMSlot7() + { + //return PickPair('Sparkster','BlackfireIgniter'); + return 'Sparkster'; + } + static Class PickSWWMSlot8() + { + //return PickPair('SilverBullet','EMPCarbine'); + return 'SilverBullet'; + } + static Class PickSWWMSlot9() + { + //return PickPair('CandyGun','RayKhom'); + return 'CandyGun'; + } + static Class PickSWWMSlot0() + { + /*if ( gameinfo.GameType&GAME_Strife ) return 'GrandLance'; + return PickPair('Ynykron','GrandLance');*/ + return 'Ynykron'; + } + static Class PickDoomSlot6() + { + //return PickPair(PickSWWMSlot7(),PickSWWMSlot8(),2); + return PickPair('Sparkster','SilverBullet',2); + } + static Class PickDoomSlot7() + { + //return PickPair(PickSWWMSlot9(),PickSWWMSlot0(),2); + return PickPair('CandyGun','Ynykron',2); + } + static Class PickHereticSlot3() + { + //return PickPair(PickSWWMSlot3(),PickSWWMSlot4(),2); + return PickPair('Spreadgun','Wallbuster',2); + } } Class RadiusDebugSphere : Actor