Dear forum users! In compliance with the new European GDPR regulations, we'd just like to inform you that if you have an account, your email address is stored in our database. We do not share your information with third parties, and your email address and password are encrypted for security reasons.

New to the forum? Say hello in this topic! Also make sure to read the rules.

Scripting 08 - Projectile manipulation

A smaller forum with a few tutorials how to get started with the ScriptAPI.
Forum rules
By using the forum you agree to the following rules.
Post Reply
User avatar
Gurt
Lead Programmer
Lead Programmer
Posts: 1884
Joined: Sun Feb 28, 2016 3:22 pm
Title: Lead programmer
Started SFD: Made it!
Location: Sweden
Gender:
Age: 34

Scripting 08 - Projectile manipulation

Post by Gurt » Fri Jul 26, 2019 12:20 pm

Scripting 08 - Projectile manipulation

Scripting in SFD assumes you have a fair knowledge of C#.

The following code demonstrates how to manipulate projectiles and listen on projectile hit events in v.1.3.0 (OnProjectileCreated event in v.1.3.1).

Code: Select all

// Example script to manipulate projectiles
public void OnStartup()
{
	Events.UpdateCallback.Start(OnUpdate, 0);
	Events.ProjectileCreatedCallback.Start(OnProjectileCreated);
	Events.ProjectileHitCallback.Start(OnProjectileHit);
}

public void OnProjectileCreated(IProjectile[] projectiles)
{
	// Created projectiles, not yet run their first update cycle.
	foreach(IProjectile projectile in projectiles) {
		Game.WriteToConsole(string.Format("Projectile {0} created", projectile.InstanceID));
	}
}

public void OnProjectileHit(IProjectile projectile, ProjectileHitArgs args)
{
	Game.WriteToConsole(string.Format("Projectile {0} hit {1} {2} for {3} damage", projectile.InstanceID, (args.IsPlayer ? "player" : "object"), args.HitObjectID, args.Damage));

}

public void OnUpdate(float ms)
{	
	foreach (IProjectile proj in Game.GetProjectiles())
	{
		// lower velocity for bazooka rockets to 300
		if (proj.ProjectileItem == ProjectileItem.BAZOOKA) 
		{
			if (proj.Velocity.Length() > 301f)
			{
				proj.Velocity = proj.Direction * 300f;
			}
		}
		// shotguns can only reach 200 world units
		if (proj.ProjectileItem == ProjectileItem.SHOTGUN || proj.ProjectileItem == ProjectileItem.DARK_SHOTGUN)
		{
			if (proj.TotalDistanceTraveled > 200f) 
			{
				proj.FlagForRemoval();
			}
		}
		
		// pistols rounds affected by gravity
		if (proj.ProjectileItem == ProjectileItem.PISTOL) 
		{
			proj.Velocity = new Vector2(proj.Velocity.X, proj.Velocity.Y - 0.3f * ms);
		}

	}
}

You can do all kinds of interesting things with projectiles. But changing position and velocity too often and too suddenly can make the projectiles look jittery and buggy on clients if the client have a fluctuating ping (which makes the client-side prediction fail - it can't predict what you want to do in your code :P). It's just how it is. Keep that in mind when testing your code in the editor vs a public game.

Note: If you only want to listen on player damage you could use the PlayerDamageCallback event instead. See viewtopic.php?f=22&t=3771

IProjectile Implementation
► Show Spoiler
2 x
Gurt

NearHuscarl
Superfighter
Superfighter
Posts: 97
Joined: Thu Feb 07, 2019 4:36 am

Post by NearHuscarl » Fri Jul 26, 2019 1:43 pm

Does IProjectile have the ID of the player who shot it? I want to know if player B is shot by player A, but it can't be implemented cleanly with the current version of the script API
0 x
Image

User avatar
Gurt
Lead Programmer
Lead Programmer
Posts: 1884
Joined: Sun Feb 28, 2016 3:22 pm
Title: Lead programmer
Started SFD: Made it!
Location: Sweden
Gender:
Age: 34

Post by Gurt » Fri Jul 26, 2019 2:30 pm

NearHuscarl wrote:
Fri Jul 26, 2019 1:43 pm
Does IProjectile have the ID of the player who shot it? I want to know if player B is shot by player A, but it can't be implemented cleanly with the current version of the script API
You have the properties for initialOwnerPlayerID and ownerPlayerID. The initialOwnerPlayerID is the original owner of the projectile while ownerPlayerID is updated with each bounce/deflection of the projectile.

You will have to refer to the full ScriptAPI after the update is released for more details.
1 x
Gurt

User avatar
Danger Ross
Superfighter
Superfighter
Posts: 154
Joined: Thu Mar 31, 2016 12:56 am
Title: Dangerous
SFD Alias: Danger Ross
Started SFD: 14 june 2012 (launch day)
Location: California
Gender:
Age: 23

Post by Danger Ross » Fri Aug 02, 2019 8:32 am

Very cool update!

but is there any way to detect whether or not the projectile hit callback event is of the projectile hitting an object that stops it?
As in, a way to filter detection of objects that the projectile ignores in its trajectory.
I'm asking this because I want the projectile to leave behind something after being removed, but it's uncertain when that will happen when relying on the event call.

also a small suggestion: could you make the Game.SpawnProjectile() method return an IProjectile object instead of void? thanks!
0 x
sorry bucko, you can't punch with swords 8-)

User avatar
Gurt
Lead Programmer
Lead Programmer
Posts: 1884
Joined: Sun Feb 28, 2016 3:22 pm
Title: Lead programmer
Started SFD: Made it!
Location: Sweden
Gender:
Age: 34

Post by Gurt » Fri Aug 02, 2019 12:15 pm

Good suggestions. Adding it after v.1.3.0b.
ScriptAPI: Updated IGame.SpawnProjectile(). It now returns the created IProjectile instance (can return null).
ScriptAPI: Updated ProjectileHitArgs with new property bool RemoveFlag to determine if the projectile is going to be removed by the hit or not.
0 x
Gurt

Post Reply