[SOLVED] Monster Spawn Not Dying When A_KillMaster is Called

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Locked
That Blind Guy
Posts: 20
Joined: Fri Mar 10, 2017 8:18 am

[SOLVED] Monster Spawn Not Dying When A_KillMaster is Called

Post by That Blind Guy »

The title says it all. Here's how it's supposed to work.

1. The spawner replaces a monster (e.g., the Cyberdemon is replaced by a "CyberDemonSpawner" actor).
2. This spawner selects a random monster from the set given to it using A_Jump and places it in the level.
3. The spawner waits until the monster is killed. At this point, A_KillMaster is called. Ergo, it's the death of the spawner, not the monster itself, that triggers whatever is supposed to happen such as a level ending or wall lowering.

The mod I'm working on has 5 possible bosses for both the Cyberdemon and Spider Mastermind spawn points. Nine of these 10 bosses work, and we know that the spawners themselves are fine. We tried replacing the faulty monster with one we know works elsewhere, and everything fired off as intended, so something is wrong with the monster itself. I'm all but sure of it.

Here is the actor's code.

Code: Select all

actor SZ_AracnorbQueen 30100
{
	//$Category "Monsters/Bosses"
	//$Title "Arachnorb Queen"
  MONSTER
  +NOGRAVITY
  +FLOAT
  +FLOATBOB
  +BOSS
  +NORADIUSDMG
  +DONTMORPH
  +MISSILEMORE
  Health 2500
  WoundHealth 150
  Radius 34
  Height 76
  Mass 2000
  Speed 15
  var int user_ragetimer;
  var int user_autorage;
  PainChance 45
  PainChance "BFGBlast", 256
  PainChance "Thunderbolt", 256
  PainChance "GreenBFGball", 256
  PainChance "Pierce", 0
  PainChance "Dark", 0
  SelfDamageFactor 0
  DamageFactor "EnergyBlast", 2.0
  DamageFActor "BFGBlast", 2.0
  DamageFactor "Pierce", 0.15
  DamageFactor "Dark", 0.15
  SeeSound "queen/sight"
  ActiveSound "queen/active"
  PainSound "queen/pain"
  DeathSound "queen/death"
  MeleeSound "queen/melee"
  MeleeDamage 16
  MissileHeight 36
  Obituary "%o suffered psychic trauma from an aracnorb queen's brainwaves."
  HitObituary "%o had %p skull chewed by an aracnorb queen."
  Scale 0.85
  States
  {
  Spawn:
	ARNQ A 0 A_SetUserVar(user_autorage, 0)
        ARNQ A 1 A_Look
        Loop
  See:
        ARNQ A 2 A_Chase
        Loop
  Melee:
        ARNQ ABC 3 A_FaceTarget
        ARNQ D 6 A_MeleeAttack
        Goto See
  Missile:
        TNT1 A 0 A_JumpIf(user_ragetimer > 0, "RageMissile")
	TNT1 A 0 A_Jump(96, "BFG")
	TNT1 A 0 A_JumpIfCloser(512, "CloseRange")
	Goto LongRange
  CloseRange:
        TNT1 A 0 A_Jump(176, "RapidFire")
	Goto SpreadFire
  LongRange:
        TNT1 A 0 A_Jump(176, "SpreadFire")
	Goto RapidFire
  BFG:
        TNT1 A 0 A_PlaySound("queen/fire")
	ARNQ BCD 8 A_FaceTarget
        ARNQ E 10 Bright A_CustomMissile("QueenBFG",50,-10,0)
	Goto See
  RapidFire:
        ARNQ BCD 8 A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ P 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 0 BRIGHT A_FaceTarget
        ARNQ E 5 BRIGHT A_CustomMissile ("QueenPlasmaBlast", 40, 0, random(-4,4))
        ARNQ D 5 A_FaceTarget
        //ARNQ D 5
	Goto See
  SpreadFire:
        ARNQ BCD 8 A_FaceTarget
	ARNQ A 0 A_PlaySound("weapons/ionalt")
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	ARNQ E 5 Bright A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-4,4))
	ARNQ BCD 8 A_FaceTarget
	ARNQ A 0 A_PlaySound("weapons/ionalt")
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	ARNQ E 5 Bright A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-4,4))
	ARNQ D 5 A_FaceTarget
	Goto See
  RageMissile:
	ARNQ BCD 8 A_FaceTarget
	ARNQ A 0 A_PlaySound("weapons/ionalt")
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	ARNQ E 5 Bright A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-4,4))
	ARNQ BCD 4 A_FaceTarget
	ARNQ A 0 A_PlaySound("weapons/ionalt")
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	ARNQ E 5 Bright A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-4,4))
	ARNQ BCD 4 A_FaceTarget
	ARNQ A 0 A_PlaySound("weapons/ionalt")
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	TNT1 A 0 A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-7,7), CMF_AIMOFFSET|CMF_OFFSETPITCH, random(-3,3))
	ARNQ E 5 Bright A_CustomMissile("QueenPlasmaBlast", 40, 0, random(-4,4))
        TNT1 A 0 A_PlaySound("queen/fire")
	ARNQ BCD 8 A_FaceTarget
        ARNQ E 10 Bright A_CustomMissile("QueenBFG",50,-10,0)
	ARNQ E 0 A_SetUserVar(user_ragetimer, user_ragetimer-1)
	ARNQ E 0 A_JumpIf(user_ragetimer < 1, "EndRage")
  Pain:
	TNT1 A 0 A_Jump(128, "PainSpam")
        ARNQ F 4
	ARNQ F 4 A_Pain
        Goto See
  Pain.StunBomb:
	ARNQ F 0 A_Pain
	ARNQ F 35 A_SpawnItem("StunLight")
	Goto PainSpam
  Pain.BFGBlast:
        ARNQ A 0 A_CustomMissile("BFGEffect", 40)
	ARNQ F 10 A_Pain
	Goto BeginRage
  Death.BFGBlast:
        ARNQ A 0 A_CustomMissile("BFGEffect", 40)
	Goto Death
  Pain.Thunderbolt:
        ARNQ A 0 A_CustomMissile("PBFGEffect", 40)
	ARNQ F 10 A_Pain
	Goto BeginRage
  Death.Thunderbolt:
        ARNQ A 0 A_CustomMissile("PBFGEffect", 40)
	Goto Death
  Wound:
	ARNQ A 1
	ARNQ A 0 A_JumpIf(user_autorage > 0, "See")
	ARNQ A 0 A_SetUserVar(user_autorage, 1)
  Pain.GreenBFGBall:
  BeginRage:
        ARNQ F 0 A_ChangeFlag("INVULNERABLE", true)
        ARNQ F 0 A_SetSpeed(30)
	ARNQ F 0 A_SetUserVar(user_ragetimer, 2)
	ARNQ F 0 A_Quake(7, 70, 0, 2000)
	ARNQ F 0 A_PlaySound("queen/sight")
	ARNQ F 35
	ARNQ A 0 A_CustomMissile("QueenSummon", 50, 0, -45)
	ARNQ A 0 A_CustomMissile("QueenSummon", 50)
	ARNQ A 0 A_CustomMissile("QueenSummon", 50, 0, 45)
	Goto See
  EndRage:
        ARNQ F 0 A_ChangeFlag("INVULNERABLE", false)
       ARNQ A 1 A_SetSpeed(15)
	Goto See
  PainSpam:
        ARNQ F 4
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,5,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,25,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,45,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,65,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,85,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,105,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,125,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,145,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,165,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,185,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,205,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,225,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,245,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,265,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,285,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,305,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,325,32,0)
        ARNQ F 0 A_custommissile("QueenPainPlasmaBlast",75,0,345,32,0)
	ARNQ F 4 A_Pain
	ARNQ F 0 A_Jump(128, "PainSpam")
        Goto See
  Death:
	ARNQ G 0 A_SpawnItem("SZ_LifeSphere")
        ARNQ G 0 A_ChangeFlag("FLOATBOB",0)
        ARNQ G 9 A_Scream
	ARNQ G 3 A_Fall
	ARNQ G 175 
	ARNQ G 0 A_KillMaster
	ARNQ G 1 A_BossDeath
        Wait
  Crash:
        ARNQ HIJKL 9
        ARNQ M -1
        Stop
  /*Raise:
        ARNQ MLKJIHGA 8
        ARNQ A 0 A_ChangeFlag("FLOATBOB",1)
	Goto See*/
  }
}
Here's what we've tried.

