Add "on-demand" option to only spawn ammo for available weapons.

Add dedicated "Ammo Spawner" class to simplify code.
Small code duplication cleanup.
This commit is contained in:
Mari the Deer 2021-06-23 01:00:53 +02:00
commit fb0e8c45f3
14 changed files with 349 additions and 276 deletions

View file

@ -34,26 +34,17 @@ Class SMW05Ammo : Ammo
}
}
Class SMW05BundleSpawn : Actor
Class SMW05BundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
int bnd = Random[Bundle](2,3);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("SMW05Ammo",Vec3Angle(4,i*(360/bnd)));
a.special = special;
a.angle = i*(360/bnd);
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}
@ -201,27 +192,17 @@ Class QuadravolAmmo : Ammo
}
}
Class QuadravolAmmoBundleSpawn : Actor
Class QuadravolAmmoBundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
int bnd = Random[Bundle](2,3);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("QuadravolAmmo",Vec3Angle(6,i*(360/bnd)));
a.special = special;
a.angle = i*(360/bnd);
a.FloatBobPhase = FloatBobPhase;
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}
@ -302,27 +283,17 @@ Class EMPCore : Ammo
}
}
Class EMPCoreBundleSpawn : Actor
Class EMPCoreBundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
int bnd = Random[Bundle](2,3);
for ( int i=0; i<3; i++ )
{
let a = Spawn("EMPCore",Vec3Angle(6,i*(360/bnd)));
a.special = special;
a.angle = i*(360/bnd);
a.FloatBobPhase = FloatBobPhase;
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}
@ -351,26 +322,17 @@ Class RayBolt : MagAmmo
}
}
Class RayBoltBundleSpawn : Actor
Class RayBoltBundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
int bnd = Random[Bundle](2,5);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("RayBolt",Vec3Angle(6,i*(360/bnd)));
a.special = special;
a.angle = i*(360/bnd);
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}

View file

