[HELP] Weapon Select/Deselect issue.

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!)
Post Reply
User avatar
Dan_The_Noob
Posts: 880
Joined: Tue May 07, 2019 12:24 pm
Graphics Processor: nVidia with Vulkan support
Contact:

[HELP] Weapon Select/Deselect issue.

Post by Dan_The_Noob »

Hey guys,

So my Autoshotgun and Launcher Chaingun don't seem to deselect properly when out of ammo?
I don't think i can set minimum ammo as the shotgun has a magazine as an alternate ammo type and the chaingun is both chaingun and rocket launcher. (2 ammo types)

AutoShotgun

Code: Select all

actor AutoShotgun : Weapon
{
+AMMO_OPTIONAL
+ALT_AMMO_OPTIONAL
  spawnid 237
  obituary "%o got blasted away by %k's Auto-shotgun."
  radius 20
  height 16
  Inventory.Pickupmessage "You got the Automatic shotgun!"
  weapon.slotnumber 3
  weapon.selectionorder 700
  Weapon.AmmoType1 "Shell"
  Weapon.AmmoType2 "ASGClip"
  Weapon.AmmoGive1 10
  Weapon.AmmoGive2 0
  Weapon.AmmoUse 1
  //AttackSound "weapons/asgfir"
  Damagetype "Normal"
  states
  {
  Spawn:
    WASG A -1
    stop
  Ready:
    ASGG A 1 A_WeaponReady(WRF_ALLOWRELOAD)
    loop
  Deselect:
    ASGG A 0 A_Lower
    ASGG A 1 A_Lower
    loop
  Select:
    ASGG A 0 A_Raise
    ASGG A 1 A_Raise
    loop
  Fire:
    ASGG A 0 A_JumpIfInventory("ASGClip",1,3) //if "has ammo" jump to shoot
	ASGG A 0 A_JumpIfInventory("Shell",1,"Reload") //if "has shells" jump to reload
	ASGG A 0 A_PlayWeaponSound("Weapons/asgout")//if "out of ammo" click and reset
	goto Ready
    Goto Reload
    ASGG A 1
	ASGG A 0 A_TakeInventory("ASGClip",1,TIF_NOTAKEINFINITE)
    ASGG L 1 Offset(0,37) A_FireBullets(4,3,9,7,"BulletPuff",0)
	ASGG L 0 A_PlaySound("weapons/asgfir",4,1,false,0.3)
	ASGG L 0 A_GunFlash
	ASGG L 1 Offset(0,34)
	ASGG L 1 Offset(0,32)
    ASGG M 2
    ASGG N 2
    ASGG A 3 A_PlaySoundEX("weapons/asgld1","auto",0)
    ASGG A 7
    ASGG A 0 A_ReFire
	ASGG A 2
    goto Ready
  AltFire:
  Burst:
	ASGG A 0 A_JumpIfInventory("ASGClip",1,4) //if "has ammo"
	ASGG A 0 A_ResetReloadCounter //reset "Burst counter" (start new burst)
	ASGG A 0 A_JumpIfInventory("Shell",1,"Reload") //if "has shells"
	ASGG A 0 A_PlayWeaponSound("Weapons/asgout")
	goto Ready
	ASGG A 1
	ASGG A 0 A_TakeInventory("ASGClip",1,TIF_NOTAKEINFINITE)
	ASGG L 1 Offset(0,37) A_FireBullets(6,5,8,7,"BulletPuff",0)
	ASGG L 0 A_PlaySound("weapons/asgfir",4,1,false,0.3)
	ASGG L 0 A_GunFlash
	ASGG L 1 Offset(0,34)
	ASGG L 1 Offset(0,32)
	ASGG M 2
	ASGG A 0 A_CheckForReload(3,"Burst") //counts 3-shot burst
	ASGG N 3
	ASGG A 3
	ASGG A 0 A_ResetReloadCounter
    Goto Ready
  Reload:
	ASGG G 0 A_JumpIfInventory("ASGClip",0,2)
	ASGG G 0 A_JumpIfInventory("Shell",1,3)
	ASGG G 0 A_PlayWeaponSound("Weapons/asgout")
	Goto Ready
    ASGG BCDEF 3
    ASGG G 3 A_PlayWeaponSound("Weapons/asgout")
    ASGG HIJ 2
    ASGG k 12
    ASGG JIH 3
  Reload2:
	ASGG G 0 A_TakeInventory("Shell",1)
    ASGG G 0 A_GiveInventory("ASGClip",1)
    ASGG G 0 A_JumpIfInventory("ASGClip",0,2)//if "full magazine"
    ASGG G 0 A_JumpIfInventory("Shell",1,"Reload2")//if "has shells"
    ASGG G 2 A_PlayWeaponSound("Weapons/asgin")
    ASGG FEDCB 4
    ASGG A 8 A_PlaySound("weapons/asgld1")
    goto Ready
  Flash:
    NULL A 4 bright A_Light1
	NULL A 3 bright A_Light2
	NULL A 0 bright A_Light0
    stop
  }
}

