[ZScript] Special Ammo (SOLVED!)

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
User avatar
DeadHeartProductions
Posts: 36
Joined: Sun Apr 09, 2023 10:49 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Intel (Modern GZDoom)
Location: Eastern North Southlandia, West Side. Formerly NeoTerraNova

[ZScript] Special Ammo (SOLVED!)

Post by DeadHeartProductions »

Greetings, everyone. Thanks to everyone that takes the time to read this and offer their help.

I'm.. hitting kind of a wall, here. I have things set up so that "one weapon" (actually all separate ACTORS) can use multiple types of ammo. When I originally got help for an issue involving ammo, this wasn't the case. And now.. it's been so long, I can't remember how to alter this code chunk to do what I need.

What I need to do, here, is add to or alter the "Check" ability of this code chunk to detect things in the player's Inventory.

Right now, it's set up to detect if a Weapon is in their inventory that can use the AmmoType listed. I need it to, instead or in addition to this, check if the player is holding one of several Weapons that would ALL potentially use that ammo.

As it stands, I have two actual, different Shotguns coded, and each Shotgun has a "clone" that uses a different ammo type (one uses Slugs, one uses Shot Shells), for a total of four Actors, and eventually, many more (I have 4 shotguns planned for the project, and a third type of ammo).

I need this code chunk to allow the Player to pick up ammo only when they have one of these guns, and (as you can see in the Code), deposit a residual item if not all of the ammunition in the Pickup can fit in the Player's Inventory.

And I don't know ZScript well enough to figure out how to do that. I've been messing with different ideas for a week, and.. yeah, nothing.

Here's the code chunk as it stands:

Code: Select all


class LooseSGSHOTBase : Inventory
{
    Default
    {
        Inventory.Amount 1;
        Inventory.PickupSound "pickup/ammogeneral";
        Inventory.PickupMessage "12 Gauge #00 Shot";
        Scale 0.3;
    }

    States
    {
        Spawn:
            SMSH B -1 Bright;
            Stop;
    }

    // These are the ammo types we'll be scanning for
    static const class<Ammo> AmmoTypes[] = { 'Shot00BK' };

    override bool TryPickup(in out Actor toucher)
    {
        bool success = false;

        // Try to give ammo of each type, as long as we have anything to give at all
        for (int i = 0; i < AmmoTypes.Size() && Amount > 0; i++)
        {
            let at = AmmoTypes[i];
       
            // Check if we have any weapons that use this ammo type
            for (let ii = toucher.Inv; ii != null; ii = ii.Inv)
            {
                let weap = Weapon(ii);
               
                if (weap == null)
                {
                    // Not a weapon
                    continue;
                }

                Ammo aa;

                if (weap.Ammo1 is at)
                {
                    // Correct ammo1
                    aa = weap.Ammo1;
                }
                else if (weap.Ammo2 is at)
                {
                    // Correct ammo2
                    aa = weap.Ammo2;
                } 
                else
                {
                    // Wrong ammo types
                    continue;
                }

                // Correct ammo. See how much we can give
                int toGive = Min(aa.MaxAmount - aa.Amount, Amount);
               
                aa.Amount += toGive;
                Amount -= toGive;
               
                // Pickup will succeed if at least 1 ammo has been given
                success = success || toGive > 0;
            }
        }

        if (success)
        {
            // If there's still some ammo left, create a residual pickup
            if (Amount > 0 && (bDropped || !ShouldRespawn()))
            {
                let newItem = Inventory(Actor.Spawn("LooseSGSHOTBase", Pos));

                if (newItem != null)
                {
                    newItem.Vel = Vel;
                    newItem.Angle = Angle;
                    newItem.Pitch = Pitch;
                    newItem.Roll = Roll;
                    newItem.FloatBobPhase = FloatBobPhase;
                    newItem.Amount = Amount;
                    newItem.bIgnoreSkill = true;
                    newItem.bDropped = bDropped;
                }
            }

            // OK, register pickup
            GoAwayAndDie();
        }
        else
        {
            toucher.A_Print("I can't carry any more #00 shotgun shells");
        }

        return success;
    }
}


And here's an example of one of its "children" that has a set amount of ammo.

Code: Select all

class LooseSGSHOTBox7 : LooseSGSHOTBase
{
    Default
    {
        Inventory.Amount 7;
        Inventory.PickupMessage "Box of 12 Gauge #00 Shot";
    }
    States
    {
        Spawn:
            SGAA A -1 Bright;
            Stop;
    }
}