-Deriving the actor from bosses we know work.
-Calling A_KillChildren
-Calling A_UnsetInvulnerable in case that somehow got triggered.
-Changing Wait to Stop in the Death state.
-Creating a fallthrough XDeath state
-Specifying the class of the spawner in the parameters of A_KillMaster

I might be missing a couple. Those are just the ones I remember. We've been just trying everything we can think of.

The real confusing part is that we had this problem with 2 different bosses on this spawner, because we forgot the the SXF_SETMASTER flag. That fixed one, but not the other.

Here's the spawner code too, just to be thorough.

Code: Select all

Actor SpiderMastermindSpawner : SpiderMastermind Replaces SpiderMastermind
{
	Health 10000000000
	Height 0
	Radius 0
	MONSTER
	-COUNTKILL
	+SHOOTABLE
	+CANTSEEK
	+INVISIBLE
	States
	{
	Spawn:
		NULL A 1
		Goto Summon
	Summon:
		NULL A 1
		NULL A 0 A_Jump(220,"Spider","Arachno","Queen","Haed")
		NULL A 0 A_Jump(182,"CM")
	Spider:
		NULL A 0
		NULL A 1 A_SpawnItemEX("SZ_SpiderMastermind",0,0,0,0,0,0,0,304,0)
		NULL A -1
		wait
	Arachno:
		NULL A 0
		NULL A 1 A_SpawnItemEX("SZ_Arachnophyte",0,0,0,0,0,0,0,304,0)
		NULL A -1
		wait
	Queen:
		NULL A 0
		NULL A 1 A_SpawnItemEX("SZ_AracnorbQueen",0,0,0,0,0,0,0,304,0)
		NULL A -1
		wait
	Haed:
		NULL A 0
		NULL A 1 A_SpawnItemEX("SZ_Haedexebus",0,0,0,0,0,0,0,304,0)
		NULL A -1
		wait
	CM:
		NULL A 0
		NULL A 1 A_SpawnItemEX("SZ_CyberMastermind",0,0,0,0,0,0,0,304,0)
		NULL A -1
		wait
	Pain:
		NULL A -1
		wait
	Death:
		NULL A 1 A_BossDeath
		NULL A 0 A_Die
		NULL A -1
		Stop
	}
}
If anyone has suggestions or sees the solution, please let me know.

