Need help: Pistol crashes game upon equipping silencer

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
Retraux Squid
Posts: 230
Joined: Sat Aug 13, 2016 8:41 pm
Location: E1M1

Need help: Pistol crashes game upon equipping silencer

Post by Retraux Squid »

Code: Select all

ACTOR UACWeaponsPistol : Pistol replaces Pistol
{
  Weapon.SelectionOrder 1900
  Weapon.AmmoUse 1
  Weapon.AmmoGive 15
  Weapon.AmmoType "Clip"
  Obituary "%o was shot by %k's pistol."
  +WEAPON.WIMPY_WEAPON
  +WEAPON.NOALERT
  Inventory.Pickupmessage "Picked up another pistol."
  Tag "Pistol"
  Attacksound ""
  States
  {
  Ready:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "ReadySilent")
	goto Ready2
  Ready2:  
	PKPI A 1 A_WeaponReady
    Loop
  ReadySilent:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 0, "Ready")
	goto ReadySilent2
  ReadySilent2:
    SPIL A 1 A_WeaponReady
	Loop
  SelectSilent:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 0, "Select")
    SPIL A 1 A_Raise
	SPIL A 0 A_Raise
	Loop
  DeselectSilent:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 0, "Deselect")
    SPIL A 1 A_Lower
	SPIL A 0 A_Lower
	Loop
  Deselect:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "DeselectSilent")
    PKPI A 1 A_Lower
	PKPI A 0 A_Lower
    Loop
  Select:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 0, "SelectSilent")
    PKPI A 1 A_Raise
	PKPI A 0 A_Raise
    Loop
  Fire:
	PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "FireSilent")
    PKPI A 0 A_AlertMonsters
	PKPI A 0 A_GunFlash
	PKPI A 0 A_PlaySound("weapons/pistol", CHAN_WEAPON)
	PKPI B 2 bright A_FireBullets(2.5,2.5,1,5,"BulletPuff")
    PKPI C 1
    PKPI D 2
	PKPI E 2
	PKPI F 1
	PKPI G 1
	PKPI A 5
    PKPI A 5 A_ReFire
    Goto Ready
  FireSilent:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 0, "Fire")
	PKPI A 0 A_PlaySound("weapons/silencer", CHAN_WEAPON)
	SPIL B 2 bright A_FireBullets(2,2,1,3,"BulletPuff")
    SPIL C 1
    SPIL D 2
	SPIL E 2
	SPIL F 1
	SPIL G 1
	SPIL A 5
    SPIL A 5 A_ReFire
    Goto Ready
  AltFire:
	PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 0, "PutOnSilencer")
	PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "RemoveSilencer")
  PutOnSilencer:
    PKPI A 0 A_PlaySound("weapons/shotgr", CHAN_WEAPON)
	PREP ABCD 2
	PREP EFGH 2
	PKPI A 0 A_GiveInventory("PistolSilencedDummy", 1)
	SPIL A 1
	goto Ready
  RemoveSilencer:
    PKPI A 0 A_PlaySound("weapons/shotgr", CHAN_WEAPON)
	PREP HGFE 2
	PREP DCBA 2
	PKPI A 0 A_TakeInventory("PistolSilencedDummy", 1)
	PKPI A 1
	goto Ready
  Flash:
    PKPF A 2 Bright A_Light1
    Goto LightDone
  Spawn:
    SPIP A -1
    Stop
  }
}

ACTOR PistolSilencedDummy : Inventory
{
	+IGNORESKILL
	Inventory.MaxAmount 1
}
This handgun is meant to be able to swap between a silencer or no silencer with right-click, playing a short animation. The primary fire works perfectly, however when I try to equip the silencer the game runs through the animation and then immediately freezes, hangs up for a few seconds, then crashes.

What am I doing wrong here?
User avatar
wildweasel
Posts: 21643
Joined: Tue Jul 15, 2003 7:33 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): A lot of them
Graphics Processor: Not Listed

Re: Need help: Pistol crashes game upon equipping silencer

Post by wildweasel »

The problem stems from how you're checking the absence of a silencer in this block of code:

Code: Select all

ReadySilent:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 0, "Ready")
   goto ReadySilent2
A_JumpIfInventory cannot be used to check for the LACK of something, only for the PRESENCE of it. If you're checking for "0" of an item, A_JumpIfInventory interprets this as checking for the Inventory.MaxAmount of that item instead - meaning ReadySilent is passing its check, going back to Ready, passing THAT check, going back to ReadySilent, and getting itself stuck in an infinite loop.

What I would suggest is doing away with the second check altogether and letting the code fall through. Like this:

Code: Select all

Ready:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "ReadySilent")
   PKPI A 1 A_WeaponReady
    Loop
  ReadySilent:
    SPIL A 1 A_WeaponReady
   Goto Ready
User avatar
Retraux Squid
Posts: 230
Joined: Sat Aug 13, 2016 8:41 pm
Location: E1M1

Re: Need help: Pistol crashes game upon equipping silencer

Post by Retraux Squid »

wildweasel wrote:The problem stems from how you're checking the absence of a silencer in this block of code:

