From 1a0ddc5e7994f947614064503fa855742ca0e911 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Wed, 1 Dec 2021 01:10:07 +0100 Subject: [PATCH] Rewrite the weapon replacement system (less of a mess now maybe?). --- language.version | 4 +- zscript/handler/swwm_handler_replacements.zsc | 4 +- zscript/utility/swwm_utility.zsc | 200 +++++++++++------- zscript/weapons/swwm_baseweapon.zsc | 4 - 4 files changed, 133 insertions(+), 79 deletions(-) diff --git a/language.version b/language.version index e614d5f3e..8d9de164c 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\chSWWM \czGZ\c- \cw1.2pre r64 \cu(Tue 30 Nov 23:13:25 CET 2021)\c-"; -SWWM_SHORTVER="\cw1.2pre r64 \cu(2021-11-30 23:13:25)\c-"; +SWWM_MODVER="\chSWWM \czGZ\c- \cw1.2pre r65 \cu(Wed 1 Dec 01:10:07 CET 2021)\c-"; +SWWM_SHORTVER="\cw1.2pre r65 \cu(2021-12-01 01:10:07)\c-"; diff --git a/zscript/handler/swwm_handler_replacements.zsc b/zscript/handler/swwm_handler_replacements.zsc index 2f2b69241..09ecb89db 100644 --- a/zscript/handler/swwm_handler_replacements.zsc +++ b/zscript/handler/swwm_handler_replacements.zsc @@ -616,9 +616,9 @@ extend Class SWWMHandler 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.Replacement = SWWMUtility.PickSWWMSlot2(); - else if ( (e.Replacee is 'Shotgun') || (e.Replacee is 'CWeapStaff') ) e.Replacement = SWWMUtility.IsDoomOne()?SWWMUtility.PickHereticSlot3():SWWMUtility.PickSWWMSlot3(); + else if ( (e.Replacee is 'Shotgun') || (e.Replacee is 'CWeapStaff') ) e.Replacement = SWWMUtility.IsDoomOne()?SWWMUtility.PickDoomSlot3():SWWMUtility.PickSWWMSlot3(); else if ( (e.Replacee is 'SuperShotgun') || (e.Replacee is 'MWeapFrost') ) e.Replacement = SWWMUtility.PickSWWMSlot4(); - else if ( e.Replacee is 'Crossbow' ) e.Replacement = SWWMUtility.PickHereticSlot3(); + else if ( e.Replacee is 'Crossbow' ) e.Replacement = SWWMUtility.PickDoomSlot3(); else if ( (e.Replacee is 'Chaingun') || (e.Replacee is 'Blaster') || (e.Replacee is 'FWeaponPiece3') ) e.Replacement = SWWMUtility.PickSWWMSlot5(); else if ( (e.Replacee is 'RocketLauncher') || (e.Replacee is 'PhoenixRod') || (e.Replacee is 'FWeapHammer') ) e.Replacement = SWWMUtility.PickSWWMSlot6(); else if ( (e.Replacee is 'PlasmaRifle') || (e.Replacee is 'SkullRod') ) e.Replacement = SWWMUtility.PickDoomSlot6(); diff --git a/zscript/utility/swwm_utility.zsc b/zscript/utility/swwm_utility.zsc index a5e7b4daf..4d395aae9 100644 --- a/zscript/utility/swwm_utility.zsc +++ b/zscript/utility/swwm_utility.zsc @@ -1995,138 +1995,196 @@ Class SWWMUtility } // multi-weapon spawn stuff - static private Class PickPair( Class a, Class b, int weight = 1 ) + + static private Class PickPair( Class a, Class b ) { - if ( CheckNeedsItem(a) ) return a; - if ( CheckNeedsItem(b) ) return b; - return Random[Replacements](weight,0)?a:b; + if ( ItemExists(a,mapstart:true) ) return b; + return Random[Replacements](0,1)?a:b; } - static private Class PickTrio( Class a, Class b, Class c, int weight1 = 1, int weight2 = 1 ) + static private Class PickTrio( Class a, Class b, Class c ) { - if ( CheckNeedsItem(a) ) return a; - if ( CheckNeedsItem(b) ) return b; - if ( CheckNeedsItem(c) ) return c; - return Random[Replacements](weight1,0)?a:Random[Replacements](weight2,0)?b:c; + if ( ItemExists(a,mapstart:true) ) + { + if ( ItemExists(b,mapstart:true) ) + return c; + return Random[Replacements](0,1)?b:c; + } + if ( ItemExists(b,mapstart:true) ) + { + if ( ItemExists(c,mapstart:true) ) + return a; + return Random[Replacements](0,1)?a:c; + } + if ( ItemExists(c,mapstart:true) ) + Random[Replacements](0,1)?a:b; + switch ( Random[Replacements](0,2) ) + { + case 0: + return a; + case 1: + return b; + } + return c; } - // boy, this one got complicated fast - static Class PickSWWMSlot1() + // melee weapons + extra slot 2 guns (50% chance) + static Class PickSWWMSlot1() { // so the player can recover it if they decided to drop it in a previous map, or they didn't start with it if ( CheckNeedsItem('DeepImpact') ) return 'DeepImpact'; - bool needsmelee = CheckNeedsItem('PusherWeapon')/*|CheckNeedsItem('ItamexHammer')|CheckNeedsItem('FistGun')*/; - bool needsgun = CheckNeedsItem('ExplodiumGun',true)/*|CheckNeedsItem('PlasmaBlast',true)*/; - if ( !needsmelee && !needsgun ) - { - static const Class wpns[] = - { - 'ExplodiumGun', 'PusherWeapon', - 'PlasmaBlast', 'ItamexHammer', - 'FistGun' - }; - //return wpns[Random[Replacements](0,4)]; - //return wpns[Random[Replacements](0,3)]; - return wpns[Random[Replacements](0,1)]; - } - if ( !needsmelee && needsgun ) - { - //bool needsexplo = CheckNeedsItem('ExplodiumGun',true); - //bool needsblast = CheckNeedsItem('PlasmaBlast',true); - //if ( needsexplo && !needsblast ) return 'ExplodiumGun'; - //if ( !needsexplo && needsblast ) return 'PlasmaBlast'; - //return Random[Replacements](0,1)?'ExplodiumGun':'PlasmaBlast'; - return 'ExplodiumGun'; - } - if ( needsmelee && !needsgun ) - { - //return PickTrio('PusherWeapon','ItamexHammer','FistGun'); - //return PickPair('PusherWeapon','ItamexHammer'); - return 'PusherWeapon'; - } - if ( CheckNeedsItem('ExplodiumGun',true) && Random[Replacements](0,1) ) return 'ExplodiumGun'; - //if ( CheckNeedsItem('PlasmaBlast',true) && Random[Replacements](0,1) ) return 'PlasmaBlast'; + bool hasmelee = (!CheckNeedsItem('PusherWeapon')/*||!CheckNeedsItem('ItamexHammer')||!CheckNeedsItem('FistGun')*/); + bool gunexists = ItemExists('ExplodiumGun',worldonly:true)/*||ItemExists('PlasmaBlast',worldonly:true)*/; + // if the player already has a melee weapon, 50% chance to spawn either slot 2 weapon as long as one doesn't exist in the map already + if ( hasmelee && !gunexists && Random[Replacements](0,1) ) + return PickSWWMSlot2(); //return PickTrio('PusherWeapon','ItamexHammer','FistGun'); //return PickPair('PusherWeapon','ItamexHammer'); return 'PusherWeapon'; } - static Class PickSWWMSlot2() + // pistol spawn, pretty simple + static Class PickSWWMSlot2() { //return PickPair('ExplodiumGun','PlasmaBlast'); return 'ExplodiumGun'; } - static Class PickSWWMSlot3() + // shotgun spawn + static Class PickSWWMSlot3() { //return PickPair('Spreadgun','PuntzerBeta'); return 'Spreadgun'; } - static Class PickSWWMSlot4() + // super shotgun spawn + static Class PickSWWMSlot4() { //return PickPair('Wallbuster','PuntzerGamma'); return 'Wallbuster'; } - static Class PickSWWMSlot5() + // chaingun spawn + static Class PickSWWMSlot5() { //return PickPair('Eviscerator','HeavyMahSheenGun'); return 'Eviscerator'; } - static Class PickSWWMSlot6() + // rocket launcher spawn + static Class PickSWWMSlot6() { - //return PickTrip('Hellblazer','Quadravol','ModernSparkster'); + //return PickTrio('Hellblazer','Quadravol','ModernSparkster'); //return PickPair('Hellblazer','Quadravol'); return 'Hellblazer'; } - static Class PickSWWMSlot7() + // first plasma rifle spawn + static Class PickSWWMSlot7() { //return PickPair('Sparkster','BlackfireIgniter'); return 'Sparkster'; } - static Class PickSWWMSlot8() + // second plasma rifle spawn + static Class PickSWWMSlot8() { //return PickPair('SilverBullet','EMPCarbine'); return 'SilverBullet'; } - static Class PickSWWMSlot9() + // first bfg spawn + static Class PickSWWMSlot9() { //return PickTrio('CandyGun','RayKhom','MisterRifle'); //return PickPair('CandyGun','RayKhom'); return 'CandyGun'; } - static Class PickSWWMSlot0() + // second bfg spawn (each weapon can only exist once) + static Class PickSWWMSlot0( bool fallback = true ) { - /*if ( !CheckNeedsItem('Ynykron') ) + /*if ( ItemExists('Ynykron',mapstart:true) ) { - if ( !CheckNeedsItem('GrandLance') ) + if ( ItemExists('GrandLance',mapstart:true) ) { - if ( !CheckNeedsItem('RafanKos') ) - return PickSWWMSlot9(); + if ( ItemExists('RafanKos',null,true) ) + return fallback?PickSWWMSlot9():null; return 'RafanKos'; } - if ( !CheckNeedsItem('RafanKos') ) + if ( ItemExists('RafanKos',mapstart:true) ) return 'GrandLance'; - return PickPair('GrandLance','RafanKos'); + return Random[Replacements](0,1)?'GrandLance':'RafanKos'; } - return PickTrio('Ynykron','GrandLance','RafanKos');*/ - /*if ( !CheckNeedsItem('Ynykron') ) + if ( ItemExists('GrandLance',mapstart:true) ) { - if ( !CheckNeedsItem('GrandLance') ) - return PickSWWMSlot9(); + if ( ItemExists('RafanKos',mapstart:true) ) + return 'Ynykron'; + return Random[Replacements](0,1)?'Ynykron':'RafanKos'; + } + if ( ItemExists('RafanKos',mapstart:truee) ) + return Random[Replacements](0,1)?'Ynykron':'GrandLance'; + switch ( Random[Replacements](0,2) ) + { + case 0: + return 'Ynykron'; + case 1: return 'GrandLance'; } - return PickPair('Ynykron','GrandLance');*/ - return !CheckNeedsItem('Ynykron')?'CandyGun':'Ynykron'; + return 'RafanKos';*/ + /*if ( ItemExists('Ynykron',mapstart:true) ) + { + if ( ItemExists('GrandLance',mapstart:true) ) + return fallback?PickSWWMSlot9():null; + return 'GrandLance'; + } + if ( ItemExists('GrandLance',mapstart:true) ) + return 'Ynykron'; + return Random[Replacements](0,1)?'Ynykron':'GrandLance';*/ + if ( ItemExists('Ynykron',mapstart:true) ) return fallback?PickSWWMSlot9():null; + return 'Ynykron'; } - static Class PickDoomSlot6() + // either plasma rifle spawn + static Class PickDoomSlot6() { - return PickPair(PickSWWMSlot7(),PickSWWMSlot8(),2); + bool hasslot7 = (!CheckNeedsItem('Sparkster')/*||!CheckNeedsItem('BlackfireIgniter')*/); + bool hasslot8 = (!CheckNeedsItem('SilverBullet')/*||!CheckNeedsItem('EMPCarbine')*/); + // if the player already has a slot 7 weapon... + if ( hasslot7 ) + { + // ... and also has a slot 8 weapon, 33% chance of a slot 8 spawn + // otherwise, guaranteed slot 8 spawn + if ( hasslot8 && Random[Replacements](0,2) ) return PickSWWMSlot7(); + else return PickSWWMSlot8(); + } + // otherwise, always spawn a slot 7 weapon first + return PickSWWMSlot7(); + } - static Class PickDoomSlot7() + // either bfg spawn + static Class PickDoomSlot7() { - return PickPair(PickSWWMSlot9(),PickSWWMSlot0(),2); + bool hasslot9 = (!CheckNeedsItem('CandyGun')/*||!CheckNeedsItem('RayKhom')||!CheckNeedsItem('MortalRifle')*/); + bool hasslot0 = (!CheckNeedsItem('Ynykron')/*||!CheckNeedsItem('GrandLance')||!CheckNeedsItem('RafanKos')*/); + let rep = PickSWWMSlot0(false); + // if the player already has a slot 9 weapon (and a slot 0 weapon can still spawn)... + if ( hasslot9 && rep ) + { + // ... and also has a slot 0 weapon already, 33% chance of a slot 0 spawn + // otherwise, guaranteed slot 0 spawn + if ( hasslot0 && Random[Replacements](0,2) ) return PickSWWMSlot9(); + else return rep; + } + // otherwise, always spawn a slot 9 weapon first + return PickSWWMSlot9(); } - static Class PickHereticSlot3() // also used for Doom 1 + // either shotgun spawn (also used for Heretic) + static Class PickDoomSlot3() { - if ( level.maptime ) return PickSWWMSlot3(); // always slot 3 after map start, prevents shotgun guys from dropping wallbusters - return PickPair(PickSWWMSlot3(),PickSWWMSlot4(),2); + // always slot 3 after map start, prevents shotgun guys from dropping wallbusters, which is weird af + if ( level.maptime ) return PickSWWMSlot3(); + bool hasslot3 = (!CheckNeedsItem('Spreadgun')/*||!CheckNeedsItem('PuntzerBeta')*/); + bool hasslot4 = (!CheckNeedsItem('Wallbuster')/*||!CheckNeedsItem('PuntzerGamma')*/); + // if the player already has a slot 3 weapon... + if ( hasslot3 ) + { + // ... and also has a slot 4 weapon, 33% chance of a slot 4 spawn + // otherwise, guaranteed slot 4 spawn + if ( hasslot4 && Random[Replacements](0,2) ) return PickSWWMSlot3(); + return PickSWWMSlot4(); + } + // otherwise, always spawn a slot 3 weapon first + return PickSWWMSlot3(); } // what RandomSpawner does, basically (simplified for items) static play void TransferItemProp( Actor a, Actor b, bool bundlehack = false ) diff --git a/zscript/weapons/swwm_baseweapon.zsc b/zscript/weapons/swwm_baseweapon.zsc index 08d34e7bd..89cdc4d0a 100644 --- a/zscript/weapons/swwm_baseweapon.zsc +++ b/zscript/weapons/swwm_baseweapon.zsc @@ -389,10 +389,6 @@ Class SWWMWeapon : Weapon abstract if ( swwm_enemydrops > 0 ) return false; else if ( swwm_enemydrops == 0 ) { - // first, check if no others exist in the map, just in - // case this weapon drop MAY be needed - if ( !SWWMUtility.ItemExists(GetClass(),self) ) - return false; // drop us // drop our corresponding ammo if ( !DropAmmoType ) return true; let a = Spawn(DropAmmoType,pos,ALLOW_REPLACE);