Thanks!
Last edited by That Blind Guy on Thu Sep 07, 2017 7:07 am, edited 1 time in total.
User avatar
phantombeta
Posts: 2089
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

Re: Monster Spawner Not Dying When A_KillMaster is Called

Post by phantombeta »

You don't have SXF_SetMaster in your flags.
Also, don't ever use numbers for flag arguments. Use constants and combine them with '|' instead. Makes it more readable, and if for some reason the values ever need to be changed, it'll still work. (Like this: "SXF_NoCheckPosition | SXF_SetMaster")
(Specifically, 304 has bits 5, 6 and 9 set. That means it has SXF_NoCheckPosition, SXF_Telefrag and SXF_TransferPitch set. No SXF_SetMaster there. If you don't have that flag, it won't set the spawner as the actor's master, and your spawner won't be killed.)

Also, you seem to be using that just to randomize the monsters spawned. You can use the [wiki=Classes:RandomSpawner]RandomSpawner[/wiki] class instead. It automatically handles bosses and stuff, so you don't need to add A_KillMaster to your monsters.
That Blind Guy
Posts: 20
Joined: Fri Mar 10, 2017 8:18 am

Re: Monster Spawner Not Dying When A_KillMaster is Called

Post by That Blind Guy »

You don't have SXF_SetMaster in your flags.
Also, don't ever use numbers for flag arguments. Use constants and combine them with '|' instead. Makes it more readable, and if for some reason the values ever need to be changed, it'll still work. (Like this: "SXF_NoCheckPosition | SXF_SetMaster")
(Specifically, 304 has bits 5, 6 and 9 set. That means it has SXF_NoCheckPosition, SXF_Telefrag and SXF_TransferPitch set. No SXF_SetMaster there. If you don't have that flag, it won't set the spawner as the actor's master, and your spawner won't be killed.)

Also, you seem to be using that just to randomize the monsters spawned. You can use the RandomSpawner class instead. It automatically handles bosses and stuff, so you don't need to add A_KillMaster to your monsters.
I see. I am not the first to work on code for this project. I'd rather use flag names explicitly myself, but the two that were working on this before me had it this way. I just left it alone because it was working at the time.

Unfortunately, setting SXF_SetMaster and SXF_NoCheckPosition did nothing. I had tried SetMaster on its own before posting this, and that had the same result.
User avatar
phantombeta
Posts: 2089
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

Re: Monster Spawner Not Dying When A_KillMaster is Called

Post by phantombeta »

Then you're doing something wrong. Anyway, since you're only using this to randomize monster spawns, it'd be a good idea to use a RandomSpawner instead, as that won't require modification of the monsters to make the spawner work with bosses. (It'll also transfer some flags and properties that can be set by the map. Your spawner won't, and if these are not transferred it can completely break some maps.)
That Blind Guy
Posts: 20
Joined: Fri Mar 10, 2017 8:18 am

Re: Monster Spawner Not Dying When A_KillMaster is Called

Post by That Blind Guy »

That works almost perfectly. Thank you!

I do have one small problem now. The game is supposed to wait a few seconds after a boss dies before proceeding so that players have a chance to pick up item drops in the event killing them ends the level (Tower of Babel, Dis, etc.), however, the transitions are happening at the exact moment the boss enters its death state, long before it calls A_KillMaster and A_BossDeath.

This is all there is to the code.

Code: Select all

Actor SpiderMastermindSpawner : RandomSpawner Replaces SpiderMastermind
{
	DropItem "SZ_SpiderMastermind", 255, 1
	DropItem "SZ_Arachnophyte", 255, 1
	DropItem "SZ_AracnorbQueen", 255, 1
	DropItem "SZ_Haedexebus", 255, 1
	DropItem "SZ_CyberMastermind", 255, 1
}
I tried sticking a 200-tic delay in the Death state. Unsurprisingly that doesn't work, so I just pulled it back out.

What am I missing here?
That Blind Guy
Posts: 20
Joined: Fri Mar 10, 2017 8:18 am

Re: Monster Spawner Not Dying When A_KillMaster is Called

Post by That Blind Guy »

Finally a solution! Sorry for resurrecting a slightly old thread. Just giving this some closure.

It turns out the Crash state in the boss' code was the issue. Removing that fixed the problem right up!
Locked

Return to “Editing (Archive)”