ACTOR ASGClip: Ammo
{
     Inventory.MaxAmount 30
     Ammo.BackpackAmount 0
     Ammo.BackpackMaxAmount 30
}

LauncherChaingun

Code: Select all

ACTOR LChaingun : Weapon
{ 
SpawnID 172
Inventory.PickupMessage "You got the Launcher Chaingun!" 
Weapon.SlotNumber 5
Weapon.SelectionOrder 120 
Weapon.AmmoType2 "RocketAmmo"
Weapon.AmmoType1 "Clip"
Weapon.AmmoGive2 5
Weapon.AmmoGive1 50
Weapon.AmmoUse2 1   
Weapon.AmmoUse1 1 
Weapon.Kickback 25   
//AttackSound "weapons/LChaingunFire"

+WEAPON.ALT_AMMO_OPTIONAL
+WEAPON.AMMO_OPTIONAL

States 
 { 
 Spawn: 
 LMCG A -1
 Stop 
   
 Ready:
 LMCG B 1 A_WeaponReady
 Loop  
   
 Deselect:
 LMCG B 1 A_Lower
 Loop 
   
 Select:
 LMCG B 1 A_Raise
 Loop
	  
 Fire:   
 NULL A 0 A_JumpIfNoAmmo("REmpity")
 LMCG C 1 A_PlayWeaponSound("weapons/LChaingunStart")
 LMCG BC 1
 NULL A 0 A_Refire
 Goto WindDown
     
 Hold:
 NULL A 0 A_JumpIfNoAmmo("WindDown")
 NULL A 0 A_FireCustomMissile("ShotSmokeSpawner",0,0,0+Random(-5,5),0+Random(-5,5),0)   
 LMCG D 2 bright A_FireBullets(3,3,3,5,"LOSPuff",1)
 LMCG D 0 A_PlaySound("weapons/LChaingunFire",4,1,false,0.3)
 LMCG D 0 A_GunFlash
 NULL A 0 A_Recoil(0.2)
 NULL A 0 A_FireCustomMissile("Capsulas1",0,0,15,-10)
 LMCG E 3
 NULL A 0 A_JumpIfNoAmmo("WindDown")
 LMCG D 2 bright A_FireBullets(3,3,3,5,"LOSPuff",1)
  LMCG D 0 A_PlaySound("weapons/LChaingunFire",4,1,false,0.3)
  LMCG D 0 A_GunFlash
 NULL A 0 A_Recoil(0.1)
  NULL A 0 A_FireCustomMissile("Capsulas1",0,0,15,-10)
 LMCG E 3 bright
 NULL A 0 A_Refire
 Goto WindDown
 
 WindDown:
 LMCG BCBC 4 A_PlayWeaponSound("weapons/LChaingunStop")
 LMCG BCB 2 A_JumpIfNoAmmo("REmpity")
 NULL A 0 A_ClearRefire
 Goto Ready

 AltFire:
 NULL A 0 A_JumpIfNoAmmo("REmpity")
 NULL A 0 A_Recoil(2)
 NULL A 0 A_FireCustomMissile("BackSmoke",0,0,9,-5,0)
 NULL A 0 A_PlaySound("weapons/LChaingunAltFire",0,1)      
 LMCG O 12 A_FireCustomMissile("LRocket",0,1,8,-5,0)
 LMCG P 12
 LMCG B 4 A_Refire
 Goto Ready
 
 Flash:
    NULL A 2 bright A_Light1
	NULL A 1 bright A_Light(3)
	NULL A 0 bright A_Light0
    stop

 REmpity:
 LMCG B 12 A_PlayWeaponSound("weapons/sshoto") 
 NULL A 0 A_ClearRefire
 Goto Ready
 } 
}

