monster that throws another monster, is it possible? sort of

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
bimshwel
Posts: 725
Joined: Tue Jul 15, 2003 5:15 pm
Location: misplaced
Contact:

monster that throws another monster, is it possible? sort of

Post by bimshwel »

or: when is a corpse not a corpse?

the monster tentatively named "pogthrower" is to encounter another object called pog and throw it at whoever it so pleases. Up to this point, the best way i could think to accomplish that was to use the arch-vile's raise method, which potentially you have seen done before. It is easy to do with a stationary object. In this case I want pog to be able to move around and also be shootable by the player (i also want pog to be gettable by the player but that is less important and a problem for later if ever).

My first attempt, making the pog "die" immediately and then walk around, spawning a separate object that looks like it is exploding if shot by the player didn't fool the game at all. although i had forgotten to give pogthrower vilechase frames at that point, but my experience with what i did later makes me think that still wouldn't work!

Another idea almost worked, having pog drop small, invisible objects (plorg) that "die" immediately and then can be raised by the pog thrower, which at the same time shoots a projectile that quickly removes pog from the ground before turning to face the player and seem to throw the pog.

However, the game only seems to consider a dead plorg a corpse once it stops animating, which either means they stay permanently on the ground and quickly outnumber the actual pogs or are removed from the game and therefore cannot be "raise"d at all.

Code: Select all

ACTOR pogthrower 500

{
 [irrelevant stuff]
		  heal:
		  fope [ 8
		  fope \ 8
		  fope ] 0 A_SpawnProjectile ("pogremover", 8, 0, 0, 0, 0)
		  fope ] 0 a_facetarget
		  fope ] 8 A_SpawnProjectile ("cheappog", 48, 0, 0, 0, 0)
		  goto see
		  
}
}

actor pogremover
{
projectile
speed 10
  DamageType pogremoval
  damage 1
  states
  {spawn:
  tnt1 a 1
  loop
  }
  }

actor trickpog 501
{
bloodtype organicpain
  PainChance "pogremoval", 255
     Radius 16
     Height 40
     Mass 100
	 
     Speed 8
     Scale 1.0
     Painchance 300
	 DeathSound "world/barrelx"
	   +SOLID
  +SHOOTABLE
  +ACTIVATEMCROSS
  +DONTGIB
  +NOICEDEATH
  +OLDRADIUSDMG
health 20
states
{
spawn:
pogg a 10 a_look
goto see
see:
POGG b 4 a_chase
pogg b 0 A_SpawnItemEx ("plorg", 0, 0, 0, 0, 0, 0, 0)
POGG b 4 a_chase
pogg b 0 A_SpawnItemEx ("plorg", 0, 0, 0, 0, 0, 0, 0)
pogg c 4  a_chase
pogg c 0 A_SpawnItemEx ("plorg", 0, 0, 0, 0, 0, 0, 0)
pogg c 4   a_chase
pogg c 0 A_SpawnItemEx ("plorg", 0, 0, 0, 0, 0, 0, 0)
//it has a bunch of walking frames but i wasn't going to put them all in until i was sure this worked
loop
   Melee:
          POGG a 4 A_facetarget
          GoTo See
		  pain:
		  POGG h 4
		   POGG h 4 a_pain
		   goto see
		   death:
pogg h 1 A_SpawnItemEx ("pogsplode", 0, 0, 0, 0, 0, 0, 0)
	stop
	pain.pogremoval:
	pogg h 1
	stop
		  }
		  }

actor plorg
		  {
		+shootable
		  radius 0
		  height 0
		  mass 1
		  states
		  {
		  spawn:
		  tnt1 a 1
		  tnt1 a 1 a_die
		  stop
		  death:
		  tnt1 a 1
		  tnt1 a 1 a_fall
		  tnt1 aaaaaaaaaaaaaaaa 1
		  tnt1 a 1
// aaaaaaaaaaaaaaaa it doesn't work!
		  stop
		  raise:
		  tnt1 a 1 
		  stop
		  }
		  }
another way would be for pog itself to cause a custom damage type that only hurts pogthrower, sending it into a unique pain state which removes the pog and throws a pog at its target (provided i kept it from identifying pog as its new target), but it would animate in the direction it was facing rather than where it got hurt from.

do you know of a better way to accomplish this? Thank you and good luck.
Last edited by bimshwel on Tue Aug 14, 2018 10:10 pm, edited 1 time in total.
User avatar
Ichor
Posts: 1784
Joined: Wed Jul 23, 2003 9:22 pm

Re: monster that throws another monster, is it possible?

Post by Ichor »

Perhaps you could try A_QueueCorpse for your "plorg"s, and set the sv_corpsequeuesize value to a low number, like maybe 5 or something. Hexen normally uses this to keep down the number of dead things since back then, computers were much slower and this was their way of limiting slowdown. Also there was that sprite limit that prevents some things from showing up. I've never used it myself, and it never really is needed nowadays, but it might work here. It only affects things with use A_QueueCorpse (which would only be the "plorg"s), so other things dying shouldn't affect the corpsequeuesize total.
User avatar
bimshwel
Posts: 725
Joined: Tue Jul 15, 2003 5:15 pm
Location: misplaced
Contact:

Re: monster that throws another monster, is it possible?

Post by bimshwel »

Thank you! Ah ha that is a good idea! I was thinking of the lost soul limit but uncertain how to tie it in here.
However I have never used a cvar before. https://zdoom.org/wiki/Custom_CVARs_with_DECORATE i tried to do what this page said, using "sv_corpsequeuesize" in place of a made up item, so that i could alter the number, but it tells me the thing already exists, but I am unclear on the method for using one that already exists. The default number 64 seems too high unless I have an impractically large number of pog things active at once.

