"Over Here!" Making Decoy Powerups

Handy guides on how to do things, written by users for users.
Forum rules
Please don't start threads here asking for help. This forum is not for requesting guides, only for posting them. If you need help, the Editing forum is for you.
User avatar
amv2k9
Posts: 2178
Joined: Sun Jan 10, 2010 4:05 pm
Location: Southern California

"Over Here!" Making Decoy Powerups

Post by amv2k9 »

MDK. Ratchet & Clank. Duke Nukem 3D. These are some of the many games and game series that have had some sort of decoy powerup, which distracts enemies and buys you some time to catch your breath. If you want to add this sort of mechanic into your mod, but are unsure as how to go about doing it, this is the tutorial for you.

This tutorial will expect the user to have some knowledge with DECORATE, as we will be working with expressions.

First off, we'll make our decoy actor.

Code: Select all

ACTOR HoloDecoy
{
 MONSTER
 -COUNTKILL
 +NOBLOOD
 Radius 10
 Height 9
 Health 1500
 Mass 0x7FFFFFFF
 DamageFactor 0.0
 Scale 0.5
 Speed 2
 States
 {
 Spawn:
  HOLP ABCD 3
  HOLP ABCD 2
  TNT1 A 0 A_SpawnItemEx("HoloDecoyProjection",0,0,10,0,0,0,0,SXF_SETMASTER)
  HOLP ABCD 1
 SpawnLoop:
  HOLP ABCD 1 A_Wander
  TNT1 A 0 A_DamageSelf(10,"None",DMSS_NOFACTOR)
  Loop
 Death:
  HOLP ABCD 2 A_Wander
  HOLP ABCD 3 A_Wander
  HOLP ABCD 4 A_Wander
  HOLP ABCD 5 A_Wander
  TNT1 A 0 A_KillChildren("HoloKill")
  HOLP A 1 A_FadeOut(0.1,1)
  Wait
 }
}
Nothing terribly complex; Once it's spawned, the actor spawns the HoloDecoyProjection actor, which is set as a child of its spawner, then promptly mills about aimlessly through the use of A_Wander. When it completes its SpawnLoop state, it decrements its own health by 10. Once it dies, it kills its child and fades out.

Now, for the projection that our decoy spawns.

Code: Select all

ACTOR HoloDecoyProjection
{
 MONSTER
 +FRIENDLY
 -COUNTKILL
 +GHOST
 +NOBLOODDECALS
 +DONTFALL
 +NOGRAVITY
 BloodType ""
 Height 45
 Radius 5
 Health 1
 Mass 0x7FFFFFFF
 DamageFactor 0.0
 DamageFactor "HoloKill", 1
 RenderStyle "Add"
 Alpha 0.75
 Scale 0.75
 States
 {
 Spawn:
  TNT1 A 0 NoDelay Thing_ChangeTID(0,666)
 SpawnLoop:
  HOLO A 0 A_RadiusGive("DecoyHater",512,RGF_MONSTERS)
  HOLO AAAABBBBCCCCDDDD 1 BRIGHT A_Warp(AAPTR_MASTER,0,0,15,0,WARPF_NOCHECKPOSITION|WARPF_INTERPOLATE)
  Loop
 Death.HoloKill:
  "####" "#" 0 A_NoBlocking
 FadeLoop:
  "####" "#" 0 BRIGHT A_SetScale(scalex-0.075,scaley+0.075)
  "####" "#" 2 BRIGHT A_FadeOut(0.1,1)
  Loop
 }
}
Things are a little more involved now. The first thing our projection does is set its own TID, the use of which we'll come back to in a moment. Next, it enters its SpawnLoop state, where it gives a DecoyHater item to every monster in a 512 mapunit radius, then it repositions itself every tic for twenty tics to fifteen mapunits above its master, through the use of A_Warp. This state will be continued until it finally dies, at which point it will undergo a simple effect where its sprite's width will decrease and height increase as it fades out. If your're unfamiliar with the use of "####" and "#" as the sprite name and frame, they're used to render the last sprite used by the actor.

Now, let's look at possibly the most important part of this example; the item the HoloDecoyProjection is giving to the monsters around it.

Code: Select all

ACTOR DecoyHater : CustomInventory
{
 +ALWAYSPICKUP
 States
 {
 Pickup:
  TNT1 A 0 A_JumpIf(CheckClass("HoloDecoy"),"End")
  TNT1 A 0 A_JumpIf(CheckClass("HoloDecoyProjection"),"End")
  TNT1 A 0 A_JumpIf(tidtohate==666,"End")
  TNT1 A 0 Thing_Hate(0,666,0)
 End:
  TNT1 A 0
  Stop
 }
}
The first thing this item does is check its class; that is, its checking the class of the monster that got the item. Remember; action functions called in a CustomInventory actor's Pickup state are treated as though the actor obtaining the item is the caller, not the item itself! If the checks for the item obtainer being the HoloDecoy or HoloDecoyProjection return true, the actor proceeds to the End state, where it does nothing. This is not strictly necessary for our example, but its present to show you what you may need to do if your mod has other friendly monsters in it. Don't want your friendlies attacking each other, after all!

The next thing the actor does is check the item obtainer's current hated TID, and if it is already the TID of the HoloDecoyProjection, it again moves to a state where it does nothing. If false, it then sets the item obtainer's hated TID to that of the HoloDecoyProjection. Above, I mentioned that the HoloDecoyProjection first set its own TID before doing anything else, and this is why; it gives us a no-nonsense way of garnering the attention of any monster we want it to. We check the obtainer's current hated TID before setting the TID to hate for a very important reason; if we continuously re-set a monster's hated TID, it will never complete its attack states, and will continuously stutter as it impotently attempts to chase or attack.

And that's it! Below is an compiled version of the above code as a pk3 for you to try out in Doom; just load it up and type in "summon HoloDecoy" at the console to see the above decoy in action.
You do not have the required permissions to view the files attached to this post.
User avatar
Nash
 
 
Posts: 17506
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: "Over Here!" Making Decoy Powerups

Post by Nash »

Very cool example, thanks!

Return to “Tutorials”