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
). 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
Code: Select all
Game {
/// <summary>
/// Gets all current projectiles.
/// </summary>
public abstract IProjectile[] GetProjectiles();
/// <summary>
/// Gets the projectile with the specified projectile instanceID.
/// </summary>
/// <param name="projectileInstanceID">Projectile instance ID</param>
public abstract IProjectile GetProjectile(int projectileInstanceID);
}
[Serializable()]
public struct ProjectileProperties
{
/// <summary>
/// Gets the projectile item ID of this projectile.
/// </summary>
public readonly ProjectileItem ProjectileItem;
/// <summary>
/// Gets the initial speed in world units per second that will decide the velocity vector for the projectile.
/// The velocity is reduced if the projectile bounces.
/// </summary>
public readonly float InitialSpeed;
/// <summary>
/// Gets the damage done to players.
/// </summary>
public readonly float PlayerDamage;
/// <summary>
/// Gets the damage done to objects.
/// </summary>
public readonly float ObjectDamage;
/// <summary>
/// Gets the critical hit chance.
/// </summary>
public readonly float CritChance;
/// <summary>
/// Gets the critical damage.
/// </summary>
public readonly float CritDamage;
/// <summary>
/// Gets the dodge chance for this projectile while diving/rolling. Range [0 - 1]
/// </summary>
public readonly float DodgeChance;
/// <summary>
/// Gets if the projectile can be blocked at all from player melee weapons.
/// </summary>
public readonly bool CanBeBlocked;
}
/// <summary>
/// Access to certain information and functions about a projectile.
/// </summary>
public abstract class IProjectile
{
/**@{*/
/// <summary>
/// Gets the projectile item ID of this projectile.
/// </summary>
public abstract ProjectileItem ProjectileItem { get; }
/// <summary>
/// Gets the instance ID of this projectile.
/// </summary>
public abstract int InstanceID { get; }
/// <summary>
/// Gets the projectile's current owner player uniqueID. This is reset when the projectile bounces or is deflected.
/// </summary>
public abstract int OwnerPlayerID { get; }
/// <summary>
/// Gets the projectile's initial owner player uniqueID.
/// </summary>
public abstract int InitialOwnerPlayerID { get; }
/**@}*/
/**@{*/
/// <summary>
/// Gets or Sets the current position of the projectile.
/// </summary>
public abstract Vector2 Position { get; set; }
/// <summary>
/// Gets or Sets the current direction of the projectile.
/// </summary>
public abstract Vector2 Direction { get; set; }
/// <summary>
/// Gets or Sets the current velocity that the projectile covers each second.
/// Note: Sync over server-client assumes the velocity stays intact and changing this each update can make it look janky on clients.
/// Note: You can not set a velocity greater than the max speed of the projectile and not set a velocity less than 100 in magnitude.
/// </summary>
public abstract Vector2 Velocity { get; set; }
/**@}*/
/**@{*/
/// <summary>
/// Gets the total distance the projectile has traveled.
/// </summary>
public abstract float TotalDistanceTraveled { get; }
/**@}*/
/**@{*/
/// <summary>
/// Gets different properties for the projectile.
/// </summary>
public abstract ProjectileProperties GetProperties();
/**@}*/
/**@{*/
/// <summary>
/// Gets number of reflections/bounces this projectile has performed.
/// </summary>
public abstract int BounceCount { get; }
/// <summary>
/// Gets or Sets if the projectile has the bounce powerup attribute active.
/// </summary>
public abstract bool PowerupBounceActive { get; set; }
/// <summary>
/// Gets or Sets if the projectile has the fire powerup attribute active.
/// </summary>
public abstract bool PowerupFireActive { get; set; }
/// <summary>
/// Gets or Sets damage modifier for the projectile. Defaults to 1 and is set from player modifiers when shot from a player.
/// </summary>
public abstract float DamageDealtModifier { get; set; }
/// <summary>
/// Gets or Sets crit chance modifier for the projectile. Defaults to 1 and is set from player modifiers when shot from a player.
/// </summary>
public abstract float CritChanceDealtModifier { get; set; }
/**@}*/
/**@{*/
/// <summary>
/// Flags the projectile to be removed the next update cycle.
/// </summary>
public abstract void FlagForRemoval();
/**@}*/
/**@{*/
/// <summary>
/// Gets is this projectile is removed from the game and no longer active.
/// </summary>
public abstract bool IsRemoved { get; }
/**@}*/
}