Ammo buffer is fully implemented and working.

This commit is contained in:
Mari the Deer 2022-06-07 16:56:41 +02:00
commit 04e9d13c01
11 changed files with 232 additions and 123 deletions

View file

@ -8,7 +8,6 @@ Class SWWMAmmo : Ammo
String PickupTag;
Class<MagAmmo> MagAmmoType;
private int SAmmoFlags;
transient bool bSinglePrint; // used for pickup messages of mag manager
Property PickupTag : PickupTag;
Property MagAmmoType : MagAmmoType;
@ -27,12 +26,11 @@ Class SWWMAmmo : Ammo
{
if ( bUsePickupMsg ) return Super.PickupMessage();
String tagstr = "$T_"..PickupTag;
if ( (Amount > 1) && !bSinglePrint )
if ( Amount > 1 )
{
tagstr = tagstr.."S";
return String.Format("%d %s",Amount,StringTable.Localize(tagstr));
}
bSinglePrint = false;
return StringTable.Localize(tagstr);
}
@ -142,7 +140,7 @@ Class SWWMAmmo : Ammo
override bool HandlePickup( Inventory item )
{
// drop excess ammo
if ( (item is 'Ammo') && (Ammo(item).GetParentAmmo() == GetParentAmmo()) )
if ( !bUNDROPPABLE && !bUNTOSSABLE && (item is 'Ammo') && (Ammo(item).GetParentAmmo() == GetParentAmmo()) )
{
int excess = Amount+item.Amount;
if ( excess > MaxAmount ) excess -= MaxAmount;
@ -162,6 +160,23 @@ Class SWWMAmmo : Ammo
Inventory last;
while ( excess > 0 )
{
// first of all, see if we can ADD mag ammo
if ( MagAmmoType )
{
let ma = MagAmmo(Owner.FindInventory(MagAmmoType));
if ( !ma )
{
ma = MagAmmo(Spawn(MagAmmoType));
ma.Amount = 0;
ma.AttachToOwner(Owner);
}
if ( ma.Amount < (ma.MaxAmount-ma.ClipSize) )
{
ma.Amount += ma.ClipSize;
excess--;
continue;
}
}
for ( int i=0; i<ammotypes.Size(); i++ )
{
let def = GetDefaultByType(ammotypes[i]);
@ -177,7 +192,7 @@ Class SWWMAmmo : Ammo
}
}
}
else if ( MagAmmoType )
else if ( MagAmmoType && !GetDefaultByType(MagAmmoType).bUNDROPPABLE && !GetDefaultByType(MagAmmoType).bUNTOSSABLE )
{
// can we split it into mag ammo?
let ma = MagAmmo(Owner.FindInventory(MagAmmoType));
@ -192,12 +207,16 @@ Class SWWMAmmo : Ammo
// split into bullets
for ( int i=0; i<item.Amount; i++ )
{
if ( Amount < MaxAmount )
{
Amount++;
continue;
}
int bul = ma.ClipSize;
int maxgiveamt = min(ma.MaxAmount-ma.Amount,bul);
int dropamt = bul-maxgiveamt;
if ( dropamt > 0 ) ma.CreateTossable(dropamt);
if ( (bul == ma.ClipSize) && (Amount < MaxAmount) ) Amount++;
else ma.Amount = min(ma.MaxAmount,ma.Amount+bul);
ma.Amount = min(ma.MaxAmount,ma.Amount+bul);
}
item.bPickupGood = true;
return true;
@ -275,7 +294,7 @@ Class MagAmmo : Inventory abstract
int ClipSize;
int countdown;
String PickupTag;
transient bool bSinglePrint; // used for pickup messages of mag manager
int BackpackAmount;
Property ParentAmmo : ParentAmmo;
Property ClipSize : ClipSize;
@ -334,12 +353,11 @@ Class MagAmmo : Inventory abstract
override string PickupMessage()
{
String tagstr = "$T_"..PickupTag;
if ( (Amount > 1) && !bSinglePrint )
if ( Amount > 1 )
{
tagstr = tagstr.."S";
return String.Format("%d %s",Amount,StringTable.Localize(tagstr));
}
bSinglePrint = false;
return StringTable.Localize(tagstr);
}
@ -348,46 +366,71 @@ Class MagAmmo : Inventory abstract
// drop excess mag ammo
if ( (item is 'MagAmmo') && (MagAmmo(item).GetParentMagAmmo() == GetClass()) )
{
int excess = Amount+item.Amount;
if ( excess > MaxAmount ) excess -= MaxAmount;
if ( excess < item.Amount )
if ( bUNDROPPABLE || bUNTOSSABLE )
{
// enumerate all subclasses
Array<Class<MagAmmo> > ammotypes;
ammotypes.Clear();
for ( int i=0; i<AllActorClasses.Size(); i++ )
// undroppable mag ammo only drops full mags.
// due to the way this works, we theoretically
// should never end up with ammo "disappearing"
while ( Amount+item.Amount >= MaxAmount )
{
if ( AllActorClasses[i] is GetParentMagAmmo() )
ammotypes.Push((Class<MagAmmo>)(AllActorClasses[i]));
if ( Amount < ClipSize ) break;
// first of all, see if we can INCREASE
// parent ammo, rather than drop a mag
if ( pamo.Amount < pamo.MaxAmount ) pamo.Amount++;
else if ( !pamo.bUNDROPPABLE && !pamo.bUNTOSSABLE ) DoDrop(ParentAmmo);
Amount -= ClipSize;
}
// sort from largest to smallest
qsort_ammotypes(ammotypes,0,ammotypes.Size()-1);
// drop spares
Inventory last;
while ( excess > 0 )
}
else
{
int excess = Amount+item.Amount;
if ( excess > MaxAmount ) excess -= MaxAmount;
if ( excess < item.Amount )
{
// drop full mag if possible
if ( excess >= ClipSize )
// enumerate all subclasses
Array<Class<MagAmmo> > ammotypes;
ammotypes.Clear();
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
double ang = FRandom[Junk](0,360);
last = DoDrop(ParentAmmo);
last.SetOrigin(item.pos,false);
last.vel.xy = (cos(ang),sin(ang))*FRandom[Junk](2,5);
excess -= ClipSize;
continue;
if ( AllActorClasses[i] is GetParentMagAmmo() )
ammotypes.Push((Class<MagAmmo>)(AllActorClasses[i]));
}
// drop bullets otherwise
for ( int i=0; i<ammotypes.Size(); i++ )
// sort from largest to smallest
qsort_ammotypes(ammotypes,0,ammotypes.Size()-1);
// drop spares
Inventory last;
while ( excess > 0 )
{
let def = GetDefaultByType(ammotypes[i]);
if ( excess >= def.Amount )
// drop full mag if possible
if ( excess >= ClipSize )
{
// first of all, check if we can ADD a mag
if ( pamo.Amount < pamo.MaxAmount )
{
pamo.Amount++;
excess -= ClipSize;
continue;
}
double ang = FRandom[Junk](0,360);
last = DoDrop(ammotypes[i]);
last = DoDrop(ParentAmmo);
last.SetOrigin(item.pos,false);
last.vel.xy = (cos(ang),sin(ang))*FRandom[Junk](2,5);
excess -= def.Amount;
break;
excess -= ClipSize;
continue;
}
// drop bullets otherwise
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;
}
}
}
}
@ -485,13 +528,9 @@ Class MagAmmo : Inventory abstract
pamo.Amount = 0;
}
}
// check if we can fill a mag (delayed)
// check if we can fill a mag
if ( (Amount < ClipSize) || (pamo.Amount >= pamo.MaxAmount) )
{
countdown = 35;
return;
}
if ( countdown-- > 0 ) return;
MagFill();
}
@ -514,13 +553,7 @@ Class MagAmmo : Inventory abstract
pamo.Amount++;
Amount -= ClipSize;
given = true;
if ( Owner.CheckLocalView() )
{
SWWMAmmo(pamo).bSinglePrint = true;
pamo.PrintPickupMessage(true,pamo.PickupMessage());
}
}
if ( given ) pamo.PlayPickupSound(Owner);
return given;
}
@ -572,7 +605,14 @@ Class MagAmmo : Inventory abstract
override void ModifyDropAmount( int dropamount )
{
Super.ModifyDropAmount(dropamount);
Amount = min(Random[ShellDrop](1,ClipSize),Amount);
int maxdrop = 1;
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
if ( !(AllActorClasses[i] is GetParentMagAmmo()) ) continue;
let def = GetDefaultByType((Class<MagAmmo>)(AllActorClasses[i]));
maxdrop = max(maxdrop,def.amount);
}
Amount = Random[ShellDrop](1,clamp(dropamount,1,maxdrop));
}
}