Projectile AI (Demon Scythe)

In this tutorial, I will be covering the AI used by the Demon Scythe AI. If you don’t know, Demon Scythe is a spell that creates a scythe at the position of the player and then it increases in speed and flies in the direction it was set.

Animation shows the Demon Scythe in action.
Image from https://terraria.gamepedia.com/Demon_Scythe

The code below is a modified version of the Demon Scythe used in our Arcana Mod Pack’s Book of Flames. Which spawns a blade of fire that acts similar to the Demon Scythe.

public override void AI() {
	if(projectile.ai[1] == 0f) {
		projectile.ai[1] = 1f;
		Main.PlaySound(SoundID.Item8, projectile.position);
	}
	projectile.rotation += (float)projectile.direction *= 0.95f;
	projectile.ai[0] += 1f;
	if(projectile.ai[0] >= 30f) {
		if(projectile.ai[0] < 100f) {
			projectile.velocity *= 1.1f;
		} else {
			projectile.ai[0] = 200f;
		}
	}
	for(int i = 0; i < 2; i++) {
		Vector2 pos = projectile.position;
		int w = projectile.width;
		int h = projectile.height;
		Color col = default(Color);
		int dust = Dust.NewDust(pos, w, h, mod.DustType(""), 0f, 0f, projectile.alpha, col, 1f);
	}
}

Let’s start by looking at the first if statement that utilises the AI value of 1.

if(projectile.ai[1] == 0f) {
	projectile.ai[1] = 1f;
	Main.PlaySound(SoundID.Item8, projectile.position);
}

By default, the AI settings are all set to 0f unless set elsewhere. In this case when the AI value of [1] is equal to 0f, then we set the AI value of [1] to 1f then we play a sound. So as soon as the AI starts, it should make the sound and only make the sound once.

Now let’s take a look at the next portion of the code which looks at the rotation of the projectile.

projectile.rotation += (float)projectile.direction * 0.95f;

The way this works is we are increasing the current rotation of the projectile by the direction it is facing multiplied by a value to affect the rotation speed.

We now want to take look at moving the projectile and increasing the speed of the projectile gradually.

projectile.ai[0] += 1f;
if(projectile.ai[0] >= 30f) {
	if(projectile.ai[0] < 100f) {
		projectile.velocity *= 1.1f;
	} else {
		projectile.ai[0] = 200f;
	}
}

The first line in this piece is increasing the AI value. Once it is greater than or equal to 30, we have some events happening. While the AI value is below 100, the velocity is multiplied by 1.1 which means that the projectile will get faster and faster. As soon as the AI value is equal to or greater than 100, then the AI value is set to 200 meaning that no more movement code is done.

This final part looks at the dust for the projectile and how it is generated.

for(int i = 0; i < 2; i++){
	Vector2 pos = projectile.position;
	int w = projectile.width;
	int h = projectile.height;
	Color col = default(Color);
	int dust = Dust.NewDust(pos, w, h, mod.DustType(""), 0f, 0f, projectile.alpha, col, 1f);
}

What we are doing here is creating a for loop that creates 2 dust particles every cycle of AI. We first set the position equal to the projectile’s current position.

We also get the width and height of the projectile (even those we do no modify this, it is just easier to make an easy way to get width and height).

We then have the colour of the dust we are creating, by default this is a value of 255, 255, 255 which is White.

The final part is creating the dust particle. In this case we pass in the projectile position vector, width, height, then the ID of the dust particle. We set speedX and speedY to 0 as we have our own AI in dust. We pass in the projectile’s alpha as well which is set in the SetDefaults section. We then pass in the colour of the dust. Finally we have the Scale of the dust which we set to a scale of 1.

You can modify the code to change the way the AI acts. Want to move faster, change the velocity. Want to decide how fast the projectile rotates, change that value.

Leave a Reply

Your email address will not be published. Required fields are marked *