// inventory-related functions extend Class SWWMUtility { // full reset of inventory (excluding collectibles, and optionally resetting the score) static play void WipeInventory( Actor mo, bool resetscore = false, bool allplayers = false ) { if ( allplayers ) { for ( int i=0; i itm, bool multi = false ) { int np = 0; for ( int i=0; i0); } // checks if instances of a certain item exist // skipme: optionally, ignore checking for one specific instance // (useful to check if we're the only copy of an item) // mapstart: this function is being called during map load, so we // should also check STAT_TRAVELLING inventory // worldonly: only checks for items that are placed in the world // ownedonly: only checks for items that are owned by players // (note that this is mutually exclusive with worldonly) static bool ItemExists( Class itm, Inventory skipme = null, bool mapstart = false, bool worldonly = false, bool ownedonly = false ) { let ti = ThinkerIterator.Create(itm); Inventory i; while ( i = Inventory(ti.Next()) ) { if ( i == skipme ) continue; if ( worldonly && i.Owner ) continue; if ( ownedonly && (!i.Owner || !i.Owner.player) ) continue; return true; } if ( worldonly || !mapstart ) return false; ti = ThinkerIterator.Create(itm,Thinker.STAT_TRAVELLING); while ( i = Inventory(ti.Next()) ) { if ( i == skipme ) continue; if ( ownedonly && (!i.Owner || !i.Owner.player) ) continue; return true; } return false; } // multi-weapon spawn stuff static private Class PickPair( Class a, Class b ) { if ( !ItemExists(a,mapstart:true) ) return a; if ( !ItemExists(b,mapstart:true) ) return b; return Random[Replacements](0,1)?a:b; } // melee weapon + extra slot 2 guns static Class PickSWWMSlot1() { // [GROSS HACK] default to a hammer if there are no players // (this genuinely can happen, if player starts were placed AFTER the item) int np = 0; for ( int i=0; i PickSWWMSlot2() { // as they are dual-wieldable, there should be a 50% chance for spares to also appear if needed if ( Random[Replacements](0,1) && !CheckNeedsItem('ExplodiumGun') && CheckNeedsItem('ExplodiumGun',true) ) return 'ExplodiumGun'; if ( Random[Replacements](0,1) && !CheckNeedsItem('PlasmaBlast') && CheckNeedsItem('PlasmaBlast',true) ) return 'PlasmaBlast'; return PickPair('ExplodiumGun','PlasmaBlast'); } // shotgun spawn static Class PickSWWMSlot3() { return PickPair('Spreadgun','PuntzerBeta'); } // super shotgun spawn static Class PickSWWMSlot4() { return PickPair('Wallbuster','PuntzerGamma'); } // chaingun spawn static Class PickSWWMSlot5() { return PickPair('Eviscerator','HeavyMahSheenGun'); } // rocket launcher spawn static Class PickSWWMSlot6() { return PickPair('Hellblazer','Quadravol'); } // first plasma rifle spawn static Class PickSWWMSlot7() { return PickPair('Sparkster','ModernSparkster'); } // second plasma rifle spawn static Class PickSWWMSlot8() { return PickPair('SilverBullet','RayKhom'); } // first bfg spawn static Class PickSWWMSlot9() { // 25% chance to still drop another candy gun if it's not at max capacity if ( !Random[Replacements](0,3) && ItemExists('CandyGun') && CheckNeedsItem('CandyGunSpares',true) ) return 'CandyGun'; return PickPair('CandyGun','MisterRifle'); } // second bfg spawn (each weapon can only exist once) static Class PickSWWMSlot0( bool fallback = true ) { if ( ItemExists('Ynykron',mapstart:true) ) { if ( ItemExists('RafanKos',mapstart:true) ) return fallback?PickSWWMSlot9():null; return 'RafanKos'; } if ( ItemExists('RafanKos',mapstart:true) ) return 'Ynykron'; return Random[Replacements](0,1)?'Ynykron':'RafanKos'; } // either plasma rifle spawn static Class PickDoomSlot6() { bool hasslot7 = (!CheckNeedsItem('Sparkster')||!CheckNeedsItem('ModernSparkster')); bool hasslot8 = (!CheckNeedsItem('SilverBullet')||!CheckNeedsItem('RayKhom')); // 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(); } // either bfg spawn static Class PickDoomSlot7() { bool hasslot9 = (!CheckNeedsItem('CandyGun')||!CheckNeedsItem('MisterRifle')); bool hasslot0 = (!CheckNeedsItem('Ynykron')||!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(); } // either shotgun spawn (also used for Heretic) static Class PickDoomSlot3() { // 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(); } }