Code: Select all

ReadySilent:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 0, "Ready")
   goto ReadySilent2
A_JumpIfInventory cannot be used to check for the LACK of something, only for the PRESENCE of it. If you're checking for "0" of an item, A_JumpIfInventory interprets this as checking for the Inventory.MaxAmount of that item instead - meaning ReadySilent is passing its check, going back to Ready, passing THAT check, going back to ReadySilent, and getting itself stuck in an infinite loop.

What I would suggest is doing away with the second check altogether and letting the code fall through. Like this:

Code: Select all

Ready:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "ReadySilent")
   PKPI A 1 A_WeaponReady
    Loop
  ReadySilent:
    SPIL A 1 A_WeaponReady
   Goto Ready
Enormous thanks. Just struggling with making weaponry properly work now:

Code: Select all

ACTOR UACWeaponsPistol : Pistol replaces Pistol
{
  Weapon.SelectionOrder 1900
  Weapon.AmmoUse 1
  Weapon.AmmoGive 15
  Weapon.AmmoType "Clip"
  Obituary "%o was shot by %k's pistol."
  +WEAPON.WIMPY_WEAPON
  +WEAPON.NOALERT
  Inventory.Pickupmessage "Picked up another pistol."
  Tag "Pistol"
  Attacksound ""
  States
  {
  Ready:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "ReadySilent")
  ReadyUnsilent:
    PKPI A 1 A_WeaponReady
    Loop
  ReadySilent:
    SPIL A 1 A_WeaponReady
    Loop
  SelectSilent:
    SPIL A 1 A_Raise
    SPIL A 0 A_Raise
    Loop
  DeselectSilent:
    SPIL A 1 A_Lower
    SPIL A 0 A_Lower
    Loop
  Deselect:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "DeselectSilent")
    PKPI A 1 A_Lower
    PKPI A 0 A_Lower
    Loop
  Select:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "SelectSilent")
    PKPI A 1 A_Raise
    PKPI A 0 A_Raise
    Loop
  Fire:
    PKPI A 0 A_JumpIfInventory("PistolSilencedDummy", 1, "FireSilent")
    PKPI A 0 A_AlertMonsters
    PKPI A 0 A_GunFlash
    PKPI A 0 A_PlaySound("weapons/pistol", CHAN_WEAPON)
    PKPI B 2 bright A_FireBullets(2.5,2.5,1,6,"BulletPuff")
    PKPI C 1
    PKPI D 2
    PKPI E 2
    PKPI F 1
    PKPI G 1
    PKPI A 5
    PKPI A 5 A_ReFire
    Goto Ready
  FireSilent:
    PKPI A 0 A_PlaySound("weapons/silencer", CHAN_WEAPON)
    SPIL B 2 bright A_FireBullets(2,2,1,5,"BulletPuff")
    SPIL C 1
    SPIL D 2
    SPIL E 2
    SPIL F 1
    SPIL G 1
    SPIL A 5
    SPIL A 5 A_ReFire
    Goto Ready
  AltFire:
	PKPI A 0
    PKPI A 1 A_JumpIfInventory("PistolSilencedDummy", 1, "RemoveSilencer")
  RemoveSilencer:
    PKPI A 0 A_PlaySound("weapons/shotgr", CHAN_WEAPON)
    PREP HGFEDCBA 2
    PKPI A 1 A_TakeInventory("PistolSilencedDummy", 1)
    PKPI A 1
    goto ReadyUnsilent
  PutOnSilencer:
    PKPI A 0 A_PlaySound("weapons/shotgr", CHAN_WEAPON)
    PREP ABCD 2
    PREP EFGH 2
    SPIL A 1 A_GiveInventory("PistolSilencedDummy", 1)
    SPIL A 1
    goto ReadySilent
  Flash:
    PKPF A 2 Bright A_Light1
    Goto LightDone
  Spawn:
    SPIP A -1
    Stop
  }
}

ACTOR PistolSilencedDummy : Inventory
{
   +IGNORESKILL
   Inventory.MaxAmount 1
}
This at least doesn't crash the game when I try to equip the silencer, but things seem messy and for the life of me I can't figure out exactly why. I think for the rest of my weapons I'll be using simpler alt-fires.
Blue Shadow
Posts: 4935
Joined: Sun Nov 14, 2010 12:59 am
Graphics Processor: ATI/AMD (Modern GZDoom)

Re: Need help: Pistol crashes game upon equipping silencer

Post by Blue Shadow »

From what I see, each time you press altfire, you remove the silencer, whether you had it on or not.

Code: Select all

    AltFire:
        PKPI A 0
        PKPI A 1 A_JumpIfInventory("PistolSilencedDummy", 1, "RemoveSilencer")
        Goto PutOnSilencer // You need this here.
    RemoveSilencer:
        PKPI A 0 A_PlaySound("weapons/shotgr", CHAN_WEAPON)
        PREP HGFEDCBA 2
        PKPI A 1 A_TakeInventory("PistolSilencedDummy", 1)
        PKPI A 1
        goto ReadyUnsilent

Return to “Scripting”