A projectile "script" class can modify a projectile while in flight. This system is inspired by Unity's script system. Look at ProjectileScript.java for a better idea.
To use scripts, you must do 2 things:
Create a ProjectileScriptManager.
Attach scripts to projectiles.
Let's take a closer look at how WeaponMechanicsCosmetics adds particles to falling blocks:
Creating a Projectile Script
public class FallingBlockScript extends ProjectileScript<AProjectile> {
private Object data; // either BlockData (1.13+) or MaterialData (1.12-)
public FallingBlockScript(@NotNull Plugin owner, @NotNull AProjectile projectile) {
super(owner, projectile);
if (projectile.getDisguise() == null || projectile.getDisguise().getType() != EntityType.FALLING_BLOCK)
throw new IllegalArgumentException("Tried to attach to " + projectile + " when it doesn't have falling block");
data = projectile.getDisguise().getData();
}
@Override
public void onTickEnd() {
Configuration config = WeaponMechanicsCosmetics.getInstance().getConfiguration();
int amount = config.getInt("Explosion_Effects.Falling_Block_Dust.Amount");
double spread = config.getDouble("Explosion_Effects.Falling_Block_Dust.Spread");
if (amount != 0) {
World world = projectile.getWorld();
Location location = projectile.getLocation().toLocation(world);
world.spawnParticle(Particle.FALLING_DUST, location, amount, spread, spread, spread, data);
}
}
}
This script will spawn a dust particle every tick on the projectile's location.
Projectile Script Manager
public class CosmeticsScriptManager extends ProjectileScriptManager {
public CosmeticsScriptManager(Plugin plugin) {
super(plugin);
}
@Override
public void attach(@NotNull AProjectile aProjectile) {
if (aProjectile.getIntTag("explosion-falling-block") == 1) {
FallingBlockScript script = new FallingBlockScript(getPlugin(), aProjectile);
aProjectile.addProjectileScript(script);
return;
}
// snip... other WMC stuff is below this, we use 1 manager to attach all scripts
}
}
This manager will attach the falling block script to all projectiles marked with the explosion-falling-block tag.
This code will inject your script manager, and begin listening for newly spawned projectiles! But wait, after someone runs /wm reload, your script will be gone! So instead of running this onEnable(), we should be running it after WeaponMechanics reloads config.
So use the following listener:
@EventHandler
public void queueSerializers(QueueSerializerEvent event) {
if (!event.getSourceName().equals("WeaponMechanics"))
return;
WeaponMechanics.getProjectilesRunnable().addScriptManager(new CosmeticsScriptManager(plugin));
}