@ -555,12 +555,6 @@ extend Class SWWMHandler
if ( profiling ) checkreplacement_ms += MSTime()-curms;
return;
}
// shell types (sorted by rarity
static const Class<Actor> redpool[] = {'RedShell','RedShell2','RedShell4'};
static const Class<Actor> greenpool[] = {'GreenShell','GreenShell2','GreenShell4'};
static const Class<Actor> whitepool[] = {'WhiteShell','WhiteShell2'};
static const Class<Actor> purplepool[] = {'PurpleShell','PurpleShell2','PurpleShell4'};
static const Class<Actor> bluepool[] = {'BlueShell','BlueShell2','BlueShell4'};
// DRLA Monsters stuff
if ( hasdrlamonsters )
{
@ -611,7 +605,7 @@ extend Class SWWMHandler
}
e.Replacement = 'SWWMBossBrain';
}
else if ( e.Replacee is 'RedCard' )
else if ( (e.Replacee is 'RedCard') && !(e.Replacee is 'ChexRedCard') )
{
if ( level.GetChecksum() ~== "3805A661D5C4523AFF7BF86991071043" )
{
@ -620,8 +614,8 @@ extend Class SWWMHandler
}
e.Replacement = 'SWWMRedCard';
}
else if ( e.Replacee is 'BlueCard' ) e.Replacement = 'SWWMBlueCard';
else if ( e.Replacee is 'YellowCard' ) e.Replacement = 'SWWMYellowCard';
else if ( (e.Replacee is 'BlueCard') && !(e.Replacee is 'ChexBlueCard') ) e.Replacement = 'SWWMBlueCard';
else if ( (e.Replacee is 'YellowCard') && !(e.Replacee is 'ChexYellowCard') ) e.Replacement = 'SWWMYellowCard';
else if ( e.Replacee.GetClassName() == 'GreenCard' ) e.Replacement = 'SWWMGreenCard';
else if ( e.Replacee is 'RedSkull' ) e.Replacement = iskdizd?'SWWMSilverCardKDiZD':'SWWMRedSkull';
else if ( e.Replacee is 'BlueSkull' ) e.Replacement = iskdizd?'SWWMGreenCardKDiZD':'SWWMBlueSkull';
@ -646,144 +640,49 @@ extend Class SWWMHandler
else if ( e.Replacee is 'MWeaponPiece1' ) e.Replacement = SWWMUtility.PickSWWMSlot0();
else if ( (e.Replacee is 'ShellBox') || (e.Replacee is 'CrossbowHefty') )
{
/*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'SMW05SmallAmmo':'SMW05BigAmmo';
else */switch( Random[Replacements](0,20) )
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
e.Replacement = redpool[Random[Replacements](1,2)];
break;
case 6:
case 7:
case 8:
case 9:
case 10:
e.Replacement = greenpool[Random[Replacements](1,2)];
break;
case 11:
case 12:
case 13:
case 14:
e.Replacement = purplepool[Random[Replacements](0,2)];
break;
case 15:
case 16:
case 17:
e.Replacement = bluepool[Random[Replacements](0,2)];
break;
case 18:
case 19:
e.Replacement = whitepool[Random[Replacements](0,1)];
break;
case 20:
e.Replacement = 'BlackShell';
break;
}
if ( swwm_ondemandammo ) e.Replacement = 'SWWMShellAmmoBig';
else e.Replacement = SWWMShellAmmoBig.PickAmmo(true);
}
else if ( (e.Replacee is 'Shell') || (e.Replacee is 'CrossbowAmmo') )
{
/*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'SMW05SmallAmmo':'SMW05BundleSpawn';
else */switch( Random[Replacements](0,9) )
{
case 0:
case 1:
case 2:
case 3:
e.Replacement = redpool[0];
break;
case 4:
case 5:
case 6:
e.Replacement = greenpool[0];
break;
case 7:
case 8:
e.Replacement = purplepool[0];
break;
case 9:
e.Replacement = bluepool[0];
break;
}
if ( swwm_ondemandammo ) e.Replacement = 'SWWMShellAmmoSmall';
else e.Replacement = SWWMShellAmmoSmall.PickAmmo(true);
}
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,5)?'EvisceratorShell':Random[Replacements](0,9)?'EvisceratorTrioSpawn':'EvisceratorSixPack';
if ( swwm_ondemandammo ) e.Replacement = 'SWWMClipAmmoBig';
else e.Replacement = SWWMClipAmmoBig.PickAmmo(true);
}
else if ( (e.Replacee is 'Clip') || (e.Replacee is 'GoldWandAmmo') ) e.Replacement = /*(e.Replacee is 'GoldWandHefty')?'SheenSmallAmmo':'SheenTinyAmmo'*/'SWWMNothing';
else if ( (e.Replacee is 'Clip') || (e.Replacee is 'GoldWandAmmo') ) e.Replacement = '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';
if ( swwm_ondemandammo ) e.Replacement = 'SWWMBlastAmmoBig';
else e.Replacement = SWWMBlastAmmoBig.PickAmmo(true);
}
else if ( e.Replacee is 'BlasterAmmo' )
{
/*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'SheenSmallAmmo':'SheenTinyAmmo';
else */e.Replacement = 'EvisceratorShell';
if ( swwm_ondemandammo ) e.Replacement = 'SWWMBlastAmmoSmall';
else e.Replacement = SWWMBlastAmmoSmall.PickAmmo(true);
}
else if ( (e.Replacee is 'RocketBox') || (e.Replacee is 'PhoenixRodHefty') || (e.Replacee is 'MaceHefty') )
{
/*if ( Random[Replacements](0,1) ) e.Replacement = Random[Replacements](0,2)?'QuadravolAmmo':'QuadravolAmmoBundleSpawn';
else */switch ( Random[Replacements](0,11) )
{
case 0:
case 1:
case 2:
case 3:
case 4:
if ( Random[Replacements](0,5) ) e.Replacement = 'HellblazerMissiles';
else if ( Random[Replacements](0,4) ) e.Replacement = 'HellblazerMissileTrioSpawn';
else e.Replacement = 'HellblazerMissileMag';
break;
case 5:
case 6:
case 7:
case 8:
if ( Random[Replacements](0,6) ) e.Replacement = 'HellblazerCrackshots';
else e.Replacement = 'HellblazerCrackshotMag';
break;
case 9:
case 10:
if ( Random[Replacements](0,8) ) e.Replacement = 'HellblazerRavagers';
else e.Replacement = 'HellblazerRavagerMag';
break;
case 11:
if ( Random[Replacements](0,10) ) e.Replacement = 'HellblazerWarheads';
else e.Replacement = 'HellblazerWarheadMag';
break;
}
if ( swwm_ondemandammo ) e.Replacement = 'SWWMRocketAmmoBig';
else e.Replacement = SWWMRocketAmmoBig.PickAmmo(true);
}
else if ( (e.Replacee is 'RocketAmmo') || (e.Replacee is 'PhoenixRodAmmo') || (e.Replacee is 'MaceAmmo') )
{
/*if ( Random[Replacements](0,1) ) e.Replacement = 'QuadravolAmmo';
else */e.Replacement = Random[Replacements](0,2)?'HellblazerMissiles':'HellblazerCrackshots';
if ( swwm_ondemandammo ) e.Replacement = 'SWWMRocketAmmoSmall';
else e.Replacement = SWWMRocketAmmoSmall.PickAmmo(true);
}
else if ( (e.Replacee is 'CellPack') || (e.Replacee is 'SkullRodHefty') )
{
/*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';
}
else if ( Random[Replacements](0,2) ) e.Replacement = 'CandyGunBulletsBundleSpawn';
else e.Replacement = 'CandyGunAmmo';
if ( swwm_ondemandammo ) e.Replacement = 'SWWMCellAmmoBig';
else e.Replacement = SWWMCellAmmoBig.PickAmmo(true);
}
else if ( (e.Replacee is 'Cell') || (e.Replacee is 'SkullRodAmmo') )
{
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';
if ( swwm_ondemandammo ) e.Replacement = 'SWWMCellAmmoSmall';
else e.Replacement = SWWMCellAmmoSmall.PickAmmo(true);
}
else if ( e.Replacee is 'Mana1' ) e.Replacement = 'FabricatorTier1';
else if ( e.Replacee is 'Mana2' ) e.Replacement = 'FabricatorTier2';

View file

@ -500,25 +500,7 @@ Class HammerspaceEmbiggener : Inventory
}
let n = Spawn("BulkHammerspaceEmbiggener",pos);
Inventory(n).Amount = min(tamount,MaxAmount);
n.spawnpoint = spawnpoint;
n.spawnangle = spawnangle;
n.angle = angle;
n.pitch = pitch;
n.roll = roll;
n.special = special;
for ( int i=0; i<5; i++ ) n.args[i] = args[i];
n.special1 = special1;
n.special2 = special2;
n.spawnflags = spawnflags&~MTF_SECRET;
n.HandleSpawnFlags();
n.spawnflags = spawnflags;
n.bCountSecret = spawnflags&MTF_SECRET;
n.ChangeTid(tid);
n.vel = vel;
n.master = master;
n.tracer = tracer;
n.target = target;
if ( !bDROPPED ) n.bDROPPED = false;
SWWMUtility.TransferItemProp(self,n);
ClearCounters();
Destroy();
}

View file

@ -522,26 +522,17 @@ Class EvisceratorSixPack : EvisceratorShell
}
}
Class EvisceratorTrioSpawn : Actor
Class EvisceratorBundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
for ( int i=0; i<3; i++ )
int bnd = Random[Bundle](3,4);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("EvisceratorShell",Vec3Angle(12,i*120));
a.special = special;
a.angle = i*120;
a.FloatBobPhase = FloatBobPhase;
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
let a = Spawn("EvisceratorShell",Vec3Angle(12,i*(360/bnd)));
a.angle = i*(360/bnd);
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}
@ -604,26 +595,17 @@ Class HellblazerMissileMag : HellblazerMissiles
Height 26;
}
}
Class HellblazerMissileTrioSpawn : Actor
Class HellblazerMissileBundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
for ( int i=0; i<3; i++ )
int bnd = Random[Bundle](2,4);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("HellblazerMissiles",Vec3Angle(8,i*120));
a.special = special;
a.angle = i*120;
a.FloatBobPhase = FloatBobPhase;
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
let a = Spawn("HellblazerMissiles",Vec3Angle(8,i*(360/bnd)));
a.angle = i*(360/bnd);
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}
@ -682,6 +664,19 @@ Class HellblazerCrackshotMag : HellblazerCrackshots
Height 26;
}
}
Class HellblazerCrackshotBundleSpawn : SWWMAmmoSpawner
{
override void SpawnAmmo()
{
int bnd = Random[Bundle](2,3);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("HellblazerCrackshots",Vec3Angle(8,i*(360/bnd)));
a.angle = i*(360/bnd);
SWWMUtility.TransferItemProp(self,a,true);
}
}
}
Class HellblazerRavagers : Ammo
{
@ -839,6 +834,20 @@ Class SparkUnit : Ammo
Stop;
}
}
Class SparkUnitBundleSpawn : SWWMAmmoSpawner
{
override void SpawnAmmo()
{
int bnd = Random[Bundle](2,3);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("SparkUnit",Vec3Angle(8,i*(360/bnd)));
a.angle = i*(360/bnd);
SWWMUtility.TransferItemProp(self,a,true);
}
}
}
// ============================================================================
// Silver Bullet ammo
@ -1001,50 +1010,30 @@ Class SilverBullets2 : MagAmmo
}
}
Class SilverBulletsBundleSpawn : Actor
Class SilverBulletsBundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
int bnd = Random[Bundle](2,3);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("SilverBullets",Vec3Angle(6,i*(360/bnd)));
a.special = special;
a.angle = i*(360/bnd);
a.FloatBobPhase = FloatBobPhase;
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}
Class SilverBullets2BundleSpawn : Actor
Class SilverBullets2BundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
int bnd = Random[Bundle](2,3);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("SilverBullets2",Vec3Angle(6,i*(360/bnd)));
a.special = special;
a.angle = i*(360/bnd);
a.FloatBobPhase = FloatBobPhase;
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}
@ -1131,26 +1120,17 @@ Class CandyGunBullets : MagAmmo
}
}
Class CandyGunBulletsBundleSpawn : Actor
Class CandyGunBulletsBundleSpawn : SWWMAmmoSpawner
{
override void PostBeginPlay()
override void SpawnAmmo()
{
if ( bCOUNTSECRET ) level.total_secrets--;
int bnd = Random[Bundle](2,3);
for ( int i=0; i<bnd; i++ )
{
let a = Spawn("CandyGunBullets",Vec3Angle(4,i*(360/bnd)));
a.special = special;
a.angle = i*(360/bnd);
for ( int j=0; j<5; j++ ) a.args[j] = args[j];
if ( bCOUNTSECRET )
{
a.bCOUNTSECRET = true;
level.total_secrets++;
}
a.bDROPPED = bDROPPED;
SWWMUtility.TransferItemProp(self,a,true);
}
Destroy();
}
}

View file

@ -0,0 +1,199 @@
// on-demand ammo spawners
Mixin Class SWWMOndemandAmmoSpawner
{
override void SpawnAmmo()
{
let ac = PickAmmo();
if ( !ac ) return;
let a = Spawn(ac,pos);
SWWMUtility.TransferItemProp(self,a);
}
}
Class SWWMShellAmmoSmall : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('PuntzerBeta') || SWWMUtility.ItemExists('PuntzerGamma')) )
return Random[Replacements](0,2)?'SMW05SmallAmmo':'SMW05BundleSpawn';*/
switch( Random[Replacements](0,9) )
{
case 0:
case 1:
case 2:
case 3:
return 'RedShell';
case 4:
case 5:
case 6:
return 'GreenShell';
case 7:
case 8:
return 'PurpleShell';
}
// case 9
return 'BlueShell';
}
}
Class SWWMShellAmmoBig : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
// shell types (sorted by rarity)
static const Class<Actor> redpool[] = {'RedShell','RedShell2','RedShell4'};
static const Class<Actor> greenpool[] = {'GreenShell','GreenShell2','GreenShell4'};
static const Class<Actor> whitepool[] = {'WhiteShell','WhiteShell2'};
static const Class<Actor> purplepool[] = {'PurpleShell','PurpleShell2','PurpleShell4'};
static const Class<Actor> bluepool[] = {'BlueShell','BlueShell2','BlueShell4'};
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('PuntzerBeta') || SWWMUtility.ItemExists('PuntzerGamma')) )
return Random[Replacements](0,2)?'SMW05SmallAmmo':'SMW05BigAmmo';*/
switch( Random[Replacements](0,20) )
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
return redpool[Random[Replacements](0,2)];
case 6:
case 7:
case 8:
case 9:
case 10:
return greenpool[Random[Replacements](0,2)];
case 11:
case 12:
case 13:
case 14:
return purplepool[Random[Replacements](0,2)];
case 15:
case 16:
case 17:
return bluepool[Random[Replacements](0,2)];
case 18:
case 19:
return whitepool[Random[Replacements](0,1)];
}
// case 20
return 'BlackShell';
}
}
Class SWWMClipAmmoBig : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('HeavyMahsheenGun')) )
return Random[Replacements](0,2)?'SheenSmallAmmo':'SheenBigAmmo';*/
return Random[Replacements](0,5)?'EvisceratorShell':'EvisceratorBundleSpawn';
}
}
Class SWWMBlastAmmoSmall : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('HeavyMahsheenGun')) )
return Random[Replacements](0,2)?'SheenSmallAmmo':'SheenTinyAmmo';*/
return 'EvisceratorShell';
}
}
Class SWWMBlastAmmoBig : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('HeavyMahsheenGun')) )
return Random[Replacements](0,2)?'SheenBigAmmo':'SheenSmallAmmo';*/
return 'EvisceratorBundleSpawn';
}
}
Class SWWMRocketAmmoSmall : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('Quadravol')) ) return 'QuadravolAmmo';*/
return Random[Replacements](0,2)?'HellblazerMissiles':'HellblazerCrackshots';
}
}
Class SWWMRocketAmmoBig : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('Quadravol')) )
return Random[Replacements](0,2)?'QuadravolAmmo':'QuadravolAmmoBundleSpawn';*/
switch ( Random[Replacements](0,11) )
{
case 0:
case 1:
case 2:
case 3:
case 4:
return Random[Replacements](0,2)?'HellblazerMissiles':'HellblazerMissileBundleSpawn';
case 5:
case 6:
case 7:
case 8:
return Random[Replacements](0,3)?'HellblazerCrackshots':'HellblazerCrackshotBundleSpawn';
case 9:
case 10:
return 'HellblazerRavagers';
}
// case 11
return 'HellblazerWarheads';
}
}
Class SWWMCellAmmoSmall : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
/*if ( !Random[Replacements](0,2) && (notondemand || SWWMUtility.ItemExists('RayKhom') || SWWMUtility.ItemExists('GrandLance')) ) return 'RayBattery';*/
if ( !Random[Replacements](0,2) )
{
if ( !Random[Replacements](0,3) )
{
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('RayKhom')) ) return 'RayBolt';*/
if ( notondemand || SWWMUtility.ItemExists('CandyGun') ) return 'CandyGunBullets';
}
/*if ( Random[Replacements](0,1) && (notondemand || SWWMUtility.ItemExists('EMPCarbine')) ) return 'EMPCore';*/
if ( notondemand || SWWMUtility.ItemExists('SilverBullet') ) return Random[Replacements](0,2)?'SilverBullets':'SilverBullets2';
}
/*if ( !Random[Replacements](0,4) && (notondemand || SWWMUtility.ItemExists('BlackfireIgniter')) ) return 'DarkCanister';*/
return 'SparkUnit';
}
}
Class SWWMCellAmmoBig : SWWMAmmoSpawner
{
Mixin SWWMOndemandAmmoSpawner;
static Class<Actor> PickAmmo( bool notondemand = false )
{
/*if ( Random[Replacements](0,1) )
{
if ( !Random[Replacements](0,2) && (notondemand || SWWMUtility.ItemExists('EMPCarbine')) ) return Random[Replacements](0,3)?'EMPCoreBundleSpawn':'EMPCore';
if ( notondemand || SWWMUtility.ItemExists('RayKhom') ) return Random[Replacements](0,2)?'RayBoltBundleSpawn':'RayAmmo';
}*/
if ( !Random[Replacements](0,2) && (notondemand || SWWMUtility.ItemExists('SilverBullet')) )
{
if ( Random[Replacements](0,3) ) return Random[Replacements](0,2)?'SilverBulletsBundleSpawn':'SilverBullets2BundleSpawn';
return Random[Replacements](0,2)?'SilverBulletAmmo':'SilverBulletAmmo2';
}
if ( notondemand || SWWMUtility.ItemExists('CandyGun') ) return Random[Replacements](0,2)?'CandyGunBulletsBundleSpawn':'CandyGunAmmo';
/*if ( !Random[Replacements](0,2) && (notondemand || SWWMUtility.ItemExists('BlackfireIgniter')) ) return 'DarkCanister';*/
return Random[Replacements](0,2)?'SparkUnit':'SparkUnitBundleSpawn';
}
}

