Bouncing actor that doesn’t change states when stopping

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.

Bouncing actor that doesn’t change states when stopping

Postby Rip and Tear » Mon Mar 09, 2020 3:27 pm

I’ve got a decorative actor that I want to bounce. The problem is that (AFAIK) actors need to be flagged with +MISSILE in order to bounce, and missiles enter their Death state when they stop bouncing, which I don’t want.

Adding “Goto Spawn;” to the Death state won’t work because Spawn has multiple frames, so the goto causes the animation to restart from the beginning.
User avatar
Rip and Tear
I <3 ZScript
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Bouncing actor that doesn’t change states when stopping

Postby Dan_The_Noob » Mon Mar 09, 2020 5:12 pm

what do you want the actor to do?
User avatar
Dan_The_Noob
 
Joined: 07 May 2019
Twitch ID: Dan_The_Noob
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: nVidia with Vulkan support

Re: Bouncing actor that doesn’t change states when stopping

Postby Rip and Tear » Mon Mar 09, 2020 7:42 pm

Dan_The_Noob wrote:what do you want the actor to do?

Bounce without jumping states when it stops bouncing/hits something.
User avatar
Rip and Tear
I <3 ZScript
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Bouncing actor that doesn’t change states when stopping

Postby Dan_The_Noob » Mon Mar 09, 2020 7:49 pm

couldn't you just not make it a missile?
add +BOUNCEONFLOORS and +BOUNCEONCEILINGS etc.?
maybe create a "landed" version of the thing that it spawns on death? that's how mines work in one of my weapons.

do you mind posting the code you have?
User avatar
Dan_The_Noob
 
Joined: 07 May 2019
Twitch ID: Dan_The_Noob
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: nVidia with Vulkan support

Re: Bouncing actor that doesn’t change states when stopping

Postby Rip and Tear » Mon Mar 09, 2020 8:44 pm

The bounce flags don’t work without +MISSILE as far as I know. Removing +MISSILE removes the bounce behavior in my testing.

Default block:

Code: Select allExpand view
Default {
   Gravity 0.5;
   BounceType 'Hexen';
   +BOUNCEONFLOORS
   +BOUNCEAUTOOFFFLOORONLY
   +MISSILE
}
User avatar
Rip and Tear
I <3 ZScript
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Bouncing actor that doesn’t change states when stopping

Postby Dan_The_Noob » Mon Mar 09, 2020 10:57 pm

ok yeah, maybe just try making a landed version that pops up on death.

I'm assuming it's some kind of fireball/bomb/drone?
User avatar
Dan_The_Noob
 
Joined: 07 May 2019
Twitch ID: Dan_The_Noob
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: nVidia with Vulkan support

Re: Bouncing actor that doesn’t change states when stopping

Postby Matt » Mon Mar 09, 2020 11:51 pm

I can think of 2 options:


Option 1: same actor
Create a new state label, "SteadyState", where the projectile ends up after its initial spawn animation has finished.
On death, have it do all of the following:
- turn +missile back on
- give it a small boost in velocity in the direction it is facing
- jump to SteadyState


Option 2: 2 actors
Have your regular actor plus a second one (inheriting from the first) whose spawn state starts at whatever you would have defined as the "SteadyState" in Option 1.
On death, have actor 1 spawn actor 2 and give it some forward and randomized upwards/downwards momentum. (Actor 2 will just inherit this behaviour.)


Option 1 is a bit less computationally expensive since you're not spawning a new actor, but it's probably negligible and Option 2 is a bit mentally easier to keep track of.
User avatar
Matt
Putting the XD into *xdeath since 2007
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: Bouncing actor that doesn’t change states when stopping

Postby Xtyfe » Tue Mar 10, 2020 7:09 am

Rip and Tear wrote:I’ve got a decorative actor that I want to bounce. The problem is that (AFAIK) actors need to be flagged with +MISSILE in order to bounce, and missiles enter their Death state when they stop bouncing, which I don’t want.

Adding “Goto Spawn;” to the Death state won’t work because Spawn has multiple frames, so the goto causes the animation to restart from the beginning.


Have you tried setting BounceType to "None" and BounceCount to 0?

Here a modified Heretic Mace Ball that does an action only once and counts down a user variable to track the bounces but otherwise will be infinite bounces on walls and such.