ACTOR LRocket
{
Obituary "%o rode %k's LRocket."
Radius 3
Height 3
Speed 50
explosionDamage 200
explosionRadius 192
Scale 0.3

PROJECTILE
+RANDOMIZE

States
 {
 Spawn:
 RCK2 A 1 Bright A_SpawnItem("LRocket-Trail")
 Loop
   
 Death:
 NULL A 1 A_PlaySound("Weapons/Lexplosion",4,1,false,0.1)
 NULL A 1 A_Explode
 NULL A 0 A_SpawnItem("LRocket-Flash")
 NULL A 1 A_SpawnItem("LRocket-Explosion")
 NULL A 1 A_SpawnItem("LRocket-Explosion-Smoke")   
 Stop
 }
}

ACTOR LRocket-Trail
{
Radius 1
Height 1
Scale 0.2
RenderStyle Add
Alpha 0.4

PROJECTILE
+NOGRAVITY
+NOBLOCKMAP 
+RANDOMIZE
+FORCEXYBILLBOARD

States
 {
 Spawn:
 SMOK ABCDEFGHI 1
 SMOK JKLMNOPQ 1 A_FadeOut
 Goto Death

 Death:
 NULL A 1
 Stop
 }
}

ACTOR BackSmoke
{
Radius 1
Height 1
Speed 1
Damage 0
Scale 0.3

PROJECTILE
+CLIENTSIDEONLY
+FORCEXYBILLBOARD

States
 {
 Spawn:
 NULL AAAAAAAA 1 A_SpawnItem("LRocket-Trail")
 Goto Death

 Death:
 NULL A 1
 Stop
 }
}

ACTOR LRocket-Flash
{
Radius 1
Height 1
RenderStyle Add
Alpha 0.3

+CLIENTSIDEONLY
+NOGRAVITY
+FORCEXYBILLBOARD

States
 {
 Spawn:
 NULL A 1 A_SetScale(1,1)
 NULL A 0 A_Jump(125,"DeathB")
 Goto DeathA
 
 DeathA:
 BOOM A 1 Bright A_SetScale(0.5,0.5)
 BOOM A 1 Bright A_SetScale(1,1)
 BOOM A 1 Bright A_SetScale(1.5,1.5)
 BOOM A 1 Bright A_FadeOut
 Stop
 
 DeathB:
 BOOM B 1 Bright A_SetScale(0.5,0.5)
 BOOM B 1 Bright A_SetScale(1,1)
 BOOM B 1 Bright A_SetScale(1.5,1.5)
 BOOM B 1 Bright A_FadeOut
 Stop
 }
}

