diff --git a/language.version b/language.version index 6b641a33f..7f3d6cc64 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r99 \cu(Tue 7 Jun 13:42:13 CEST 2022)\c-"; -SWWM_SHORTVER="\cw1.3pre r99 \cu(2022-06-07 13:42:13)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r100 \cu(Tue 7 Jun 16:56:41 CEST 2022)\c-"; +SWWM_SHORTVER="\cw1.3pre r100 \cu(2022-06-07 16:56:41)\c-"; diff --git a/zscript.txt b/zscript.txt index 1ee455cbb..bdbf4892e 100644 --- a/zscript.txt +++ b/zscript.txt @@ -101,6 +101,7 @@ version "4.8" #include "zscript/weapons/swwm_baseweapon_fx.zsc" #include "zscript/weapons/swwm_baseweapon_melee.zsc" #include "zscript/weapons/swwm_baseweapon_precisechair.zsc" +#include "zscript/weapons/swwm_baseweapon_ammobuffer.zsc" #include "zscript/weapons/swwm_deepdarkimpact.zsc" #include "zscript/weapons/swwm_deepdarkimpact_fx.zsc" #include "zscript/weapons/swwm_splode.zsc" diff --git a/zscript/items/swwm_baseammo.zsc b/zscript/items/swwm_baseammo.zsc index 25ef5a965..50eb262f0 100644 --- a/zscript/items/swwm_baseammo.zsc +++ b/zscript/items/swwm_baseammo.zsc @@ -8,7 +8,6 @@ Class SWWMAmmo : Ammo String PickupTag; Class 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 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 > ammotypes; - ammotypes.Clear(); - for ( int i=0; i= MaxAmount ) { - if ( AllActorClasses[i] is GetParentMagAmmo() ) - ammotypes.Push((Class)(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 > ammotypes; + ammotypes.Clear(); + for ( int i=0; i)(AllActorClasses[i])); } - // drop bullets otherwise - for ( int i=0; i 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= 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[i])); + maxdrop = max(maxdrop,def.amount); + } + Amount = Random[ShellDrop](1,clamp(dropamount,1,maxdrop)); } } diff --git a/zscript/weapons/swwm_baseweapon.zsc b/zscript/weapons/swwm_baseweapon.zsc index d5bdc9390..1e76ee9c9 100644 --- a/zscript/weapons/swwm_baseweapon.zsc +++ b/zscript/weapons/swwm_baseweapon.zsc @@ -201,9 +201,30 @@ Class SWWMWeapon : Weapon abstract int dropme = AmmoGive1-ammogiven; if ( dropme > 0 ) { - // hacky, but it works - ownedWeapon.Ammo1.CreateTossable(dropme); - ownedWeapon.Ammo1.Amount += dropme; + if ( (ownedWeapon.Ammo1 is 'SWWMAmmo') && SWWMAmmo(ownedWeapon.Ammo1).MagAmmoType ) + { + // can we add it as mag ammo? + MagAmmo ma = MagAmmo(Owner.FindInventory(SWWMAmmo(ownedWeapon.Ammo1).MagAmmoType)); + if ( !ma ) + { + ma = MagAmmo(Spawn(SWWMAmmo(ownedWeapon.Ammo1).MagAmmoType)); + ma.Amount = 0; + ma.AttachToOwner(Owner); + } + while ( ma.Amount <= (ma.MaxAmount-ma.ClipSize) ) + { + ma.Amount += ma.ClipSize; + dropme--; + } + } + if ( dropme > 0 ) + { + // hacky, but it works + let a = Ammo(Spawn(AmmoType1,Owner.pos)); + a.Owner = Owner; + a.Amount = dropme; + a.CreateTossable(dropme); + } } } if ( ownedWeapon.Ammo2 ) @@ -218,9 +239,30 @@ Class SWWMWeapon : Weapon abstract int dropme = AmmoGive2-ammogiven; if ( dropme > 0 ) { - // hacky, but it works - ownedWeapon.Ammo2.CreateTossable(dropme); - ownedWeapon.Ammo2.Amount += dropme; + if ( (ownedWeapon.Ammo2 is 'SWWMAmmo') && SWWMAmmo(ownedWeapon.Ammo2).MagAmmoType ) + { + // can we add it as mag ammo? + MagAmmo ma = MagAmmo(Owner.FindInventory(SWWMAmmo(ownedWeapon.Ammo2).MagAmmoType)); + if ( !ma ) + { + ma = MagAmmo(Spawn(SWWMAmmo(ownedWeapon.Ammo2).MagAmmoType)); + ma.Amount = 0; + ma.AttachToOwner(Owner); + } + while ( ma.Amount <= (ma.MaxAmount-ma.ClipSize) ) + { + ma.Amount += ma.ClipSize; + dropme--; + } + } + if ( dropme > 0 ) + { + // hacky, but it works + let a = Ammo(Spawn(AmmoType2,Owner.pos)); + a.Owner = Owner; + a.Amount = dropme; + a.CreateTossable(dropme); + } } } return gotstuff; @@ -276,6 +318,7 @@ Class SWWMWeapon : Weapon abstract } override void OwnerDied() { + ClearBufferedAmmo(); if ( Owner.player && (Owner.player.ReadyWeapon == self) ) { Owner.A_StopSound(CHAN_WEAPONEXTRA); @@ -285,6 +328,16 @@ Class SWWMWeapon : Weapon abstract A_ClearRefire(); Super.OwnerDied(); } + override void Travelled() + { + ClearBufferedAmmo(); + Super.Travelled(); + } + override void DetachFromOwner() + { + ClearBufferedAmmo(); + Super.DetachFromOwner(); + } override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack ) { if ( mod == 'Melee' ) return StringTable.Localize("$O_MELEE"); diff --git a/zscript/weapons/swwm_baseweapon_ammobuffer.zsc b/zscript/weapons/swwm_baseweapon_ammobuffer.zsc index 6fb77ff97..20b36c200 100644 --- a/zscript/weapons/swwm_baseweapon_ammobuffer.zsc +++ b/zscript/weapons/swwm_baseweapon_ammobuffer.zsc @@ -10,44 +10,45 @@ extend Class SWWMWeapon { Array BufferedAmmo; - protected AmmoBuffer BufferAmmo( Class type, int amount ) + protected void BufferAmmo( Class type, int amount ) { AmmoBuffer b; for ( int i=0; i type, int amount ) + protected void BufferMagAmmo( Class type, int amount ) { AmmoBuffer b; for ( int i=0; i type, int amount ) + protected int FetchBufferedAmmo( Class type, int amount, bool fullfetch = false ) { for ( int i=0; i type, int amount ) + protected int FetchBufferedMagAmmo( Class type, int amount, bool fullfetch = false ) { for ( int i=0; i= amo.MaxAmount) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) - amo.CreateTossable(1); - amo.Amount++; + invoker.BufferAmmo(types[which],1); + else amo.Amount++; } } invoker.loaded[invoker.rotation[5]*5+i] = null; @@ -687,7 +687,7 @@ Class Wallbuster : SWWMWeapon Class toload = invoker.reloadqueue[invoker.reloadqueue.Size()-1]; invoker.reloadqueue.Pop(); invoker.loaded[invoker.rotation[5]*5+invoker.rotation[invoker.rotation[5]]] = toload; - if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) + if ( !invoker.FetchBufferedAmmo(toload,1) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) { let am = FindInventory(toload); if ( am && (am.Amount > 0) ) am.Amount--; @@ -1163,7 +1163,7 @@ Class Wallbuster : SWWMWeapon XZWE T 0; Stop; EndReload: - XZW4 W 1; + XZW4 W 1 { invoker.ClearBufferedAmmo(); } XZW8 OPQRS 1; XZW8 T 1 A_StartSound("wallbuster/lock",CHAN_WEAPON,CHANF_OVERLAP); XZW8 UVWXY 1; diff --git a/zscript/weapons/swwm_shot.zsc b/zscript/weapons/swwm_shot.zsc index 09135ca28..abaf9759a 100644 --- a/zscript/weapons/swwm_shot.zsc +++ b/zscript/weapons/swwm_shot.zsc @@ -250,8 +250,8 @@ Class Spreadgun : SWWMWeapon amo.Amount = 0; } if ( (amo.Amount >= amo.MaxAmount) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) - amo.CreateTossable(1); - amo.Amount++; + invoker.BufferAmmo(types[i],1); + else amo.Amount++; break; } } @@ -590,7 +590,7 @@ Class Spreadgun : SWWMWeapon action void A_LoadShell() { A_StartSound("spreadgun/shellin",CHAN_WEAPON,CHANF_OVERLAP); - if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) + if ( !invoker.FetchBufferedAmmo(invoker.nextammo,1) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) { let amo = FindInventory(invoker.nextammo); if ( amo && (amo.Amount > 0) ) amo.Amount--; @@ -598,14 +598,13 @@ Class Spreadgun : SWWMWeapon invoker.chambered = true; invoker.fired = false; invoker.loadammo = invoker.nextammo; + invoker.ClearBufferedAmmo(); } action void A_Prime() { if ( invoker.fired || invoker.wasfired ) - { A_StartSound("spreadgun/hammer",CHAN_WEAPON,CHANF_OVERLAP); - } } override bool PickupForAmmoSWWM( SWWMWeapon ownedWeapon ) diff --git a/zscript/weapons/swwm_sparkyboi.zsc b/zscript/weapons/swwm_sparkyboi.zsc index 5f30bfeb9..730854c58 100644 --- a/zscript/weapons/swwm_sparkyboi.zsc +++ b/zscript/weapons/swwm_sparkyboi.zsc @@ -143,6 +143,7 @@ Class Sparkster : SWWMWeapon override void Travelled() { + Super.Travelled(); if ( Owner.player && (Owner.player.Readyweapon == self) ) { Owner.A_StartSound("biospark/idle",CHAN_WEAPONEXTRA,CHANF_LOOP,doublestacc?.6:.4,4.); diff --git a/zscript/weapons/swwm_tastytreat.zsc b/zscript/weapons/swwm_tastytreat.zsc index afd63ab3c..f945222f6 100644 --- a/zscript/weapons/swwm_tastytreat.zsc +++ b/zscript/weapons/swwm_tastytreat.zsc @@ -60,9 +60,30 @@ Class CandyGun : SWWMWeapon int dropme = AmmoGive1-ammogiven; if ( dropme > 0 ) { - // hacky, but it works - ownedWeapon.Ammo1.Amount += dropme; - ownedWeapon.Ammo1.CreateTossable(dropme); + if ( (ownedWeapon.Ammo1 is 'SWWMAmmo') && SWWMAmmo(ownedWeapon.Ammo1).MagAmmoType ) + { + // can we add it as mag ammo? + MagAmmo ma = MagAmmo(Owner.FindInventory(SWWMAmmo(ownedWeapon.Ammo1).MagAmmoType)); + if ( !ma ) + { + ma = MagAmmo(Spawn(SWWMAmmo(ownedWeapon.Ammo1).MagAmmoType)); + ma.Amount = 0; + ma.AttachToOwner(Owner); + } + while ( ma.Amount <= (ma.MaxAmount-ma.ClipSize) ) + { + ma.Amount += ma.ClipSize; + dropme--; + } + } + if ( dropme > 0 ) + { + // hacky, but it works + let a = Ammo(Spawn(AmmoType1,Owner.pos)); + a.Owner = Owner; + a.Amount = dropme; + a.CreateTossable(dropme); + } } } if ( (AmmoGive1 == 0) && ((clipcount > 0) || chambered) ) @@ -76,6 +97,12 @@ Class CandyGun : SWWMWeapon ma.Amount = 0; ma.AttachToOwner(Owner); } + // can we add a full mag? + if ( (bul >= ma.clipsize) && (ma.pamo.Amount < ma.pamo.MaxAmount) ) + { + bul -= ma.clipsize; + ma.pamo.Amount++; + } int maxgiveamt = min(ma.MaxAmount-ma.Amount,bul); int dropamt = bul-maxgiveamt; if ( dropamt > 0 ) ma.CreateTossable(dropamt); @@ -247,15 +274,9 @@ Class CandyGun : SWWMWeapon } int maxgiveamt = min(ma.MaxAmount-ma.Amount,invoker.clipcount); int dropamt = invoker.clipcount-maxgiveamt; - if ( dropamt > 0 ) ma.CreateTossable(dropamt); + if ( dropamt > 0 ) invoker.BufferMagAmmo("CandyGunBullets",dropamt); ma.Amount = min(ma.MaxAmount,ma.Amount+invoker.clipcount); ma.MagFill(); - if ( CheckLocalView() ) for ( int i=0; i 0 ) ma.PlayPickupSound(self); invoker.clipcount = 0; } @@ -269,12 +290,17 @@ Class CandyGun : SWWMWeapon int takeamt = min(sb.Amount,sb.ClipSize); invoker.clipcount = takeamt; sb.Amount -= takeamt; + int req = invoker.default.ClipCount-invoker.clipcount; + if ( req > 0 ) invoker.clipcount += invoker.FetchBufferedMagAmmo("CandyGunBullets",req); } + else if ( invoker.FetchBufferedMagAmmo("CandyGunBullets",sb.ClipSize,true) ) + invoker.clipcount = invoker.default.clipcount; else { invoker.Ammo1.Amount = max(0,invoker.Ammo1.Amount-1); invoker.clipcount = invoker.default.clipcount; } + invoker.ClearBufferedAmmo(); } action void A_DropCasing() diff --git a/zscript/weapons/swwm_thiccboolet.zsc b/zscript/weapons/swwm_thiccboolet.zsc index 96bad7600..296f72b0f 100644 --- a/zscript/weapons/swwm_thiccboolet.zsc +++ b/zscript/weapons/swwm_thiccboolet.zsc @@ -728,45 +728,19 @@ Class SilverBullet : SWWMWeapon } action void A_DropMag() { - if ( invoker.clipcount >= invoker.default.clipcount ) + Class mac = invoker.fcbloaded?"SilverBullets2":"SilverBullets"; + MagAmmo ma = MagAmmo(FindInventory(mac)); + if ( !ma ) { - if ( invoker.fcbloaded ) - { - if ( (invoker.Ammo2.Amount >= invoker.Ammo2.MaxAmount) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) - invoker.Ammo2.CreateTossable(1); - invoker.Ammo2.Amount++; - } - else - { - if ( (invoker.Ammo1.Amount >= invoker.Ammo1.MaxAmount) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) - invoker.Ammo1.CreateTossable(1); - invoker.Ammo1.Amount++; - } - invoker.ClipCount = 0; - return; // no mag dropped - } - else - { - Class mac = invoker.fcbloaded?"SilverBullets2":"SilverBullets"; - MagAmmo ma = MagAmmo(FindInventory(mac)); - if ( !ma ) - { - ma = MagAmmo(Spawn(mac)); - ma.Amount = 0; - ma.AttachToOwner(self); - } - int maxgiveamt = min(ma.MaxAmount-ma.Amount,invoker.clipcount); - int dropamt = invoker.clipcount-maxgiveamt; - if ( dropamt > 0 ) ma.CreateTossable(dropamt); - ma.Amount = min(ma.MaxAmount,ma.Amount+invoker.clipcount); - ma.MagFill(); - if ( CheckLocalView() ) for ( int i=0; i 0 ) ma.PlayPickupSound(self); + ma = MagAmmo(Spawn(mac)); + ma.Amount = 0; + ma.AttachToOwner(self); } + int maxgiveamt = min(ma.MaxAmount-ma.Amount,invoker.clipcount); + int dropamt = invoker.clipcount-maxgiveamt; + if ( dropamt > 0 ) invoker.BufferMagAmmo(mac,dropamt); + ma.Amount = min(ma.MaxAmount,ma.Amount+invoker.clipcount); + ma.MagFill(); invoker.ClipCount = 0; if ( swwm_nomagdrop ) return; Vector3 x, y, z; @@ -834,13 +808,18 @@ Class SilverBullet : SWWMWeapon int takeamt = min(sb.Amount,sb.ClipSize); invoker.clipcount = takeamt; sb.Amount -= takeamt; + int req = invoker.default.ClipCount-invoker.clipcount; + if ( req > 0 ) invoker.clipcount += invoker.FetchBufferedMagAmmo("SilverBullets",req); } + else if ( invoker.FetchBufferedMagAmmo("SilverBullets",sb.ClipSize,true) ) + invoker.clipcount = invoker.default.clipcount; else { invoker.Ammo1.Amount = max(0,invoker.Ammo1.Amount-1); invoker.clipcount = invoker.default.clipcount; } invoker.wastecycle = 0; + invoker.ClearBufferedAmmo(); } action void A_LoadMagAlt() { @@ -852,13 +831,18 @@ Class SilverBullet : SWWMWeapon int takeamt = min(sb.Amount,sb.ClipSize); invoker.clipcount = takeamt; sb.Amount -= takeamt; + int req = invoker.default.ClipCount-invoker.clipcount; + if ( req > 0 ) invoker.clipcount += invoker.FetchBufferedMagAmmo("SilverBullets2",req); } + else if ( invoker.FetchBufferedMagAmmo("SilverBullets2",sb.ClipSize,true) ) + invoker.clipcount = invoker.default.clipcount; else { invoker.Ammo2.Amount = max(0,invoker.Ammo2.Amount-1); invoker.clipcount = invoker.default.clipcount; } invoker.wastecycle = 0; + invoker.ClearBufferedAmmo(); } override bool PickupForAmmoSWWM( SWWMWeapon ownedWeapon )