Code: Select allExpand view
Class XtFireMaceFX : Actor
{
   Default
   {
      Radius 8;
      Height 6;
      Speed 15;
      Gravity 0.5;
      DamageFunction (Random(1, 8)*5);
      DamageType "Fire";
      Projectile;
      BounceType "None";
      BounceFactor 0.75;
      WallBounceFactor 0.75;
      BounceCount 0;
      SeeSound "weapons/maceshoot";
      BounceSound "weapons/macebounce";
      DeathSound "weapons/macehit";
      Obituary "$OB_MPMACE";
      +INTERPOLATEANGLES
      +FORCEXYBILLBOARD
      +NOFORWARDFALL
      +BOUNCEONWALLS
      +BOUNCEONFLOORS
      +BOUNCEONCEILINGS
      +ALLOWBOUNCEONACTORS
      +CANBOUNCEWATER
      +USEBOUNCESTATE
      -NOGRAVITY
   }
   
   int user_didfloorbounce;
   int user_didflooreffect;
   int user_dideffect;

   void A_XtFireMaceFireBounce()
   {
      Actor mo = Spawn("XtFireMaceFX4", Pos, ALLOW_REPLACE);
      if (mo != null)
         {
            mo.target = target;
            mo.angle = angle + random[MaceFX](-(45/16*2), (45/16*2));
            mo.VelFromAngle();
            mo.CheckMissileSpawn (radius);
         }
   }
   
   void A_XtFireMaceBallSplit()
   {
      Actor mo = Spawn("XtFireMaceFX", pos, ALLOW_REPLACE);
      if (mo != null)
      {
         mo.target = target;
         mo.angle = angle + random[MaceFX](-22.5, 22.5);
         mo.VelFromAngle(Vel.Z - 1.);
         mo.Vel += (Vel.XY * .5, Vel.Z);
         mo.CheckMissileSpawn (radius);
      }
      mo = Spawn("XtFireMaceFX", pos, ALLOW_REPLACE);
      if (mo != null)
      {
         mo.target = target;
         mo.angle = angle - random[MaceFX](-22.5, 22.5);
         mo.VelFromAngle(Vel.Z - 1.);
         mo.Vel += (Vel.XY * .5, Vel.Z);
         mo.CheckMissileSpawn (radius);
      }
   }
   
   States
   {
   Spawn:
      TNT1 A 0 A_JumpIf (user_didfloorbounce == 3, "Death");
      FX02 CD 4;
      Loop;
   Bounce.Floor:
      TNT1 A 0
         {
            if (user_didflooreffect == 0)
            {
               A_XtFireMaceFireBounce ();
               user_didflooreffect += 1;
            }
            
            if (user_dideffect == 0)
            {
               A_XtFireMaceBallSplit ();
               user_dideffect += 1;
            }
            
            user_didfloorbounce += 1;
         }
      Goto Spawn;
   Bounce.Ceiling:
      TNT1 A 0
         {
            if (user_dideffect == 0)
            {
               A_XtFireMaceBallSplit ();
               user_dideffect += 1;
            }
         }
      Goto Spawn;
   Bounce.Wall:
      TNT1 A 0
         {
            if (user_dideffect == 0)
            {
               A_XtFireMaceBallSplit ();
               user_dideffect += 1;
            }
         }
      Goto Spawn;
   Bounce.Actor:
      TNT1 A 0
         {
            if (user_dideffect == 0)
            {
               A_XtFireMaceBallSplit ();
               user_dideffect += 1;
            }
         }
      Goto Spawn;
   Death:
      TNT1 A 0
         {
            Vel = (0, 0, 0);
            bBounceOnWalls = false;
            bBounceOnFloors = false;
            bBounceOnCeilings = false;
            bAllowBounceOnActors = false;
            bNoGravity = true;
            Gravity = 1;
         }
      FX02 G 4 Bright A_SetRenderStyle (1, STYLE_ADD);
      FX02 HIJK 4 Bright;
      Stop;
   }
}
User avatar
Xtyfe
Neque Deos, Neque Dominos
 
Joined: 15 Dec 2007
Location: The Intertubes

Re: Bouncing actor that doesn’t change states when stopping

Postby Rip and Tear » Thu Mar 26, 2020 10:33 am

None of the current answers really solve my problem. I don’t think I’ve explained the issue clearly enough, so I’ll try to be a bit more concrete.

Here’s the States block from the specific actor I’m working with.

Code: Select allExpand view
States {
Spawn:
   ICEC ABCD 10 A_IceSetTics();
   Stop;
}


I want the actor to go through these states without any changes to their duration. Whenever one of the actors hits something or loses enough momentum to stop bouncing, it disappears. Even if I made Death just jump to Spawn, it would still cause the actor to go back to the first frame.

This is the workaround I came up with, but it’s a bit sloppy and I’m still looking for something better.

Code: Select allExpand view
override void Tick() {
   State previousState = self.curState;
   
   Super.Tick();
   
   if (self.curState == findState('Death')) {
      setState(previousState, true);
   }
}
User avatar
Rip and Tear
I <3 ZScript
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Bouncing actor that doesn’t change states when stopping

Postby Matt » Thu Mar 26, 2020 5:40 pm

Could you describe in more general terms what you want the finished product to look like? It might be more fruitful to go with a different approach depending on the exact desired effect.
User avatar
Matt
Putting the XD into *xdeath since 2007
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia


Return to Scripting

Who is online

Users browsing this forum: No registered users and 1 guest