View file

@ -380,3 +380,25 @@ Mixin Class SWWMShellAmmo
Amount = Random[ShellDrop](1,clamp(dropamount,1,4));
}
}
// Ref class for ammo spawners, used by both on-demand replacers and bundles
Class SWWMAmmoSpawner : Actor abstract
{
virtual void SpawnAmmo() {}
override void PostBeginPlay()
{
SpawnAmmo();
ClearCounters();
Destroy();
}
default
{
+NOGRAVITY;
+NOBLOCKMAP;
+NOINTERACTION;
+NOTELEPORT;
+DONTSPLASH;
}
}

View file

@ -735,18 +735,8 @@ Class ChanceboxSpawner : Actor
}
let b = Spawn("Chancebox",pos);
// copy all our stuff
b.spawnangle = spawnangle;
b.angle = angle;
b.pitch = pitch;
b.roll = roll;
b.spawnpoint = spawnpoint;
b.special = special;
for ( int i=0; i<5; i++ )
b.Args[i] = Args[i];
b.spawnflags = spawnflags&~MTF_SECRET;
b.HandleSpawnFlags();
b.bCOUNTSECRET = spawnflags&MTF_SECRET;
b.ChangeTid(tid);
SWWMUtility.TransferItemProp(self,b);
ClearCounters();
Destroy();
}

