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.

Need help: Pistol crashes game upon equipping silencer

Postby Retraux Squid » Thu Jan 11, 2018 7:04 pm

Code: Select allExpand view
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
Retraux Squid
A_PosAttack
 
Joined: 13 Aug 2016
Location: E1M1

Re: Need help: Pistol crashes game upon equipping silencer

Postby wildweasel » Thu Jan 11, 2018 7:20 pm

The problem stems from how you're checking the absence of a silencer in this block of code:
Code: Select allExpand view
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 allExpand view
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
wildweasel
change o' pace.
Moderator Team Lead
 
Joined: 15 Jul 2003

Re: Need help: Pistol crashes game upon equipping silencer

Postby Retraux Squid » Thu Jan 11, 2018 9:08 pm

wildweasel wrote:The problem stems from how you're checking the absence of a silencer in this block of code:
Code: Select allExpand view
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 allExpand view
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 allExpand view
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.
User avatar
Retraux Squid
A_PosAttack
 
Joined: 13 Aug 2016
Location: E1M1

Re: Need help: Pistol crashes game upon equipping silencer

Postby Blue Shadow » Fri Jan 12, 2018 10:31 am

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

Code: Select allExpand view
    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
User avatar
Blue Shadow
 
Joined: 14 Nov 2010
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD (Modern GZDoom)


Return to Scripting

Who is online

Users browsing this forum: No registered users and 0 guests