ACTOR LRocket-Explosion
{
Radius 1
Height 1
RenderStyle Add
Alpha 0.9

+CLIENTSIDEONLY
+NOGRAVITY
+FORCEXYBILLBOARD

States
 {
 Spawn:
 HGRN G 1 A_SetScale(0.5,0.5)
 HGRN H 1 A_SetScale(1.2,1.2)
 HGRN IJKL 4 A_SetScale(1.5,1.5)
 HGRN MN 2 A_SetScale(1.2,1.2)
 HGRN OP 3 A_SetScale(0.7,0.7)
 HGRN QR 4 A_FadeOut
 Goto Death
  
 Death:
 NULL A 1
 Stop
 }
}  

ACTOR LRocket-Explosion-Smoke
{
Radius 1
Height 1
RenderStyle Add
Alpha 0.1
Scale 2.3

+CLIENTSIDEONLY
+NOGRAVITY
+FORCEXYBILLBOARD

States
 {
 Spawn:
 BLOW A 1 A_SetScale(0.5,0.5)
 BLOW B 1 A_SetScale(0.6,0.6)
 BLOW C 1 A_SetScale(0.7,0.7)
 BLOW D 1 A_SetScale(0.8,0.8)
 BLOW E 1 A_SetScale(0.9,0.9)
 BLOW F 1 A_SetScale(1.0,1.0)
 BLOW G 1 A_SetScale(1.1,1.1)
 BLOW H 1 A_SetScale(1.3,1.3)
 BLOW I 1 A_SetScale(1.5,1.5)
 BLOW J 1 A_SetScale(1.7,1.7)
 BLOW K 1 A_SetScale(1.9,1.9)
 BLOW L 1 A_SetScale(2.2,2.2)
 BLOW M 1 A_SetScale(2.5,2.5)
 BLOW N 1 A_SetScale(2.8,2.8)
 BLOW O 1 A_FadeOut  
 Goto Death
 
 Death:
 NULL A 1
 Stop
 }
}

ACTOR Capsulas1
{
Radius 1
Height 1
Speed 25

PROJECTILE
+CLIENTSIDEONLY
+DONTSPLASH	
-ACTIVATEIMPACT 

States
 {
 Spawn:
   NULL A 1
   NULL A 0 A_Die
   Goto Death

 Death:
   NULL A 0 A_CustomMissile("Capsulas2",2,-10,270+random(-15,15),2,45+random(-15,15))
   Stop
 }
}

ACTOR Capsulas2
{
Height 1.5
Radius 2
Speed 8
Scale .25
SeeSound "weapons/LChaingunCapsulas" 

PROJECTILE
+CLIENTSIDEONLY
+DOOMBOUNCE
+DONTSPLASH   
- NOGRAVITY
- NOBLOCKMAP
-ACTIVATEIMPACT

States
 {
 Spawn:
   NULL A 0 A_PlaySound("NULL")
   LCPJ ACBED 1 A_CustomMissile("CapsulasSmonke",0,0,0,2,0)
   Goto Spawn + 1
	  
 Death:
   NULL A 0 A_Jump(50,4)
   NULL A 0 A_Jump(75,10)
   NULL A 0 A_Jump(100,16)
   NULL A 0 A_Jump(125,22)
   LCPJ A 1 A_CustomMissile("CapsulasSmonke",0,0,0,2,0)
   LCPJ A 350
   LCPJ AAAAA 1 A_FadeOut
   Stop
   LCPJ B 1 A_CustomMissile("CapsulasSmonke",0,0,0,2,0)
   LCPJ B 350
   LCPJ BBBBB 1 A_FadeOut
   Stop
   LCPJ C 1 A_CustomMissile("CapsulasSmonke",0,0,0,2,0)
   LCPJ C 350
   LCPJ CCCCC 1 A_FadeOut
   Stop
   LCPJ C 1 A_CustomMissile("CapsulasSmonke",0,0,0,2,0)
   LCPJ D 350
   LCPJ DDDDD 1 A_FadeOut
   Stop
 }
}