I vaguely recall reading something to the effect that it is possible to make a spawner "kill" all its spawnees once it is itself "killed" but proving that is eluding me at the moment. And since these ones would already be "dead" that might not make a huge heap of difference.
Last edited by bimshwel on Tue Aug 14, 2018 12:37 pm, edited 1 time in total.
User avatar
Ichor
Posts: 1784
Joined: Wed Jul 23, 2003 9:22 pm

Re: monster that throws another monster, is it possible?

Post by Ichor »

It turns out that you can't modify existing CVars by ACS or decorate (thanks for that one, Terry wads). So another idea is to have the thrower be the pog's master. Then you can have the pog continually use A_JumpIfMasterCloser to check if the thrower is in melee range. At that point, you could spawn a few "plorg"s in the thrower's path.
User avatar
bimshwel
Posts: 725
Joined: Tue Jul 15, 2003 5:15 pm
Location: misplaced
Contact:

Re: monster that throws another monster, is it possible?

Post by bimshwel »

Gosh I never heard of that one (or terry wads) but was able to look it up. I must be really screwing something up here; this thing will not jump at all, even with an excessively high radius number.
I designate it as having a master by using inheritance, right?

Code: Select all

actor throwpog : pogthrower 501
{
bloodtype organicpain
  PainChance "pogremoval", 255
     Radius 16
     Height 40
     Mass 100
	 
     Speed 4
     Scale 1.0
     Painchance 300
	 DeathSound "world/pogsplode"
	   +SOLID
  +SHOOTABLE
  +ACTIVATEMCROSS
health 20
states
{
spawn:
pogg a 10 a_look
goto see
see:
pogg b 4 a_vilechase
pogg b 0 A_JumpIfMasterCloser(512, "makeplorg")
pogg c 4 a_vilechase
pogg c 0 A_JumpIfMasterCloser(512, "makeplorg")
pogg d 4 a_vilechase
pogg d 0 A_JumpIfMasterCloser(512, "makeplorg")
loop

makeplorg: 
pogg a 0 A_SpawnItemEx ("plorg", 0, 0, 0, 0, 0, 0, 0)
pogg a 8
goto see
   heal:
          POGG a 4 A_facetarget
          GoTo See
//so that it can remove the plorg itself if it fails to get noticed by its master
Or is it only applicable with thingspawnex? That certainly complicates this yet further; i would need the pogthrower to create its own ammunition in the appropriate spots before the player ever saw it. However it does seem feasible.

Alternatively, I could go back to the old way but make the pogs run acs scripts instead that spawn plorgs with tids and thing_removes them if they still exist after a few seconds. maybe maybe maybe. must investigate later.
User avatar
bimshwel
Posts: 725
Joined: Tue Jul 15, 2003 5:15 pm
Location: misplaced
Contact:

Re: monster that throws another monster, is it possible?

Post by bimshwel »

Ah ha! Ha ha ha ha. I don't know why I didn't think of this immediately other than that i wanted to be able to do it without scripts so I could put the pog thrower into any level, and also because I am terrible at making scripts, but this one is basic.
It is annoying but not as bad as having a cavity filled.

Code: Select all

 script 987 open
{
	SpawnSpotForced ("plorg", 97, 96, 0);
	ThrustThing (0, 4, 0, 96);
	SpawnSpotForced ("plorg", 97, 95, 32);
	ThrustThing (32, 4, 0, 95);
	SpawnSpotForced ("plorg", 97, 94, 64);
	ThrustThing (64, 4, 0, 94);
	SpawnSpotForced ("plorg", 97, 93, 96);
	ThrustThing (96, 4, 0, 93);
SpawnSpotForced ("plorg", 97, 92, 128);
ThrustThing (128, 4, 0, 92);
SpawnSpotForced ("plorg", 97, 91, 160);
ThrustThing (160, 4, 0, 91);
SpawnSpotForced ("plorg", 97, 90, 192);
ThrustThing (192, 4, 0, 90);
SpawnSpotForced ("plorg", 97, 89, 224);
ThrustThing (224, 4, 0, 89);
	delay(20);
	Thing_Remove(96);
	Thing_Remove(95);
	Thing_Remove(94);
	Thing_Remove(93);
	Thing_Remove(92);
	Thing_Remove(91);
	Thing_Remove(90);
	Thing_Remove(89);
restart;
  }
it sends the plorgs out around each pog, since raise cannot occur when an object is in the same space as the "corpse." 20 tics is short enough to conclude before the throw animation does, although if i want to speed up the animation, once it exists, i can add regular non-vile chase frames after it.

Code: Select all

   heal:
		  fope [ 6
		  fope [ 0 A_SpawnProjectile ("pogremover", 8, 0, 0, 0, 0)
		  fope \ 6 //i want it to face where the pog was until the lift concludes, and THEN turn
		  fope ] 0 a_facetarget
		  fope ] 6 A_SpawnProjectile ("thrownpog", 48, 0, 0, 0, 0)
		  fope i 6
		  FOPE CCDD 2 a_chase 
		  goto see

This means i don't need the pog itself to do anything special apart from, when conventionally destroyed, be removed immediately and spawn a clone of itself that "dies" so that it loses its tid.

it is not perfect; if the pog turns just before the monster tries to throw it, the invisible pog-remover shot misses, However in the full context it will be a "boss" and pogs will enter the room continuously, because they are not very observant, and so it will be less obvious if occasionally one is not removed when it ought to be.

I will probably post a video once I have drawn the pog thrower itself. I can imagine having other uses for that A_JumpIfMasterCloser now that I know it exists.

Having the raised object immediately cause a custom pain type that only affects the thrower and sends it to a corresponding state could potentially allow a variety of monsters to be "thrown," although that will be a problem for later!

Uef great frimpity.
Post Reply

Return to “Scripting”