[SOLVED][ZSCRIPT]Parabolic Trajectory for Projectiles Function Help

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
Kan3x
Posts: 67
Joined: Tue Nov 08, 2022 4:19 pm

[SOLVED][ZSCRIPT]Parabolic Trajectory for Projectiles Function Help

Post by Kan3x »

Hi guys.

I was trying to play around with projectile motion to make a 100% accurate projectile that follows a parabolic trajectory (basically like fireballs in doom 3), changing its pitch and velocity depending on the target's distance.

I came up with this function here, that is working wonderfully, except for when the target is closer than the maximum projectile range at maxpitch and higher than the projectile spawn pos.

Code: Select all

action void A_SpawnParabolicProj(class<actor> missiletype, double spawnheight, double spawnofs_xy = 0, double angle = 0, double maxpitch = 30, double projgravity = 0.25, bool veladjust = false, int ptr = AAPTR_TARGET) {
		let ref = GetPointer(ptr); //get the set actor pointer
		if(!ref || (ref && ref.Health < 1)) //if there's no victim or it's dead
			return; //do nothing;
			
		double v = GetDefaultSpeed(missiletype); //get the projectile speed
		double d = Distance2D(ref); //get the distance from the victim without accounting for the altitude difference
		double g = projgravity; //set the projectile's gravity with the function itself
		double h = ref.pos.z + ref.height / 2.0 - self.pos.z - spawnheight; //get the height difference between the victim's center and the projectile spawn point
		double k = -h; //height difference between the projectile spawn point and the victim's center
		double p; //pitch

		//double a = -PitchTo(ref, spawnheight - height/2, 0); //pitch from projectile spawn height and the victim center (not used)
		if(maxpitch > 90.0) //if the maximum pitch exeeds 90°
			maxpitch = 90.0; //set it to 90°
		else if(maxpitch < 0)
			maxpitch = 30.0;
		double vx = v * cos(maxpitch); //horizontal velocity
		double vy = v * sin(maxpitch); //vertical velocity
		double b = sin(2 * (maxpitch)); //velocity component
		if(b == 0)
			g = 0.0;
		//double t = (vy + sqrt(vy**2 + 2 * g * k)) / g; //flight time (not used)
		//double r = vx * t; //maximum range (not used)
		
		if(maxpitch != 0) {
			if(veladjust && b != 0) //if the projectile shouldn't have a range limit
				v = max(sqrt(d * g / b), v); // (should) adjust the projectile's velocity to be able to reach the victim
			p = atan((v**2.0 - sqrt(v**4.0 - g * (g * (d**2.0) + 2.0 * h * (v**2.0)))) / (g * d)); //calculate the pitch according to every parameter and never let it exceed the maximum pitch
		}
		else
			p = 0;
		
		let bal = A_SpawnProjectile(missiletype, spawnheight, spawnofs_xy, angle, CMF_CHECKTARGETDEAD|CMF_ABSOLUTEPITCH, -p, ptr); //shoot the projectile with the proper parameters
		if(bal) { //if the spawn was succesful
			bal.gravity = g; //set the projectile's gravity (this is here to avoid conflicts with changes in the gravity property of the projectile, which becomes useless)
			bal.bNOGRAVITY = false; //set the gravity, in case the projectile doesn't have it
			if(veladjust) //if the velocity needs to be adjusted
				bal.Vel3DFromAngle(v, bal.angle, -p); //set the correct velocity
		}
	}
Of course, you might say, you're not accounting for those!, but unfortunately my physics knowledge on the topic ends here and I cannot find a solution anywhere D:

if someone could explain to me how to achieve that or if you know some example, that would be really appreciated!
Kan3x
Posts: 67
Joined: Tue Nov 08, 2022 4:19 pm

Re: [SOLVED][ZSCRIPT]Parabolic Trajectory for Projectiles Function Help

Post by Kan3x »

I've been able to solve the dilemma by making a better use of the maximum shooting pitch and using both the results I get from the pitch equation.
I'm leaving the complete function here:
Spoiler:
Post Reply

Return to “Scripting”