Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
bench

DECORATE Question: Is there a way to make A_SpawnItemEx check for room?

Recommended Posts

Hello!

I am currently trying to create a variation of the Demon that teleports towards the player when it's far away but I constantly get them stuck into walls. I think it should be fixable if I could stop my TeleDemonMissile from spawning TeleDemonSpot when there isn't enough room for it. I can't figure out how to do that though. I'd really appreciate some help.

Here's my code:

ACTOR TeleDemon
{
  Game Doom
  Health 100
  PainChance 180
  Speed 8
  Radius 30
  Height 56
  Species demon
  Mass 400
  MeleeThreshold 200
  Monster
  +ALWAYSFAST
  +FLOORCLIP
  SeeSound "demon/sight"
  AttackSound "demon/melee"
  PainSound "demon/pain"
  DeathSound "demon/death"
  ActiveSound "demon/active"
  Obituary "%o was bit by a teleporting demon."
  States
  {
  Spawn:
    TDEM AB 10 A_Look
    Loop
  See:
    TDEM AABBCCDD 4 Fast A_Chase
    Loop
  Melee:
    TDEM EF 8 Fast A_FaceTarget
    TDEM G 8 Fast A_SargAttack
    Goto See
  Missile:
    TDEM H 0 A_CustomMissile("TeleDemonMissile",56,0)
	TDEM H 0 A_Teleport("See", "TeleDemonSpot")
    Goto See
  Pain:
    TDEM H 2 Fast
    TDEM H 2 Fast A_Pain
    Goto See
  Death:
    TDEM I 8
    TDEM J 8 A_Scream
    TDEM K 4
    TDEM L 4 A_NoBlocking
    TDEM M 4
    TDEM N -1
    Stop
  Raise:
    TDEM N 5
    TDEM MLKJI 5
    Goto See
  }
}

ACTOR TeleDemonMissile
{
  Radius 30
  Height 56
  Speed 25
  Damage 0
  Projectile
  +NOCLIP
  States
  {
  Spawn:
    APLS AB 5 Bright
    Goto Death
  Death:
    APBX A 1 A_SpawnItemEx ("TeleDemonSpot")
    Stop
  }
}

ACTOR TeleDemonSpot : SpecialSpot
{
  Radius 30
  Height 56
  States
  {
  Spawn:
    APLS AB 5 Bright
    Goto Death
  Death:
    APBX A 1 Bright
    Stop
}
}
(The projectiles will be invisible once it's working properly, it's only visible right now for debugging reasons)

Share this post


Link to post

Yes, it is possible, I've done it before.

Make TeleDemonMissile spawn a dummy projectile - TeleCheck, which will indicate if there's an available space or not. If not, TeleCheck (as a projectile) will jump to a death state, where it will use A_GiveToTarget() function to give a dummy inventory ("noway") to its originator, TeleDemonMissile. TeleDemonMissile will check for this dummy inventory (A_CheckInventory() function) and will abort spawning TeleDemonSpot if it receives this inventory.

Full code which worked for me:

ACTOR TeleDemon
{
  Game Doom
  Health 100
  PainChance 180
  Speed 8
  Radius 30
  Height 56
  Species demon
  Mass 400
  MeleeThreshold 200
  Monster
  +ALWAYSFAST
  +FLOORCLIP
  SeeSound "demon/sight"
  AttackSound "demon/melee"
  PainSound "demon/pain"
  DeathSound "demon/death"
  ActiveSound "demon/active"
  Obituary "%o was bit by a teleporting demon."
  States
  {
  Spawn:
    SARG AB 10 A_Look
    Loop
  See:
    SARG AABBCCDD 4 Fast A_Chase
    Loop
  Melee:
    SARG EF 8 Fast A_FaceTarget
    SARG G 8 Fast A_SargAttack
    Goto See
  Missile:
    SARG H 0 A_CustomMissile("TeleDemonMissile",56,0)
	SARG H 0 A_Teleport("See", "TeleDemonSpot")
    Goto See
  Pain:
    SARG H 2 Fast
    SARG H 2 Fast A_Pain
    Goto See
  Death:
    SARG I 8
    SARG J 8 A_Scream
    SARG K 4
    SARG L 4 A_NoBlocking
    SARG M 4
    SARG N -1
    Stop
  Raise:
    TDEM N 5
    TDEM MLKJI 5
    Goto See
  }
}

ACTOR TeleDemonMissile
{
  Radius 30
  Height 56
  Speed 25
  Damage 0
  Projectile
  +NOCLIP
  States
  {
  Spawn:
    APLS AB 5 Bright
    Goto Death
  Death:
    APBX A 2 A_SpawnItemEx ("TeleCheck")
	TNT1 A 0 A_JumpIfInventory("noway",1,1)
	APBX A 1 A_SpawnItemEx ("TeleDemonSpot")
	stop
  }
}

ACTOR TeleDemonSpot : SpecialSpot
{
  Radius 30
  Height 56
  States
  {
  Spawn:
	APLS AB 5 Bright
    Goto Death
  Death:
    APBX A 1 Bright
    Stop
}
}

ACTOR TeleCheck {
  Height 57
  Radius 31
  Health 1
  PROJECTILE
  -NOBLOCKMAP
  -RANDOMIZE
  Speed 0
  States {
    Spawn:
	  TROO A 0
	  stop
	Death:
	  TROO A 1
	  TROO A 0 A_GiveToTarget("noway",1)
	  stop
  }
}

actor noway:inventory { inventory.maxamount 1 }
I can't 100% assure you it's reliable as I've written it, but I believe the principle is right and can be improved upon (although I'm not going to try it). It's also well possible that there's a much simpler solution that I didn't think off. :)

Side note: I recommend to make TeleDemonMissile inherit from FastProjectile class (start the definition with ACTOR TeleDemonMissile : FastProjectile). That will allow the projectile to have a really high Speed (above 100 or even 500, if you want) without collision side effects. Any projectile with Speed higher than 35 needs this special care, I believe.


EDIT: I've just found out that it isn't very reliable yet. You can try the other way around: Try to spawn a dummy solid actor. If there's no space available, it won't spawn at all. If there is, it will spawn, and again, it can give inventory to its "parent" somehow - maybe.

Share this post


Link to post

Would this work better for you:

 Teleport:
  MUMM AAAAAAAAA 1 A_FadeTo(0.01, 0.1)
  TNT1 AAAAAAAAA 0 A_Chase
  MUMM AAAAAAAAA 1 A_FadeTo(1, 0.1)
   Goto See
I just recently happened to make a teleporting variant of the Heretic mummy, and it seems to work nicely.

Of course, the code above won't let the demon cross chasms by teleporting, if that's what you're after.

Share this post


Link to post

^Yes, it's a good solution too. You just need to use A_Chase("","") instead of plain A_Chase, to prevent the monster from entering his attack state (melee or missile) while "teleporting".

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×