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.

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
Rip and Tear
Posts: 185
Joined: Tue May 02, 2017 3:54 pm

Bouncing actor that doesn’t change states when stopping

Post by Rip and Tear »

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
Dan_The_Noob
Posts: 872
Joined: Tue May 07, 2019 12:24 pm
Graphics Processor: nVidia with Vulkan support
Contact:

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

Post by Dan_The_Noob »

what do you want the actor to do?
User avatar
Rip and Tear
Posts: 185
Joined: Tue May 02, 2017 3:54 pm

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

Post by Rip and Tear »

Dan_The_Noob wrote:what do you want the actor to do?
Bounce without jumping states when it stops bouncing/hits something.
User avatar
Dan_The_Noob
Posts: 872
Joined: Tue May 07, 2019 12:24 pm
Graphics Processor: nVidia with Vulkan support
Contact:

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

Post by Dan_The_Noob »

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
Rip and Tear
Posts: 185
Joined: Tue May 02, 2017 3:54 pm

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

Post by Rip and Tear »

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 all

Default {
	Gravity 0.5;
	BounceType 'Hexen';
	+BOUNCEONFLOORS
	+BOUNCEAUTOOFFFLOORONLY
	+MISSILE
}
User avatar
Dan_The_Noob
Posts: 872
Joined: Tue May 07, 2019 12:24 pm
Graphics Processor: nVidia with Vulkan support
Contact:

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

Post by Dan_The_Noob »

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
Matt
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
Contact:

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

Post by Matt »

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
Xtyfe
Posts: 1480
Joined: Fri Dec 14, 2007 6:29 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 11
Graphics Processor: nVidia with Vulkan support

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

Post by Xtyfe »

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 all

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
Rip and Tear
Posts: 185
Joined: Tue May 02, 2017 3:54 pm

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

Post by Rip and Tear »

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 all

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 all

override void Tick() {
	State previousState = self.curState;
	
	Super.Tick();
	
	if (self.curState == findState('Death')) {
		setState(previousState, true);
	}
}
User avatar
Matt
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
Contact:

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

Post by Matt »

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.
Post Reply

Return to “Scripting”