why my weapon has unlimited ammo?

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!)
LuzRoja29ZD
Posts: 6
Joined: Sat Nov 19, 2022 8:27 am
Preferred Pronouns: Ask Me
Operating System Version (Optional): Windows 11

why my weapon has unlimited ammo?

Post by LuzRoja29ZD »

I made a weapon that when used generates a stimpack in front of the player, and this weapon can't pick up ammo, but it has limited ammo. The problem is that when using it, it doesn't spend the ammunition. why?
decorate of the weapon
Spoiler:
decorate of the liimited ammo
Spoiler:
Jarewill
Posts: 1422
Joined: Sun Jul 21, 2019 8:54 am

Re: why my weapon has unlimited ammo?

Post by Jarewill »

A_SpawnItemEx is not an attack function so it doesn't take ammo by default.
You will also need to use A_TakeInventory to manually take away ammo on use.
Example:

Code: Select all

TNT1 A 0
{
	A_SpawnItemEx("Stimpack",40,0,0);
	A_TakeInventory("AStimpack",1);
}
User avatar
wildweasel
Moderator Team Lead
Posts: 21584
Joined: Tue Jul 15, 2003 7:33 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Win10 22H2, Win11 22H2, macOS 11.7
Graphics Processor: nVidia with Vulkan support

Re: why my weapon has unlimited ammo?

Post by wildweasel »

The reason it does not use ammo is that you are not feeding it any action functions that check or use ammo themselves. A_SpawnItemEx does not have any flag or function to use ammo when called.

What you will need to do instead is run your own ammo check logic in your Fire state.

Code: Select all

Fire:
   PISG A 0 A_JumpIfNoAmmo("Dryfire") // Check the ammo -first-, before we allow the player to fire.
   PISG A 0 A_SpawnItemEx("ThatStuff",40,0,0) // Spawn your item.
   PISG A 0 A_TakeInventory("TheAmmoType", 1, TIF_NOTAKEINFINITE) // Take away 1 unit of ammo. The flag is here to ensure that it respects the sv_infiniteammo cvar.
   PISG ABCDEDCB 2 // Now the animation happens.
   PISG A 0 A_CheckReload //This built-in function checks if the player has ammo left and switches to the next weapon if they don't.
   Goto Ready
Dryfire: //This is where A_JumpIfNoAmmo is going to end up.
   PISG AEAEAE 3 // A different animation happens.
   PISG A 0 A_CheckReload //Might as well check one last time.
   Goto Ready
Nihlith
Posts: 5
Joined: Thu Jan 12, 2023 3:32 pm

Re: why my weapon has unlimited ammo?

Post by Nihlith »

wildweasel wrote: Sun Nov 27, 2022 3:48 pm The reason it does not use ammo is that you are not feeding it any action functions that check or use ammo themselves. A_SpawnItemEx does not have any flag or function to use ammo when called.

What you will need to do instead is run your own ammo check logic in your Fire state.

Code: Select all

Fire:
   PISG A 0 A_JumpIfNoAmmo("Dryfire") // Check the ammo -first-, before we allow the player to fire.
   PISG A 0 A_SpawnItemEx("ThatStuff",40,0,0) // Spawn your item.
   PISG A 0 A_TakeInventory("TheAmmoType", 1, TIF_NOTAKEINFINITE) // Take away 1 unit of ammo. The flag is here to ensure that it respects the sv_infiniteammo cvar.
   PISG ABCDEDCB 2 // Now the animation happens.
   PISG A 0 A_CheckReload //This built-in function checks if the player has ammo left and switches to the next weapon if they don't.
   Goto Ready
Dryfire: //This is where A_JumpIfNoAmmo is going to end up.
   PISG AEAEAE 3 // A different animation happens.
   PISG A 0 A_CheckReload //Might as well check one last time.
   Goto Ready
I had a similar problem to @LuzRoja29ZD except I was building a tri wielding setup for a three armed Player Character I call the RAVAGER. I wanted to let the player use a weapon in two hands while throwing grenades and casting spells with the other. I used elements of code I saw in @ctlcdn 's mismatched pistols to get the simultaneous actions going with the three parts of the weapon, but I couldn't get an animation to play when I used Inventory items. I used the A_TakeInventory("TheAmmoType", 1, TIF_NOTAKEINFINITE) and A_CheckReload functions, but couldn't get the weapon functioning correctly. I couldn't get the weapon to enter new states when inventory items were used, and so no animation was forthcoming. I don't understand why that is.

Thanks for the pointers though, I did end up getting somewhere neat and I'd appreciate any clarification you or any others want to provide. If I could get inventory items to work in tandem with the weapon's animations and displayed item counts I'd really be cooking with gas.

Here is the code for the dual chain gun grenade weapon

Code: Select all