Again, my thanks for anyone that stops by and has a look, and helps.
Last edited by DeadHeartProductions on Fri Sep 27, 2024 4:07 pm, edited 1 time in total.
Blue Shadow
Posts: 5019
Joined: Sun Nov 14, 2010 12:59 am

Re: [ZScript] Special Ammo

Post by Blue Shadow »

So you want to change the code to check against a list of weapons instead of a list of ammo types (like it's doing right now)?
User avatar
DeadHeartProductions
Posts: 36
Joined: Sun Apr 09, 2023 10:49 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Intel (Modern GZDoom)
Location: Eastern North Southlandia, West Side. Formerly NeoTerraNova

Re: [ZScript] Special Ammo

Post by DeadHeartProductions »

Yes. While maintaining the functionality of determining the "aa.Amount += toGive" to make sure it only gives the Player as much ammo as the player can still carry, and no more. Since the Player should only be able to pick up this ammo if they have a compatible weapon, I couldn't figure out how to change the search for Ammo in the section including "AmmoTypes.Size () && Amount" to look for the Weapons instead, while still making sure that the specific ammo type (in this case, "Shot00BK") is the ammo type granted on pickup.

Thank you very much for your help!
Blue Shadow
Posts: 5019
Joined: Sun Nov 14, 2010 12:59 am

Re: [ZScript] Special Ammo

Post by Blue Shadow »

Would this work for you?

Code: Select all

class LooseSGSHOTBase : Inventory
{
	Default
	{
		Inventory.Amount 1;
		Inventory.PickupSound "pickup/ammogeneral";
		Inventory.PickupMessage "12 Gauge #00 Shot";
		Scale 0.3;
	}

	States
	{
	Spawn:
		SMSH B -1 Bright;
		Stop;
	}

	// These are the weapons we'll be scanning for
	static const class<Weapon> aWeapons[] = { 'Weapon#1', 'Weapon#2', 'Weapon#3' }; // <--- Weapons go here...

	override bool TryPickup(in out Actor toucher)
	{
		bool success = false;

		for (int i = 0; i < aWeapons.Size() && Amount > 0; i++)
		{
			let weap = Weapon(toucher.FindInventory(aWeapons[i]));

			if (weap != null)
			{
				Ammo aa;
				int toGive = 0;

				if (weap.Ammo1 is 'Shot00BK')
				{
					aa = weap.Ammo1;
				}
				else if (weap.Ammo2 is 'Shot00BK')
				{
					aa = weap.Ammo2;
				}

				// Correct ammo. See how much we can give
				if (aa != null)
				{
					toGive = Min(aa.MaxAmount - aa.Amount, Amount);

					aa.Amount += toGive;
					Amount -= toGive;
				}

				// Pickup will succeed if at least 1 ammo has been given
				success = success || toGive > 0;
			}
		}

		if (success)
		{
			// If there's still some ammo left, create a residual pickup
			if (Amount > 0 && (bDropped || !ShouldRespawn()))
			{
				let newItem = Inventory(Actor.Spawn("LooseSGSHOTBase", Pos));

				if (newItem != null)
				{
					newItem.Vel = Vel;
					newItem.Angle = Angle;
					newItem.Pitch = Pitch;
					newItem.Roll = Roll;
					newItem.FloatBobPhase = FloatBobPhase;
					newItem.Amount = Amount;
					newItem.bIgnoreSkill = true;
					newItem.bDropped = bDropped;
				}
			}

			// OK, register pickup
			GoAwayAndDie();
		}
		else
		{
			toucher.A_Print("I can't carry any more #00 shotgun shells");
		}

		return success;
	}
}
User avatar
DeadHeartProductions
Posts: 36
Joined: Sun Apr 09, 2023 10:49 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Intel (Modern GZDoom)
Location: Eastern North Southlandia, West Side. Formerly NeoTerraNova

Re: [ZScript] Special Ammo

Post by DeadHeartProductions »

This line:

Code: Select all

	static const class<Weapon> aWeapons[] = { 'SGType100', 'SGType1SL', 'SGType2SL', 'SGType200' }; // <--- Weapons go here...
It causes a crash, (I think) since my Weapons are not defined as conventional "Weapons" but a custom class called "GWeaponDM." Changing this to "Inventory" or even class<GweaponDM> does not pass muster and also crashes.

Thank you so much for your help so far!
Blue Shadow
Posts: 5019
Joined: Sun Nov 14, 2010 12:59 am

Re: [ZScript] Special Ammo

Post by Blue Shadow »

Could you post the code of one of these weapons?
User avatar
DeadHeartProductions
Posts: 36
Joined: Sun Apr 09, 2023 10:49 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Intel (Modern GZDoom)
Location: Eastern North Southlandia, West Side. Formerly NeoTerraNova

Re: [ZScript] Special Ammo

Post by DeadHeartProductions »

This is the base code for the class "GWeaponDM"

Code: Select all

class GWeaponDM : Weapon //DM - Detachable Magazine

    {
	action void DropReserveAmmo (class<Inventory> AmmoReserve, class<Inventory> ReserveToDrop)  
 // Call this function when you want to drop all ammo, the parameter is the type of ammo to drop. 
 // Not sure you define the types exactly this way, but if an error pops-up it should point you the right way
	   {
			int AmmoHeld = CountInv(ReserveToDrop);
			int AmmoSpare = CountInv(AmmoReserve); //This is for the ammo in the gun, and on DM weapons, is currently unused.
			
			TakeInventory(ReserveToDrop, AmmoHeld); // Take RMs from the inventory
			while (AmmoHeld > 0) // Dont spawn a Mag if you dont have ammo anyway
			{
				//A_Log(TEXTCOLOR_RED .. AmmoHeld); //Not needed, retained for reference.
				Ammo DroppedAmmo = Ammo(Spawn(ReserveToDrop, Pos, NO_REPLACE)); // Spawn the new Mag
				DroppedAmmo.Amount = 1; 
				DroppedAmmo.DropTime = 30;
				DroppedAmmo.Angle = 12;
				DroppedAmmo.VelFromAngle(5);
				DroppedAmmo.Vel.Z = 2.;
				DroppedAmmo.bNoGravity = false;
				DroppedAmmo.bSpecial = DroppedAmmo.bSolid = false;
				DroppedAmmo.ClearCounters();
				AmmoHeld = AmmoHeld - 1;
			}
            TakeInventory(ReserveToDrop, AmmoSpare); 
		}
	
    
	 
	action void DropCurrentAmmo (class<Inventory> AmmoInGun, class<Inventory> AmmoToDrop) 
    // Call this function when you want to drop all ammo, the parameter is the type of ammo to drop. Not sure you define the types exactly this way, but if an error pops-up it should point you the right way
	{
		{
			int AmmoHeld2 = CountInv(AmmoToDrop);
			int AmmoSpare2 = CountInv(AmmoInGun); //This is for the ammo in the gun, and on DM weapons, is currently unused.
			
			TakeInventory(AmmoToDrop, AmmoHeld2); // Take AM from the inventory
			while (AmmoHeld2 > 0) // Dont spawn a Mag if you dont have ammo anyway
			{
				//A_Log(TEXTCOLOR_RED .. AmmoHeld); //Not needed, retained for reference.
				Ammo DroppedAmmo = Ammo(Spawn(AmmoToDrop, Pos, NO_REPLACE)); // Spawn the new Mag
				DroppedAmmo.Amount = 1; 
				DroppedAmmo.DropTime = 20;
				DroppedAmmo.Angle = 24;
				DroppedAmmo.VelFromAngle(7);
				DroppedAmmo.Vel.Z = 6;
				DroppedAmmo.bNoGravity = false;
				DroppedAmmo.bSpecial = DroppedAmmo.bSolid = false;
				DroppedAmmo.ClearCounters();
				AmmoHeld2 = AmmoHeld2 - 1;
			}	
				TakeInventory(AmmoInGun, AmmoSpare2); // Take ammo from the weapon
		}

	}
}

These are the relevant code bits for two of the weapons:

Code: Select all

Actor SGType100 : GWeaponDM
{
	Weapon.AmmoType		"SGtype1Tube00"
	Weapon.AmmoGive		0
	Weapon.AmmoUse		0
	Weapon.AmmoType2	"Shot00BK"
	Weapon.AmmoGive2	0
	Weapon.AmmoUse2		0
	Inventory.PickupMessage "Combat Shotgun [Shot] - 12ga 3'' (4)"
    Tag "Combat SG"
	Inventory.Icon "I_SGType1"
	+AMMO_OPTIONAL
	+NOAUTOFIRE

Code: Select all

Actor SGType1SL : GWeaponDM
{
	Weapon.AmmoType		"SGtype1TubeSL"
	Weapon.AmmoGive		0
	Weapon.AmmoUse		0
	Weapon.AmmoType2	"ShotSLUG"
	Weapon.AmmoGive2	0
	Weapon.AmmoUse2		0
	Inventory.PickupMessage "Combat Shotgun [Slug] - 12ga 3'' (4)"
    Tag "Combat SG"
	Inventory.Icon "I_SGType1"
	+AMMO_OPTIONAL
	+NOAUTOFIRE
Everything else about the weapons is conventional, save the "DROP" state (Identical in both, save the difference between "SLUG" and "SHOT")

Code: Select all

	User1:
		TNT1 A 0 A_GiveInventory("FakeWeaponCap",2)
		TNT1 A 0 A_TakeInventory("WeaponCap", 2)
		TNT1 A 0 A_JumpIf(CountInv("SGtype1TubeSL")==0,"SDrop")
		TNT1 A 1 DropReserveAmmo("ShotSLUG","ShotSLUG")
		TNT1 A 1 DropCurrentAmmo("SGtype1TubeSL","SGtype1TubeSL")
	    TNT1 A 0 A_TakeInventory("FM_Shot",1)
		TNT1 A 0 A_TakeInventory("SGtype1SL", 1)
		  TNT1 A 0
		  Goto Ready
	SDrop:
		TNT1 A 1 DropReserveAmmo("ShotSLUG","ShotSLUG")
		TNT1 A 0 A_SpawnItem("SGType1Empty", 1)
	    TNT1 A 0 A_TakeInventory("FM_Shot",1)
		TNT1 A 0 A_TakeInventory("SGtype1SL", 1)
		TNT1 A 0
		  Goto Ready
Blue Shadow
Posts: 5019
Joined: Sun Nov 14, 2010 12:59 am

Re: [ZScript] Special Ammo

Post by Blue Shadow »

Okay. Change these two lines...

Code: Select all

static const class<Weapon> aWeapons[] = { ... }; // <--- Weapons go here...
let weap = Weapon(toucher.FindInventory(aWeapons[i]));
to

Code: Select all

static const class<GWeaponDM> aWeapons[] = { ... }; // <--- Weapons go here...
let weap = GWeaponDM(toucher.FindInventory(aWeapons[i]));
If you still get errors, please post them.
User avatar
DeadHeartProductions
Posts: 36
Joined: Sun Apr 09, 2023 10:49 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Intel (Modern GZDoom)
Location: Eastern North Southlandia, West Side. Formerly NeoTerraNova

Re: [ZScript] Special Ammo

Post by DeadHeartProductions »

Still getting the error "Unknown Class Name" on boot. Specifically:

Script error, "Project_PreA_0.3.5.2.pk3:zscript/bullet.zs" line 303:
Unknown class name 'SGType1SL' of type 'GWeaponDM'
Script error, "Project_PreA_0.3.5.2.pk3:zscript/bullet.zs" line 303:
Unknown class name 'SGType100' of type 'GWeaponDM'

(I'm only testing it with "SGType1" right now)

I appreciate all of this! Believe me!
Blue Shadow
Posts: 5019
Joined: Sun Nov 14, 2010 12:59 am

Re: [ZScript] Special Ammo

Post by Blue Shadow »

I think I know the problem. Your weapons are made in DECORATE while the ammo pickup we're trying to modify is made in ZScript. ZScript is parsed by the engine before DECORATE. That's why you're getting those errors.

Based on that, here's the new version of the code. Hopefully, it'll work:

Code: Select all

class LooseSGSHOTBase : Inventory
{
	Default
	{
		Inventory.Amount 1;
		Inventory.PickupSound "pickup/ammogeneral";
		Inventory.PickupMessage "12 Gauge #00 Shot";
		Scale 0.3;
	}

	States
	{
	Spawn:
		SMSH B -1 Bright;
		Stop;
	}

	// These are the weapons we'll be scanning for
	static const Name aWeapons[] = { 'SGType100', 'SGType1SL', 'SGType2SL', 'SGType200' };

	override bool TryPickup(in out Actor toucher)
	{
		bool success = false;
		Name ammoName = 'Shot00BK';
		class<Ammo> ammocls = ammoName; 

		for (int i = 0; i < aWeapons.Size() && Amount > 0; i++)
		{
			let weap = Weapon(toucher.FindInventory(aWeapons[i]));

			if (weap != null)
			{
				Ammo aa;
				int toGive = 0;

				if (weap.Ammo1 is ammocls)
				{
					aa = weap.Ammo1;
				}
				else if (weap.Ammo2 is ammocls)
				{
					aa = weap.Ammo2;
				}

				// Correct ammo. See how much we can give
				if (aa != null)
				{
					toGive = Min(aa.MaxAmount - aa.Amount, Amount);

					aa.Amount += toGive;
					Amount -= toGive;
				}

				// Pickup will succeed if at least 1 ammo has been given
				success = success || toGive > 0;
			}
		}

		if (success)
		{
			// If there's still some ammo left, create a residual pickup
			if (Amount > 0 && (bDropped || !ShouldRespawn()))
			{
				let newItem = Inventory(Actor.Spawn("LooseSGSHOTBase", Pos));

				if (newItem != null)
				{
					newItem.Vel = Vel;
					newItem.Angle = Angle;
					newItem.Pitch = Pitch;
					newItem.Roll = Roll;
					newItem.FloatBobPhase = FloatBobPhase;
					newItem.Amount = Amount;
					newItem.bIgnoreSkill = true;
					newItem.bDropped = bDropped;
				}
			}

			// OK, register pickup
			GoAwayAndDie();
		}
		else
		{
			toucher.A_Print("I can't carry any more #00 shotgun shells");
		}

		return success;
	}
}
DeadHeartProductions wrote: Fri Sep 20, 2024 7:47 am I appreciate all of this! Believe me!
No worries. :)
User avatar
DeadHeartProductions
Posts: 36
Joined: Sun Apr 09, 2023 10:49 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Intel (Modern GZDoom)
Location: Eastern North Southlandia, West Side. Formerly NeoTerraNova

Re: [ZScript] Special Ammo

Post by DeadHeartProductions »

This works, BUT.. if I have slug shells equipped (SGType1SL/SGtype2SL), it won't let me pick up shotshells. And I don't know how to convert, say, this code bit:

Code: Select all

				else if (weap.Ammo2 is ammocls)
				{
					aa = weap.Ammo2;
				}
To something like:

Code: Select all

				else if (weap.Ammo1 is (Some Identifier for Slug Shells))
				{
					aa = Shot00BK; (I know this straight up won't work like this, but, somehow change the "aa" pointer or whatever, to read/give Shot shells, if the Slug Shells are currently loaded in the weapon/Weapon.AmmoType1 reads "ShotSLUG") 
				}
Blue Shadow
Posts: 5019
Joined: Sun Nov 14, 2010 12:59 am

Re: [ZScript] Special Ammo

Post by Blue Shadow »

Would this work? It only checks for and adds to AmmoType2 regardless of what it is, be it shot or slug shells.

Code: Select all

class LooseSGSHOTBase : Inventory
{
	Default
	{
		Inventory.Amount 1;
		Inventory.PickupSound "pickup/ammogeneral";
		Inventory.PickupMessage "12 Gauge #00 Shot";
		Scale 0.3;
	}

	States
	{
	Spawn:
		SMSH B -1 Bright;
		Stop;
	}

	// These are the weapons we'll be scanning for
	static const Name aWeapons[] = { 'SGType100', 'SGType1SL', 'SGType2SL', 'SGType200' };

	override bool TryPickup(in out Actor toucher)
	{
		bool success = false;

		for (int i = 0; i < aWeapons.Size() && Amount > 0; i++)
		{
			let weap = Weapon(toucher.FindInventory(aWeapons[i]));

			if (weap != null && weap.Ammo2 != null)
			{
				int toGive = Min(weap.Ammo2.MaxAmount - weap.Ammo2.Amount, Amount);
				weap.Ammo2.Amount += toGive;
				Amount -= toGive;

				// Pickup will succeed if at least 1 ammo has been given
				success = success || toGive > 0;
			}
		}

		if (success)
		{
			// If there's still some ammo left, create a residual pickup
			if (Amount > 0 && (bDropped || !ShouldRespawn()))
			{
				let newItem = Inventory(Actor.Spawn("LooseSGSHOTBase", Pos));

				if (newItem != null)
				{
					newItem.Vel = Vel;
					newItem.Angle = Angle;
					newItem.Pitch = Pitch;
					newItem.Roll = Roll;
					newItem.FloatBobPhase = FloatBobPhase;
					newItem.Amount = Amount;
					newItem.bIgnoreSkill = true;
					newItem.bDropped = bDropped;
				}
			}

			// OK, register pickup
			GoAwayAndDie();
		}
		else
		{
			toucher.A_Print("I can't carry any more #00 shotgun shells");
		}

		return success;
	}
}
User avatar
DeadHeartProductions
Posts: 36
Joined: Sun Apr 09, 2023 10:49 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Intel (Modern GZDoom)
Location: Eastern North Southlandia, West Side. Formerly NeoTerraNova

Re: [ZScript] Special Ammo

Post by DeadHeartProductions »

The code does function as written.

However, now, when I pick up Shot shells, it gives me Slug shells when "SGType1SL" is in inventory/equipped.

Is there some way to simply ignore checking ammo type at all? And grant ONLY the "Shot00BK" ONLY IF one of the weapons is in inventory?

The Player will only have one weapon at a time (they swap out what ammo is currently loaded with a button press, but this is just code trickery to take away one weapon actor, and give them another - for example, removing SGType100 and giving them SGType1SL - graphically, they're the same weapon, but one fires 00 Buck Shot, and the other fires Slugs), and each uses a completely different ammo pool (Shot00BK and ShotSLUG).

Thank you again for all your help so far.
User avatar
DeadHeartProductions
Posts: 36
Joined: Sun Apr 09, 2023 10:49 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 7
Graphics Processor: Intel (Modern GZDoom)
Location: Eastern North Southlandia, West Side. Formerly NeoTerraNova

Re: [ZScript] Special Ammo

Post by DeadHeartProductions »

I was thinking about what I'd said in my response, and managed to work out something that works as intended, using some of the code you showed me before.

Code: Select all

class LooseSGSHOTBase : Inventory
{
	Default
	{
		Inventory.Amount 1;
		Inventory.PickupSound "pickup/ammogeneral";
		Inventory.PickupMessage "12 Gauge #00 Shot";
		Scale 0.3;
	}

	States
	{
	Spawn:
		SMSH B -1 Bright;
		Stop;
	}

	// These are the weapons we'll be scanning for
	static const Name aWeapons[] = { 'M101400', 'M1014SL'};

	override bool TryPickup(in out Actor toucher)
	{
		bool success = false;
		Name ammoName = 'Shot00BK';
		class<Ammo> ammocls = ammoName;

		for (int i = 0; i < aWeapons.Size() && Amount > 0; i++)
		{
			let weap = Weapon(toucher.FindInventory(aWeapons[i]));
			let amo = toucher.FindInventory(ammocls);

			if (weap != null)
			{
				int toGive = Min(amo.MaxAmount - amo.Amount, Amount);
				amo.Amount += toGive;
				Amount -= toGive;

				// Pickup will succeed if at least 1 ammo has been given
				success = success || toGive > 0;
			}
		}

		if (success)
		{
			// If there's still some ammo left, create a residual pickup
			if (Amount > 0 && (bDropped || !ShouldRespawn()))
			{
				let newItem = Inventory(Actor.Spawn("LooseSGSHOTBase", Pos));

				if (newItem != null)
				{
					newItem.Vel = Vel;
					newItem.Angle = Angle;
					newItem.Pitch = Pitch;
					newItem.Roll = Roll;
					newItem.FloatBobPhase = FloatBobPhase;
					newItem.Amount = Amount;
					newItem.bIgnoreSkill = true;
					newItem.bDropped = bDropped;
				}
			}

			// OK, register pickup
			GoAwayAndDie();
		}
		else
		{
			toucher.A_Print("I can't carry any more #00 shotgun shells");
		}

		return success;
	}
}

With this:
-You only pick up SHOT00BK if you have a shotgun, any shotgun will do
-You only pick up as much SHOT00BK as you can carry
-It doesn't matter which actual Shotgun ACTOR is in inventory, it will only grant Shot00BK (or, if changed, ShotSLUG)


THANK YOU, Blue Shadow! You've been an immense help!

I can confirm after extensive testing that it works just fine with my situation, but there IS a pitfall: If you use this code, make ABSOLUTELY SURE you give the Player both SHOT00BK and SHOTSLUG (or whatever you rename it to), as a 0-capacity marker in their Inventory somehow. Otherwise, if you don't, the game crashes when trying to pick up the Ammo Type you don't have an inventory marker for.

Again, my thanks to BlueShadow.
Last edited by DeadHeartProductions on Fri Sep 27, 2024 4:07 pm, edited 1 time in total.
Blue Shadow
Posts: 5019
Joined: Sun Nov 14, 2010 12:59 am

Re: [ZScript] Special Ammo

Post by Blue Shadow »

You're welcome.

Return to “Scripting”