Grenade Projectile Help

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
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
Goldenflare5643
Posts: 122
Joined: Sat Oct 08, 2016 9:20 pm
Location: One of those stupid 2fort daycare servers

Grenade Projectile Help

Post by Goldenflare5643 »

Im trying to make a timed grenade projectile that explodes 2.3 seconds after first bounce but also on contact.
Here's my code:

Code: Select all

ACTOR GrenadeTimer : Inventory
{
	Inventory.MaxAmount 230
	+INVENTORY.IGNORESKILL
}

ACTOR CoolGrenade
{
	PROJECTILE
	-NOGRAVITY
	+RANDOMIZE
	+DEHEXPLOSION
	+NOTELESTOMP
	+NOICEDEATH
	+DONTTRANSLATE
	+BOUNCEONWALLS
	+BOUNCEONFLOORS
	+BOUNCEONCEILINGS
	+USEBOUNCESTATE
	Radius 4
	Height 8
	BounceFactor 0.9
	WallBounceFactor 0.25
	Mass 5
	Speed 35
	Damage 100
	BounceType "Grenade"
	States
	{
		Spawn:
		TNT1 A 0 A_GiveInventory("GrenadeTimer", 0)
		Spawned:
		SGRN A 1 Bright
		Loop
		
		SpawnBounced:
		SGRN A 1 Bright A_TakeInventory("GrenadeTimer", 1)
		TNT1 A 0 A_JumpIfInventory("GrenadeTimer", 1, "SpawnBounced")
		Goto Death
		
		Bounce:
		SGRN A 0
		{
			A_SetAngle(angle + random(-5, 5));
			A_ChangeVelocity(((abs(velx) + abs(vely)) * cos(angle)) * frandom(BounceFactor - 0.3, BounceFactor + 0.1), ((abs(velx) + abs(vely)) * sin(angle)) * frandom(BounceFactor - 0.3, BounceFactor + 0.1), velz * frandom(BounceFactor - 0.3, BounceFactor + 0.1), CVF_REPLACE);
		}
		Goto SpawnBounced
		
		Sit:
		SGRN A 1 Bright
		Goto Death
		
		Death:
		MISL A 0 A_ScreamAndUnblock
		MISL B 8 Bright A_Explode
		MISL C 6 Bright
		MISL D 4 Bright
		Stop
	}
}
Grenade's physics works as expected but, when the grenade bounces it goes to death state but only disapears if it doesnt bounce before its death state is up, as if the bounce state is interupting it. Now that is a problem I can fix, but what I cant fix is it going immediately into death state and not exploding after the actor GrenadeTimer is gone.

Im using an actor as a timer and i dont think that works on projectiles though... But I hope you can see what im trying to do here and help me get unstuck if you know what i mean.

~Thank you.
User avatar
22alpha22
Posts: 308
Joined: Fri Feb 21, 2014 5:04 pm
Graphics Processor: nVidia with Vulkan support
Location: Montana, USA

Re: Grenade Projectile Help

Post by 22alpha22 »

By setting the amount in A_GiveInventory to '0', your actually only giving the missile 1 of your grenade timer tokens rather than 230. Also since your reducing the timer tokens by 1 every 1 tic, it will take about 6.5 seconds for the grenade to explode rather than 2.5 seconds like you want because Doom runs at 35 tics/second. Why not use a User Variable for the timer rather than an inventory token? Another thing, the action function on the first frame any actor's spawn state is never executed the first time unless you preface it with the NoDelay keyword, therefore your grenade never even gets any of it's timer tokens.

Here try this version of your grenade:

Code: Select all

ACTOR CoolGrenade
{
   PROJECTILE
   -NOGRAVITY
   +RANDOMIZE
   +DEHEXPLOSION
   +NOTELESTOMP
   +NOICEDEATH
   +DONTTRANSLATE
   +BOUNCEONWALLS
   +BOUNCEONFLOORS
   +BOUNCEONCEILINGS
   +USEBOUNCESTATE
   Radius 4
   Height 8
   BounceFactor 0.9
   WallBounceFactor 0.25
   Mass 5
   Speed 35
   Damage 100
   BounceType "Grenade"
   Var Int User_GrenadeTimer;
   States
   {
      Spawn:
      TNT1 A 0 NoDelay A_SetUserVar("User_GrenadeTimer",88) //The NoDelay keyword is necessary for the action function to execute on the first frame of the spawn state
      Spawned:
      SGRN A 1 Bright
      Loop
      
      SpawnBounced:
      SGRN A 1 Bright
      {
        A_SetUserVar("User_GrenadeTimer",User_GrenadeTimer - 1); //Count down the grenade's timer

         If (User_GrenadeTimer <= 0)
         {
            Return State("Death");  //If the timer reaches '0', go to the death state
         }
         Else
         {
            Return State(0);
         }
      }
      Wait
      
      Bounce:
      SGRN A 0
      {
         A_SetAngle(angle + random(-5, 5));
         A_ChangeVelocity(((abs(velx) + abs(vely)) * cos(angle)) * frandom(BounceFactor - 0.3, BounceFactor + 0.1), ((abs(velx) + abs(vely)) * sin(angle)) * frandom(BounceFactor - 0.3, BounceFactor + 0.1), velz * frandom(BounceFactor - 0.3, BounceFactor + 0.1), CVF_REPLACE);
         A_ChangeFlag(USEBOUNCESTATE,False); //So that the grenade wont go back into the bounce state again if it keeps bouncing
      }
      Goto SpawnBounced
      
      Sit:
      SGRN A 1 Bright
      Goto Death
      
      Death:
      MISL A 0 A_ScreamAndUnblock
      MISL B 8 Bright A_Explode
      MISL C 6 Bright
      MISL D 4 Bright
      Stop
   }
}
User avatar
Goldenflare5643
Posts: 122
Joined: Sat Oct 08, 2016 9:20 pm
Location: One of those stupid 2fort daycare servers

Re: Grenade Projectile Help

Post by Goldenflare5643 »

22alpha22 wrote:By setting the amount in A_GiveInventory to '0', your actually only giving the missile 1 of your grenade timer tokens rather than 230. Also since your reducing the timer tokens by 1 every 1 tic, it will take about 6.5 seconds for the grenade to explode rather than 2.5 seconds like you want because Doom runs at 35 tics/second. Why not use a User Variable for the timer rather than an inventory token? Another thing, the action function on the first frame any actor's spawn state is never executed the first time unless you preface it with the NoDelay keyword, therefore your grenade never even gets any of it's timer tokens.
Wow thank you ill try this.

Yeah i didnt use a variable because I got into a habbit of using actors as variables because most of my work up to this point was with weapons (which i couldnt figure out how to make use of variables in). I actualy want the grenade to bounce multiple times before it explodes though, the action that changes its velocity makes it so that the grenade seems to "roll" when its velocity gets low. Though, I want it to have that "rolling" effect without having it bounce rapidly and making noise for when i give it a custom noise, im thinking about using an IF to make it so it doesnt use the bounce state or see state and switches to looping though the "Sit" state (while also removing USEBOUNCESTATE), where it will slowly glide around for a bit and then explode. How would you go about doing that?

Edit: i forgot about the 35 tics/second thing thx for catching that lol :D

Edit 2: what is the advantage of using "wait" over "loop"?
User avatar
Dan_The_Noob
Posts: 880
Joined: Tue May 07, 2019 12:24 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Grenade Projectile Help

Post by Dan_The_Noob »

"Wait" basically just means keep doing this until it finishes.
"loop" do this forever

at least far as i can tell from seeing it in places.
Post Reply

Return to “Scripting”