Omnisight now handles 3d floors and midtextures, and exit line merging works properly. Reduced Pusher primary fire damage slightly. Cleared improper usages of GetAge().
1199 lines
24 KiB
Text
1199 lines
24 KiB
Text
// All the ammo items go here
|
|
|
|
// Common code for ammo division
|
|
Mixin Class SWWMAmmo
|
|
{
|
|
private Inventory DoDrop( Class<Inventory> type )
|
|
{
|
|
let copy = Inventory(Spawn(type,Owner.Pos,NO_REPLACE));
|
|
if ( !copy ) return null;
|
|
copy.DropTime = 30;
|
|
copy.bSpecial = copy.bSolid = false;
|
|
copy.SetOrigin(Owner.Vec3Offset(0,0,10.),false);
|
|
copy.Angle = Owner.Angle;
|
|
copy.VelFromAngle(5.);
|
|
copy.Vel.Z = 1.;
|
|
copy.Vel += Owner.Vel;
|
|
copy.bNoGravity = false;
|
|
copy.ClearCounters();
|
|
copy.OnDrop(Owner);
|
|
copy.vel += (RotateVector((FRandom[Junk](-1.5,.5),FRandom[Junk](-2.5,2.5)),Owner.angle),FRandom[Junk](2.,5.));
|
|
return copy;
|
|
}
|
|
|
|
override bool SpecialDropAction( Actor dropper )
|
|
{
|
|
if ( Amount != default.Amount )
|
|
{
|
|
// needed for positioning to work
|
|
Owner = dropper;
|
|
CreateTossable(Amount);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool CmpAmmo( Class<Ammo> a, Class<Ammo> b )
|
|
{
|
|
let amta = GetDefaultByType(a).Amount;
|
|
let amtb = GetDefaultByType(b).Amount;
|
|
return (amta < amtb);
|
|
}
|
|
|
|
private int partition_ammotypes( Array<Class<Ammo> > a, int l, int h )
|
|
{
|
|
Class<Ammo> pv = a[h];
|
|
int i = (l-1);
|
|
for ( int j=l; j<=(h-1); j++ )
|
|
{
|
|
if ( CmpAmmo(pv,a[j]) )
|
|
{
|
|
i++;
|
|
Class<Ammo> tmp = a[j];
|
|
a[j] = a[i];
|
|
a[i] = tmp;
|
|
}
|
|
}
|
|
Class<Ammo> tmp = a[h];
|
|
a[h] = a[i+1];
|
|
a[i+1] = tmp;
|
|
return i+1;
|
|
}
|
|
private void qsort_ammotypes( Array<Class<Ammo> > a, int l, int h )
|
|
{
|
|
if ( l >= h ) return;
|
|
int p = partition_ammotypes(a,l,h);
|
|
qsort_ammotypes(a,l,p-1);
|
|
qsort_ammotypes(a,p+1,h);
|
|
}
|
|
|
|
override inventory CreateTossable( int amt )
|
|
{
|
|
if ( bUndroppable || bUntossable || !Owner || (Amount <= 0) || (amt == 0) )
|
|
return null;
|
|
// cap
|
|
amt = min(amount,amt);
|
|
// enumerate all subclasses
|
|
Array<Class<Ammo> > ammotypes;
|
|
ammotypes.Clear();
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
if ( AllActorClasses[i] is GetParentAmmo() )
|
|
ammotypes.Push((Class<Ammo>)(AllActorClasses[i]));
|
|
}
|
|
// sort from largest to smallest
|
|
qsort_ammotypes(ammotypes,0,ammotypes.Size()-1);
|
|
// perform subdivision
|
|
Inventory last = null;
|
|
while ( amt > 0 )
|
|
{
|
|
for ( int i=0; i<ammotypes.Size(); i++ )
|
|
{
|
|
let def = GetDefaultByType(ammotypes[i]);
|
|
if ( amt >= def.Amount )
|
|
{
|
|
last = DoDrop(ammotypes[i]);
|
|
amt -= def.Amount;
|
|
Amount -= def.Amount;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return last;
|
|
}
|
|
|
|
override bool HandlePickup( Inventory item )
|
|
{
|
|
// drop excess ammo
|
|
if ( (item is 'Ammo') && (Ammo(item).GetParentAmmo() == GetParentAmmo()) )
|
|
{
|
|
int excess = Amount+item.Amount;
|
|
if ( excess > MaxAmount ) excess -= MaxAmount;
|
|
if ( excess < item.Amount )
|
|
{
|
|
// enumerate all subclasses
|
|
Array<Class<Ammo> > ammotypes;
|
|
ammotypes.Clear();
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
if ( AllActorClasses[i] is GetParentAmmo() )
|
|
ammotypes.Push((Class<Ammo>)(AllActorClasses[i]));
|
|
}
|
|
// sort from largest to smallest
|
|
for ( int i=0; i<ammotypes.Size(); i++ )
|
|
{
|
|
int j = 1;
|
|
while ( j < ammotypes.Size() )
|
|
{
|
|
int k = j;
|
|
while ( (k > 0) && CmpAmmo(ammotypes[k-1],ammotypes[k]) )
|
|
{
|
|
Class<Ammo> tmp = ammotypes[k];
|
|
ammotypes[k] = ammotypes[k-1];
|
|
ammotypes[k-1] = tmp;
|
|
k--;
|
|
}
|
|
j++;
|
|
}
|
|
}
|
|
// drop spares
|
|
Inventory last;
|
|
while ( excess > 0 )
|
|
{
|
|
for ( int i=0; i<ammotypes.Size(); i++ )
|
|
{
|
|
let def = GetDefaultByType(ammotypes[i]);
|
|
if ( excess >= def.Amount )
|
|
{
|
|
double ang = FRandom[Junk](0,360);
|
|
last = DoDrop(ammotypes[i]);
|
|
last.SetOrigin(item.pos,false);
|
|
last.vel.xy = (cos(ang),sin(ang))*FRandom[Junk](2,5);
|
|
excess -= def.Amount;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return Super.HandlePickup(item);
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Spreadgun / Wallbuster ammo
|
|
// ============================================================================
|
|
|
|
// Common code for grouped shell handling and per-amount pickup messages
|
|
Mixin Class SWWMShellAmmo
|
|
{
|
|
override string PickupMessage()
|
|
{
|
|
String tagstr = "$T_"..GetParentAmmo().GetClassName();
|
|
tagstr.MakeUpper();
|
|
if ( Amount > 1 )
|
|
{
|
|
tagstr = tagstr.."S";
|
|
return String.Format("%d %s",Amount,StringTable.Localize(tagstr));
|
|
}
|
|
return StringTable.Localize(tagstr);
|
|
}
|
|
|
|
override void ModifyDropAmount( int dropamount )
|
|
{
|
|
Super.ModifyDropAmount(dropamount);
|
|
Amount = max(1,Amount+Random[ShellDrop](-2,1));
|
|
}
|
|
}
|
|
|
|
Class RedShell : Ammo
|
|
{
|
|
Mixin SWWMShellAmmo;
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_REDSHELLS";
|
|
Stamina 500;
|
|
Inventory.Icon "graphics/HUD/Icons/A_ShellsNormal.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 40;
|
|
Ammo.BackpackAmount 8;
|
|
Ammo.DropAmount 3;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class RedShell2 : RedShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 2;
|
|
}
|
|
}
|
|
Class RedShell4 : RedShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 4;
|
|
}
|
|
}
|
|
Class RedShell8 : RedShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 8;
|
|
}
|
|
}
|
|
Class RedShell12 : RedShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 12;
|
|
}
|
|
}
|
|
Class RedShell16 : RedShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 16;
|
|
}
|
|
}
|
|
|
|
Class GreenShell : Ammo
|
|
{
|
|
Mixin SWWMShellAmmo;
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_GREENSHELLS";
|
|
Stamina 800;
|
|
Inventory.Icon "graphics/HUD/Icons/A_ShellsSlug.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 32;
|
|
Ammo.BackpackAmount 4;
|
|
Ammo.DropAmount 2;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class GreenShell2 : GreenShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 2;
|
|
}
|
|
}
|
|
Class GreenShell4 : GreenShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 4;
|
|
}
|
|
}
|
|
Class GreenShell8 : GreenShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 8;
|
|
}
|
|
}
|
|
Class GreenShell12 : GreenShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 12;
|
|
}
|
|
}
|
|
|
|
Class WhiteShell : Ammo
|
|
{
|
|
Mixin SWWMShellAmmo;
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_WHITESHELLS";
|
|
Stamina 1000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_ShellsDragon.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 20;
|
|
Ammo.BackpackAmount 2;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class WhiteShell2 : WhiteShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 2;
|
|
}
|
|
}
|
|
Class WhiteShell4 : WhiteShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 4;
|
|
}
|
|
}
|
|
Class WhiteShell8 : WhiteShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 8;
|
|
}
|
|
}
|
|
|
|
Class BlueShell : Ammo
|
|
{
|
|
Mixin SWWMShellAmmo;
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_BLUESHELLS";
|
|
Stamina 1500;
|
|
Inventory.Icon "graphics/HUD/Icons/A_ShellsKinylum.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 24;
|
|
Ammo.BackpackAmount 4;
|
|
Ammo.DropAmount 2;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class BlueShell2 : BlueShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 2;
|
|
}
|
|
}
|
|
Class BlueShell4 : BlueShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 4;
|
|
}
|
|
}
|
|
Class BlueShell8 : BlueShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 8;
|
|
}
|
|
}
|
|
|
|
Class BlackShell : Ammo
|
|
{
|
|
Mixin SWWMShellAmmo;
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_BLACKSHELLS";
|
|
Stamina 3500;
|
|
Inventory.Icon "graphics/HUD/Icons/A_ShellsFuck.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 12;
|
|
Ammo.BackpackAmount 2;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class BlackShell2 : BlackShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 2;
|
|
}
|
|
}
|
|
Class BlackShell4 : BlackShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 4;
|
|
}
|
|
}
|
|
|
|
Class PurpleShell : Ammo
|
|
{
|
|
Mixin SWWMShellAmmo;
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_PURPLESHELLS";
|
|
Stamina 1200;
|
|
Inventory.Icon "graphics/HUD/Icons/A_ShellsBall.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 20;
|
|
Ammo.BackpackAmount 4;
|
|
Ammo.DropAmount 2;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class PurpleShell2 : PurpleShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 2;
|
|
}
|
|
}
|
|
Class PurpleShell4 : PurpleShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Amount 4;
|
|
}
|
|
}
|
|
|
|
Class GoldShellSparkle : Actor
|
|
{
|
|
override void PostBeginPlay()
|
|
{
|
|
Scale *= FRandom[Goldy](.5,1.5);
|
|
vel.z = FRandom[Goldy](.5,1.5);
|
|
}
|
|
override void Tick()
|
|
{
|
|
if ( isFrozen() ) return;
|
|
SetOrigin(Vec3Offset(0,0,vel.z),true);
|
|
alpha -= .02;
|
|
if ( alpha <= 0 ) Destroy();
|
|
}
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Scale 0.05;
|
|
+NOGRAVITY;
|
|
+NOBLOCKMAP;
|
|
+NOINTERACTION;
|
|
+DONTSPLASH;
|
|
+NOTELEPORT;
|
|
+FORCEXYBILLBOARD;
|
|
FloatBobPhase 0;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
BLPF A -1 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class GoldShell : Ammo
|
|
{
|
|
Mixin SWWMShellAmmo;
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
action void A_GoldShellTrail()
|
|
{
|
|
if ( Random[Goldy](0,2) ) return;
|
|
Spawn("GoldShellSparkle",Vec3Offset(FRandom[Goldy](-2,2),FRandom[Goldy](-2,2),FRandom[Goldy](10,18)));
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_GOLDSHELLS";
|
|
Stamina 0;
|
|
Inventory.Icon "graphics/HUD/Icons/A_ShellsGold.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 3;
|
|
Ammo.BackpackAmount 0;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A 1 A_GoldShellTrail();
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Eviscerator ammo
|
|
// ============================================================================
|
|
|
|
Class EvisceratorShell : Ammo
|
|
{
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_EVISHELLS";
|
|
Inventory.PickupMessage "$T_EVISHELL";
|
|
Stamina 2500;
|
|
Inventory.Icon "graphics/HUD/Icons/A_Eviscerator.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 24;
|
|
Ammo.BackpackAmount 3;
|
|
Ammo.DropAmount 2;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class EvisceratorSixPack : EvisceratorShell
|
|
{
|
|
Default
|
|
{
|
|
Inventory.PickupMessage "$I_EVISHELLPAK";
|
|
Inventory.Amount 6;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Hellblazer ammo
|
|
// ============================================================================
|
|
|
|
Class HellblazerMissiles : Ammo
|
|
{
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_HELLMISSILES";
|
|
Inventory.PickupMessage "$T_HELLMISSILE";
|
|
Stamina 6000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_HellblazerMissile.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 30;
|
|
Ammo.BackpackAmount 3;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class HellblazerMissileMag : HellblazerMissiles
|
|
{
|
|
Default
|
|
{
|
|
Inventory.PickupMessage "$T_HELLMISSILEMAG";
|
|
Inventory.Amount 6;
|
|
}
|
|
}
|
|
|
|
Class HellblazerCrackshots : Ammo
|
|
{
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_HELLCLUSTERS";
|
|
Inventory.PickupMessage "$T_HELLCLUSTER";
|
|
Stamina 8000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_HellblazerCrackshot.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 18;
|
|
Ammo.BackpackAmount 2;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class HellblazerCrackshotMag : HellblazerCrackshots
|
|
{
|
|
Default
|
|
{
|
|
Inventory.PickupMessage "$T_HELLCLUSTERMAG";
|
|
Inventory.Amount 3;
|
|
}
|
|
}
|
|
|
|
Class HellblazerRavagers : Ammo
|
|
{
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_HELLBURNINATORS";
|
|
Inventory.PickupMessage "$T_HELLBURNINATOR";
|
|
Stamina 12000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_HellblazerRavager.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 9;
|
|
Ammo.BackpackAmount 1;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class HellblazerRavagerMag : HellblazerRavagers
|
|
{
|
|
Default
|
|
{
|
|
Inventory.PickupMessage "$T_HELLBURNINATORMAG";
|
|
Inventory.Amount 3;
|
|
}
|
|
}
|
|
|
|
Class HellblazerWarheads : Ammo
|
|
{
|
|
Mixin SWWMAmmo;
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_HELLNUKES";
|
|
Inventory.PickupMessage "$T_HELLNUKE";
|
|
Stamina 25000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_HellblazerWarhead.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 4;
|
|
Ammo.BackpackAmount 0;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class HellblazerWarheadMag : HellblazerWarheads
|
|
{
|
|
Default
|
|
{
|
|
Inventory.PickupMessage "$T_HELLNUKEMAG";
|
|
Inventory.Amount 2;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Sparkster ammo
|
|
// ============================================================================
|
|
|
|
Class SparkUnit : Ammo
|
|
{
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_SPARKUNIT";
|
|
Inventory.PickupMessage "$T_SPARKUNIT";
|
|
Stamina 50000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_Sparkster.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 4;
|
|
Ammo.BackpackAmount 1;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Silver Bullet ammo
|
|
// ============================================================================
|
|
|
|
Class SilverBulletAmmo : Ammo
|
|
{
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_XSBMAG";
|
|
Inventory.PickupMessage "$T_XSBMAG";
|
|
Stamina 70000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_SilverBullet.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 3;
|
|
Ammo.BackpackAmount 0;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Candygun ammo
|
|
// ============================================================================
|
|
|
|
Class CandyGunAmmo : Ammo
|
|
{
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_CANDYMAG";
|
|
Inventory.PickupMessage "$T_CANDYMAG";
|
|
Stamina 100000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_CandyGun.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 2;
|
|
Ammo.BackpackAmount 0;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class CandyGunSpares : Ammo
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_CANDYSPARE";
|
|
Stamina 600000;
|
|
Inventory.Icon "graphics/HUD/Icons/W_CandyGun.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 4;
|
|
Ammo.BackpackMaxAmount 4;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Ynykron ammo
|
|
// ============================================================================
|
|
|
|
Class YnykronAmmo : Ammo
|
|
{
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_YNYKRONAMMO";
|
|
Inventory.PickupMessage "$T_YNYKRONAMMO";
|
|
Stamina 3000000;
|
|
Inventory.Icon "graphics/HUD/Icons/A_Ynykron.png";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 1;
|
|
Ammo.BackpackAmount 0;
|
|
Ammo.DropAmount 1;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Ammo fabricator
|
|
// ============================================================================
|
|
|
|
Class AmmoFabricator : Inventory abstract
|
|
{
|
|
Mixin SWWMOverlapPickupSound;
|
|
|
|
int budget, pertype, maxunitprice;
|
|
|
|
Property Budget : budget;
|
|
Property PerType : pertype;
|
|
Property MaxUnitPrice : maxunitprice;
|
|
|
|
override Inventory CreateCopy( Actor other )
|
|
{
|
|
// additional lore
|
|
SWWMLoreLibrary.Add(other.player,"Fabricator");
|
|
return Super.CreateCopy(other);
|
|
}
|
|
|
|
private bool CmpFabAmmo( Class<Ammo> a, Class<Ammo> b )
|
|
{
|
|
let ia = Owner.FindInventory(a);
|
|
int cnta = ia?ia.Amount:0;
|
|
int maxa = ia?ia.MaxAmount:GetDefaultByType(a).Amount;
|
|
let ib = Owner.FindInventory(b);
|
|
int cntb = ib?ib.Amount:0;
|
|
int maxb = ib?ib.MaxAmount:GetDefaultByType(b).Amount;
|
|
double facta = cnta/double(maxa);
|
|
double factb = cntb/double(maxb);
|
|
return (facta > factb);
|
|
}
|
|
|
|
private int partition_fabammo( Array<Class<Ammo> > a, int l, int h )
|
|
{
|
|
Class<Ammo> pv = a[h];
|
|
int i = (l-1);
|
|
for ( int j=l; j<=(h-1); j++ )
|
|
{
|
|
if ( CmpFabAmmo(pv,a[j]) )
|
|
{
|
|
i++;
|
|
Class<Ammo> tmp = a[j];
|
|
a[j] = a[i];
|
|
a[i] = tmp;
|
|
}
|
|
}
|
|
Class<Ammo> tmp = a[h];
|
|
a[h] = a[i+1];
|
|
a[i+1] = tmp;
|
|
return i+1;
|
|
}
|
|
private void qsort_fabammo( Array<Class<Ammo> > a, int l, int h )
|
|
{
|
|
if ( l >= h ) return;
|
|
int p = partition_fabammo(a,l,h);
|
|
qsort_fabammo(a,l,p-1);
|
|
qsort_fabammo(a,p+1,h);
|
|
}
|
|
|
|
bool FabricateAmmo()
|
|
{
|
|
Array<Class<Ammo> > available;
|
|
// populate ammo production list
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
let a = (Class<Ammo>)(AllActorClasses[i]);
|
|
// only direct descendants of ammo with a set price below our max unit price
|
|
if ( !a || (a.GetParentClass() != 'Ammo') ) continue;
|
|
let def = GetDefaultByType(a);
|
|
if ( !(def.Stamina) || (def.Stamina > maxunitprice) ) continue;
|
|
available.Push(a);
|
|
}
|
|
// sort by "need weight" (prioritize ammo that the player lacks over ammo that te player has plenty of
|
|
qsort_fabammo(available,0,available.Size()-1);
|
|
// loop through until we fill the inventory or run out of budget
|
|
bool given = false;
|
|
int consumed = 0;
|
|
String fabstr = "";
|
|
bool comma = false;
|
|
for ( int i=0; i<available.Size(); i++ )
|
|
{
|
|
int amt, lim;
|
|
int cnt = 0;
|
|
Ammo cur = Ammo(Owner.FindInventory(available[i]));
|
|
if ( cur )
|
|
{
|
|
amt = cur.Amount;
|
|
lim = cur.MaxAmount;
|
|
}
|
|
else
|
|
{
|
|
cur = Ammo(Spawn(available[i]));
|
|
amt = cur.Amount = 0;
|
|
lim = cur.MaxAmount;
|
|
cur.AttachToOwner(Owner);
|
|
}
|
|
while ( (amt < lim) && (consumed+cur.default.Stamina < budget) && (cnt < pertype) )
|
|
{
|
|
consumed += cur.default.Stamina;
|
|
amt = ++cur.Amount;
|
|
cnt++;
|
|
given = true;
|
|
}
|
|
if ( cnt > 0 )
|
|
{
|
|
if ( comma ) fabstr.AppendFormat(", %dx %s",cnt,cur.GetTag());
|
|
else fabstr.AppendFormat("%dx %s",cnt,cur.GetTag());
|
|
comma = true;
|
|
}
|
|
}
|
|
if ( given ) PrintPickupMessage(true,fabstr);
|
|
return given;
|
|
}
|
|
|
|
override bool Use( bool pickup )
|
|
{
|
|
bool shouldautouse = false;
|
|
if ( swwm_enforceautouseammo == 1 ) shouldautouse = true;
|
|
else if ( swwm_enforceautouseammo == -1 ) shouldautouse = false;
|
|
else shouldautouse = CVar.GetCVar('swwm_autouseammo',Owner.player).GetBool();
|
|
if ( pickup && !shouldautouse ) return false;
|
|
if ( FabricateAmmo() )
|
|
{
|
|
if ( pickup && ((Owner.player == players[consoleplayer]) || bBigPowerup) ) Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Default
|
|
{
|
|
+INVENTORY.INVBAR;
|
|
+INVENTORY.AUTOACTIVATE;
|
|
+FLOATBOB;
|
|
Inventory.UseSound "fabricator/use";
|
|
Inventory.MaxAmount 32;
|
|
Inventory.InterHubAmount 32;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class FabricatorTier1 : AmmoFabricator
|
|
{
|
|
Mixin SWWMAutoUseFix;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_FABRICATOR1";
|
|
Inventory.Icon "graphics/HUD/Icons/I_Fabricator1.png";
|
|
Inventory.PickupMessage "$T_FABRICATOR1";
|
|
Inventory.MaxAmount 30;
|
|
AmmoFabricator.Budget 5000;
|
|
AmmoFabricator.PerType 2;
|
|
AmmoFabricator.MaxUnitPrice 2500;
|
|
Stamina 3000;
|
|
}
|
|
}
|
|
Class FabricatorTier2 : AmmoFabricator
|
|
{
|
|
Mixin SWWMAutoUseFix;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_FABRICATOR2";
|
|
Inventory.Icon "graphics/HUD/Icons/I_Fabricator2.png";
|
|
Inventory.PickupMessage "$T_FABRICATOR2";
|
|
Inventory.MaxAmount 20;
|
|
AmmoFabricator.Budget 15000;
|
|
AmmoFabricator.PerType 4;
|
|
AmmoFabricator.MaxUnitPrice 10000;
|
|
Stamina 12000;
|
|
}
|
|
}
|
|
Class FabricatorTier3 : AmmoFabricator
|
|
{
|
|
Mixin SWWMAutoUseFix;
|
|
|
|
Default
|
|
{
|
|
Tag "$T_FABRICATOR3";
|
|
Inventory.Icon "graphics/HUD/Icons/I_Fabricator3.png";
|
|
Inventory.PickupMessage "$T_FABRICATOR3";
|
|
Inventory.MaxAmount 10;
|
|
AmmoFabricator.Budget 150000;
|
|
AmmoFabricator.PerType 8;
|
|
AmmoFabricator.MaxUnitPrice 80000;
|
|
Stamina 150000;
|
|
}
|
|
}
|
|
Class FabricatorTier4 : AmmoFabricator
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_FABRICATOR4";
|
|
Inventory.Icon "graphics/HUD/Icons/I_Fabricator4.png";
|
|
Inventory.PickupMessage "$T_FABRICATOR4";
|
|
Inventory.MaxAmount 5;
|
|
AmmoFabricator.Budget int.max;
|
|
AmmoFabricator.PerType int.max;
|
|
AmmoFabricator.MaxUnitPrice int.max;
|
|
-INVENTORY.AUTOACTIVATE;
|
|
Stamina 1920000;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Hammerspace embiggener
|
|
// ============================================================================
|
|
|
|
Class HammerspaceEmbiggener : Inventory
|
|
{
|
|
Mixin SWWMOverlapPickupSound;
|
|
bool cheatedin;
|
|
|
|
override void SetGiveAmount( Actor receiver, int amount, bool givecheat )
|
|
{
|
|
Super.SetGiveAmount(receiver,amount,givecheat);
|
|
// hackeroo
|
|
cheatedin = givecheat;
|
|
}
|
|
|
|
override Inventory CreateCopy( Actor other )
|
|
{
|
|
if ( !cheatedin ) other.A_StartSound("powerup/embiggener",CHAN_ITEMEXTRA);
|
|
cheatedin = false;
|
|
// Find every unique type of ammoitem. Give it to the player if
|
|
// he doesn't have it already, and increase its maximum capacity.
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
let type = (class<Ammo>)(AllActorClasses[i]);
|
|
if ( !type || (type.GetParentClass() != 'Ammo') ) continue;
|
|
// check that it's for a valid weapon
|
|
bool isvalid = false;
|
|
for ( int j=0; j<AllActorClasses.Size(); j++ )
|
|
{
|
|
let type2 = (class<Weapon>)(AllActorClasses[j]);
|
|
if ( !type2 ) continue;
|
|
let rep = GetReplacement(type2);
|
|
if ( (rep != type2) && !(rep is "DehackedPickup") ) continue;
|
|
readonly<Weapon> weap = GetDefaultByType(type2);
|
|
if ( !other.player || !other.player.weapons.LocateWeapon(type2) || weap.bCheatNotWeapon ) continue;
|
|
if ( (type2 is 'SWWMWeapon') && SWWMWeapon(weap).UsesAmmo(type) )
|
|
{
|
|
isvalid = true;
|
|
break;
|
|
}
|
|
if ( (weap.AmmoType1 == type) || (weap.AmmoType2 == type) )
|
|
{
|
|
isvalid = true;
|
|
break;
|
|
}
|
|
}
|
|
if ( !isvalid ) continue;
|
|
let ammoitem = Ammo(other.FindInventory(type));
|
|
int amount = GetDefaultByType(type).BackpackAmount;
|
|
// extra ammo in baby mode and nightmare mode
|
|
if ( !bIgnoreSkill ) amount = int(amount*G_SkillPropertyFloat(SKILLP_AmmoFactor));
|
|
if ( amount < 0 ) amount = 0;
|
|
if ( !ammoitem )
|
|
{
|
|
// The player did not have the ammoitem. Add it.
|
|
ammoitem = Ammo(Spawn(type));
|
|
ammoitem.Amount = amount;
|
|
if ( ammoitem.BackpackMaxAmount != ammoitem.default.MaxAmount )
|
|
ammoitem.MaxAmount = int(ammoitem.default.MaxAmount*(1+self.Amount/2.));
|
|
if ( (ammoitem.Amount > ammoitem.MaxAmount) && !sv_unlimited_pickup )
|
|
ammoitem.Amount = ammoitem.MaxAmount;
|
|
ammoitem.AttachToOwner(other);
|
|
}
|
|
else
|
|
{
|
|
// The player had the ammoitem. Give some more.
|
|
if ( ammoitem.BackpackMaxAmount != ammoitem.default.MaxAmount )
|
|
ammoitem.MaxAmount = int(ammoitem.default.MaxAmount*(1+self.Amount/2.));
|
|
if ( ammoitem.Amount < ammoitem.MaxAmount )
|
|
{
|
|
ammoitem.Amount += amount;
|
|
if ( (ammoitem.Amount > ammoitem.MaxAmount) && !sv_unlimited_pickup )
|
|
ammoitem.Amount = ammoitem.MaxAmount;
|
|
}
|
|
}
|
|
}
|
|
return Inventory.CreateCopy(other);
|
|
}
|
|
|
|
override bool HandlePickup( Inventory item )
|
|
{
|
|
bool res = Super.HandlePickup(item);
|
|
if ( item.GetClass() == GetClass() )
|
|
{
|
|
if ( !HammerspaceEmbiggener(item).cheatedin ) Owner.A_StartSound("powerup/embiggener",CHAN_ITEMEXTRA);
|
|
// readjust ammo values to new capacity
|
|
for ( Inventory i=Owner.Inv; i; i=i.Inv )
|
|
{
|
|
if ( !(i is 'Ammo') ) continue;
|
|
if ( Ammo(i).BackpackMaxAmount != i.default.MaxAmount )
|
|
i.MaxAmount = int(i.Default.MaxAmount*(1+self.Amount/2.));
|
|
int amount = Ammo(i).BackpackAmount;
|
|
if ( !bIgnoreSkill ) amount = int(amount*G_SkillPropertyFloat(SKILLP_AmmoFactor));
|
|
i.Amount += amount;
|
|
if ( (i.Amount > i.MaxAmount) && !sv_unlimited_pickup )
|
|
i.Amount = i.MaxAmount;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
override void DetachFromOwner()
|
|
{
|
|
// reset upgrade
|
|
for ( Inventory i=Owner.Inv; i; i=i.Inv )
|
|
{
|
|
if ( !(i is 'Ammo') ) continue;
|
|
i.MaxAmount = i.Default.MaxAmount;
|
|
if ( i.Amount > i.MaxAmount )
|
|
i.Amount = i.MaxAmount;
|
|
}
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_EMBIGGENER";
|
|
Inventory.PickupMessage "$T_EMBIGGENER";
|
|
Inventory.MaxAmount 8;
|
|
Inventory.InterHubAmount 8;
|
|
+INVENTORY.UNDROPPABLE;
|
|
+INVENTORY.UNTOSSABLE;
|
|
+INVENTORY.UNCLEARABLE;
|
|
+INVENTORY.ALWAYSPICKUP;
|
|
+COUNTITEM;
|
|
+FLOATBOB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
}
|
|
}
|