View file

@ -2099,6 +2099,38 @@ Class SWWMUtility
if ( level.maptime ) return PickSWWMSlot3(); // always slot 3 after map start, prevents shotgun guys from dropping wallbusters
return PickPair(PickSWWMSlot3(),PickSWWMSlot4(),2);
}
// what RandomSpawner does, basically (simplified for items)
static play void TransferItemProp( Actor a, Actor b, bool bundlehack = false )
{
if ( bundlehack )
{
b.spawnpoint = b.pos;
b.spawnangle = int(b.angle);
}
else
{
b.spawnpoint = a.spawnpoint;
b.spawnangle = a.spawnangle;
b.angle = a.angle;
b.pitch = a.pitch;
b.roll = a.roll;
}
b.special = a.special;
b.FloatBobPhase = a.FloatBobPhase; // important
for ( int i=0; i<5; i++ ) b.args[i] = a.args[i];
b.special1 = a.special1;
b.special2 = a.special2;
b.spawnflags = a.spawnflags&~MTF_SECRET;
b.HandleSpawnFlags();
b.spawnflags = a.spawnflags;
b.bCountSecret = a.spawnflags&MTF_SECRET;
b.ChangeTid(a.tid);
b.vel = b.vel;
b.master = b.master;
b.tracer = b.tracer;
b.target = b.target;
b.bDROPPED = a.bDROPPED;
}
}
Class RadiusDebugSphere : Actor