ACTOR DoubleChainGuns : Weapon 
{
  Weapon.SelectionOrder 750
  Weapon.AmmoGive 20
  Weapon.AmmoType "bottle" //This is so the Flechettes display on screen with the ammo. I couldn't get an animation to play when using inventory items like dark servents or bombs.
  Weapon.AmmoUse 0 //This is so using the primary and alt fire doesn't use Flechettes
  Weapon.AmmoType2 "Clip" //This is so bullets show up on screen with the ammo. Both ammo types need to be present or the weapon will run out of ammo but won't stop firing when pressed.
  Inventory.PickupMessage "You Got Twin Chainguns! (2)"
  Weapon.Slotnumber 4
  Tag "Double Chainguns"

  States
  {
  
  Spawn:
    DUCH E -1
    Stop
  
  Ready:
    TNT1 A 1 A_WeaponReady(WRF_NOFIRE) 
	Loop

  Select:
    TNT1 A 0 {
		A_PlaySound("Weapon/WhooshSFX", 6, 1);
		A_PlaySound("Weapon/AKPRaise",  5, 1);
		A_ZoomFactor(1);
		A_Light0;
	}
	TNT1 A 1  A_Raise
	TNT1 AAAAAAAAAAAAAA 0 A_Raise
	Goto RaiseAnim
  RaiseAnim:
	DUCH DCBA 3
	TNT1 A 0 {A_Overlay(3, "IdleR"); A_Overlay(-3, "IdleL"); A_Overlay(-6, "Toss");} //here are the overlays that allow 
																		//each gun and the grenade throwing arm to act independently
    Goto Ready

  Deselect:
    TNT1 A 0 {
		A_Overlay(3, ""); A_Overlay(-3, "");
		A_PlaySound("Weapon/WhooshSFX", 6, 1);	
		A_ZoomFactor(1);
		A_Light0;
	}
	DUCH ABCD 2
	Goto LowerAnim
  LowerAnim:
	TNT1 AAAAAAAAAAAA 0 A_Lower
	TNT1 A 1 A_Lower
	Loop
	
  Fire:
    Goto Ready //not sure why this is here.
	
// - - - - - - - - Left Chaingun STATES - - - - - - - -

  IdleL:
    LCHG A 1 A_JumpIf(GetPlayerInput(INPUT_BUTTONS) & BT_ALTATTACK, "FireL") //left chaingun, searches for input to initiate sequence
	Loop
	
  FireL:
	LCHG A 1 A_JumpIfInventory("Clip",1,"FireLL") //FireL is to make the weapon not fire unless its loaded
	Goto IdleL
	
	FireLL:
     LCHG B 0 {
	 A_AlertMonsters; //the weapon didn't alert monsters originally
	 A_PlaySound("weapons/dblchngun", CHAN_WEAPON);
     A_GunFlash("Flash2");
	 }
     LCHG B 4 A_FireBullets(5.6, 0, 1, 5, "BulletPuff")
	 RCHG B 0 A_TakeInventory("Clip", 1, TIF_NOTAKEINFINITE) //here the weapon spends ammo even though this is neither fire nor altfire
     LCHG B 0 {
	 A_AlertMonsters;
	 A_PlaySound("weapons/dblchngun", CHAN_WEAPON);
     A_GunFlash("Flash2");
	 }
     LCHG C 4 A_FireBullets(5.6, 0, 1, 5, "BulletPuff")
	 LCHG C 0 A_TakeInventory("Clip", 1, TIF_NOTAKEINFINITE) //didn't use A_Refire, that function always gets me into trouble 
     Goto IdleL

// - - - - - - - - Right Chaingun States - - - - - - - - //Second Verse same as the first

  IdleR:
	// Note: Swap BT_ATTACK with BT_ALTATTACK to swap handing.
	RCHG A 1 A_JumpIf(GetPlayerInput(INPUT_BUTTONS) & BT_ATTACK, "FireR")
	Loop
	
  FireR:
	RCHG A 0 A_JumpIfNoAmmo("FireRF")
    RCHG A 1 A_JumpIfInventory("Clip",1,"FireRR")
	Goto IdleR
  
  FireRR:
     RCHG B 0 {
	 A_AlertMonsters;
	 A_PlaySound("weapons/dblchngun", CHAN_WEAPON);
     A_GunFlash("Flash2");
	 }
	 RCHG B 4 A_FireBullets(5.6, 0, 1, 5, "BulletPuff")
	 RCHG B 0 A_TakeInventory("Clip", 1, TIF_NOTAKEINFINITE)
     RCHG B 0 {
	 A_AlertMonsters;
	 A_PlaySound("weapons/dblchngun", CHAN_WEAPON);
     A_GunFlash("Flash2");
	 }
     RCHG C 4 A_FireBullets(5.6, 0, 1, 5, "BulletPuff")
	 RCHG C 0 A_TakeInventory("Clip", 1, TIF_NOTAKEINFINITE)
    Goto IdleR
	
	FireRF:
	RCHG B 4
	RCHG C 4
	Goto IdleR
	
	//- - - - - - - - - - Third Arm States - - - - - - - My grenade tossing arm
 Third:
	TNT1 A 0 A_JumpIf(GetPlayerInput(INPUT_BUTTONS) & BT_USER1, "Toss") //makes the grenade button do stuff
	
	TNT1 A 1 //stops zdoom from locking when the grenade button is pressed
	Loop
 
 Toss:	
	TNT1 A 1 A_JumpIfInventory("bottle",1,"TossA") //stops the player from using bombs if their out of bombs
	Goto Third
	
	TossA:
	TNT1 A 1 A_JumpIf(GetPlayerInput(INPUT_BUTTONS) & BT_USER1, "TossC") //For some reason I needed this step to get the ammo consumption to work
	Loop
   
   TossC:	
   TOSS A 0 A_ThrowGrenade("PoisonBomb",-20,20,8, bool ("bottle")) // "Spawn your item." I got the form of this function from wild weasel. It works.
   TOSS A 0 A_TakeInventory("bottle", 1, TIF_NOTAKEINFINITE) // "Take away 1 unit of ammo. The flag is here to ensure that it respects the sv_infiniteammo cvar." wild weasel again
   TOSS ABCDCBA 2 // "Now the animation happens." and again. I couldn't get the animation to happen until I defined the Flechette or "bottle" as an ammo type. Not sure why that is.
   Goto Toss
   
	}
}
and here is a video of the weapon in action. The sounds are from ctlcdn's mismatched pistols from Realm 667, which is from valve.

[youtube]https://youtu.be/Mw6W1jxhRR4[/youtube]

Anyway, thanks again. If nothing else maybe it'll give someone else some ideas. Peace.

Return to “Scripting”