ACTOR CapsulasSmonke
{
Radius 1
Height 1
Scale 0.125
Speed 1
RenderStyle Add
ALPHA 0.05

PROJECTILE
+CLIENTSIDEONLY
+DONTSPLASH   
+NOCLIP
-ACTIVATEIMPACT   

States
 {
 Spawn:
   SMKE ABCDEFG 1   
   Stop

 Death:
   SMKE H 1
   Stop
 }
}
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: [HELP] Weapon Select/Deselect issue.

Post by Player701 »

Well, obviously, your weapons do not deselect when out of ammo due to these flags:

Code: Select all

+AMMO_OPTIONAL
+ALT_AMMO_OPTIONAL
However, removing them will prevent your weapons from working properly, because it will cause them to get deselected at inappropriate moments (due to A_ReFire and the player's firing functions performing the corresponding ammo checks). Attempting to counter this behavior by setting AmmoUse to 0 will take you back to square one (no deselection when out of ammo).

I guess you could work around this to a certain extent with some gross DECORATE hacks. However, it seems that there is no way to solve this entirely. This issue seems to plague many DECORATE-based weapon reloading systems. It is possible to use ZScript to avoid it, but depending on what exactly you intend to achieve, the resulting code can be quite complex. Therefore, I'm afraid I can't give a complete solution here, but I can give you some pointers on where to look:
  • Weapon::CheckAmmo is called to (potentially) deselect the current weapon if there is not enough ammo. The AMMO_OPTIONAL/ALT_AMMO_OPTIONAL flags bypass these checks. Note that this function is also called when trying to select the weapon - and if it returns false, this means the weapon is out of ammo and cannot be used at the moment.
  • PlayerPawn::FireWeapon and PlayerPawn::FireWeaponAlt are called when attempting to fire the weapon by pressing either the primary or the alternate fire buttons. These functions call the current weapon's CheckAmmo function as part of their logic, which can lead to the attack being aborted if there is not enough ammo available (and the automatic deselection will then take place).
  • StateProvider::A_ReFire also triggers a call to CheckAmmo if the player is no longer holding the fire button. Naturally, this will also trigger automatic deselection when there is no more ammo avaiable.
You have to understand how exactly these functions work and how they depend on each other - then you will be able to implement your own logic by overriding some of them. If you think this is way too complicated (which is, in fact, quite true), I suggest you don't bother at all and leave everything as-is.
User avatar
Dan_The_Noob
Posts: 880
Joined: Tue May 07, 2019 12:24 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: [HELP] Weapon Select/Deselect issue.

Post by Dan_The_Noob »

unfortunately i have the limitation of Zandronum compatibility to deal with.

I may be able to do an ammo check in the ready state i guess that jumps to deselect? but i don't know how much lag/delay that could cause.
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: [HELP] Weapon Select/Deselect issue.

Post by Player701 »

Sorry, I don't use Zandronum, so no idea about lag. But do note that calling A_JumpIfNoAmmo outside of a fire state will check for primary ammo only. You cannot use A_JumpIfInventory to replace A_JumpIfNoAmmo, because if you jump to the Deselect state explicitly, it will not result in your weapon being deselected (instead, it will simply jump back to its Ready state). In addition, you need to consider some other factors, e.g. infinite ammo.
User avatar
Dan_The_Noob
Posts: 880
Joined: Tue May 07, 2019 12:24 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: [HELP] Weapon Select/Deselect issue.

Post by Dan_The_Noob »

maybe for consistency, i could just make no weapons switch ():)
User avatar
LossForWords
Posts: 700
Joined: Fri Jan 13, 2017 9:08 pm

Re: [HELP] Weapon Select/Deselect issue.

Post by LossForWords »

Replace ammo_optional with Ammo_CheckBoth, then put an Ammo.Use on both.

Make it so that the attack has the FBF_USEAMMO set to 0, and track how much ammo it uses by using A_JumpIfInventory and A_TakeInventory.
Post Reply

Return to “Scripting”