Finished Skeleton NPC.

Finished Necro Caster.
This commit is contained in:
FyloZ 2020-07-11 13:50:40 -04:00
parent ccf993c077
commit b3585374fe
3 changed files with 161 additions and 71 deletions

View File

@ -33,8 +33,8 @@ namespace Decimation.Content.NPCs
npc.buffImmune[BuffID.ShadowFlame] = true;
npc.value = 10000;
npc.damage = 15;
npc.HitSound = SoundID.NPCHit1;
npc.DeathSound = SoundID.NPCDeath1;
npc.HitSound = SoundID.DD2_SkeletonHurt;
npc.DeathSound = SoundID.DD2_SkeletonDeath;
animationType = NPCID.Necromancer;
}

View File

@ -1,17 +1,64 @@
using Microsoft.Xna.Framework;
using System;
using System.IO;
using Decimation.Content.Items.Weapons;
using Decimation.Lib.Items;
using Decimation.Lib.Items;
using Decimation.Lib.Util;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace Decimation.Content.Projectiles
{
internal class Bone : DecimationProjectile
internal class Bone : DecimationProjectile
{
private float maxSpeed = 5f;
private const int IdlingCounterMax = 60;
private const int TargetingCounterMax = 90;
private const float IdlingVelocity = 5f;
private const float AttackingVelocity = 10f;
private AiState State
{
get
{
{
switch ((int) projectile.ai[0])
{
case 0: return AiState.Idling;
case 1: return AiState.Targeting;
default: return AiState.Attacking;
}
}
}
set
{
int state;
switch (value)
{
case AiState.Idling:
state = 0;
break;
case AiState.Targeting:
state = 1;
break;
default:
state = 2;
break;
}
projectile.ai[0] = state;
}
}
private int Counter
{
get => (int) projectile.ai[1];
set => projectile.ai[1] = value;
}
private int Target
{
get => (int) projectile.localAI[0];
set => projectile.localAI[0] = value;
}
private Player TargetPlayer => Main.player[Target];
protected override void Init()
{
@ -23,76 +70,112 @@ namespace Decimation.Content.Projectiles
DamageType = DecimationWeapon.DamageType.Ranged;
projectile.hostile = true;
projectile.friendly = false;
projectile.penetrate = 2;
projectile.timeLeft = 60;
projectile.penetrate = -1;
projectile.hostile = false;
projectile.friendly = false;
projectile.timeLeft = 600;
Damages = Main.expertMode ? 57 : 20;
projectile.localAI[0] = 15;
Target = 255;
}
// ai 0: target, ai 1: state, localAI 0: rotation
private int counter = 0;
public override void AI()
{
if (projectile.ai[1] == 0)
if (State == AiState.Idling)
{
projectile.localAI[0] = 15;
projectile.rotation += MathHelper.Pi * (1 / 64f);
projectile.velocity.Normalize();
projectile.velocity *= IdlingVelocity;
if (projectile.timeLeft < 10)
if (Counter > IdlingCounterMax)
{
projectile.ai[1]++;
projectile.timeLeft = 600;
projectile.velocity *= 0;
}
}
else if (projectile.ai[1] == 1)
{
if (Main.netMode != 1)
counter++;
projectile.localAI[0] += 4;
if (counter >= 60)
{
projectile.ai[1]++;
counter = 0;
}
}
else if (projectile.ai[1] == 2)
{
Player target = Main.player[(int)projectile.ai[0]];
Vector2 velocity = target.position - projectile.position;
float magnitude = (float)Math.Sqrt(velocity.X * velocity.X + velocity.Y * velocity.Y);
if (magnitude > maxSpeed)
{
float ratio = maxSpeed / magnitude;
velocity.X *= ratio;
velocity.Y *= ratio;
Counter = 0;
State = AiState.Targeting;
}
projectile.velocity = velocity;
projectile.ai[1]++;
Counter++;
}
else if (State == AiState.Targeting)
{
projectile.velocity *= 0f;
projectile.rotation += MathHelper.Pi * (1 / 64f) * (1 + Counter / 10);
if (Counter > TargetingCounterMax)
{
FindTarget();
if (TargetPlayer == null || !TargetPlayer.active || TargetPlayer.dead)
{
projectile.Kill();
return;
}
Vector2 velocity = TargetPlayer.Center - projectile.Center;
velocity.Normalize();
velocity *= AttackingVelocity;
projectile.hostile = true;
projectile.velocity = velocity;
projectile.penetrate = 1;
State = AiState.Attacking;
}
Counter++;
}
else if (State == AiState.Attacking)
{
if (TargetPlayer == null || !TargetPlayer.active || TargetPlayer.dead)
{
projectile.Kill();
return;
}
projectile.rotation += MathHelper.Pi * (1 / 64f) * (1 + Counter / 10);
}
projectile.rotation += (float)(Math.PI / projectile.localAI[0]);
int dust = Dust.NewDust(projectile.position, projectile.width, projectile.height, DustID.Blood);
Main.dust[dust].noGravity = true;
Lighting.AddLight(projectile.Center, LightingUtils.Rgb255ToRgb1(158, 6, 6));
}
public override void SendExtraAI(BinaryWriter writer)
public override void Kill(int timeLeft)
{
writer.Write(counter);
}
public override void ReceiveExtraAI(BinaryReader reader)
{
counter = reader.ReadInt32();
DustUtils.NewDustCircle(8, projectile.position, projectile.width, projectile.height, DustID.Blood,
projectile.scale * 2f);
}
public override void OnHitPlayer(Player target, int damage, bool crit)
{
if (Main.expertMode && Main.rand.Next(100) < 35) target.AddBuff(BuffID.Confused, 600);
}
private void FindTarget()
{
if (Target >= 255)
{
float lastDistance = float.MaxValue;
for (int i = 0; i < Main.player.Length; i++)
{
Player player = Main.player[i];
if (player != null && player.active && !player.dead)
{
float distance = projectile.Distance(player.Center);
if (distance < lastDistance)
{
lastDistance = distance;
Target = i;
}
}
}
}
}
private enum AiState
{
Idling = 0,
Targeting = 1,
Attacking = 2
}
}
}
}

View File

@ -103,6 +103,20 @@ namespace Decimation.Content.Projectiles
if (Counter > TargetingCounterMax)
{
FindTarget();
if (TargetNPC == null || !TargetNPC.active)
{
projectile.Kill();
return;
}
Vector2 velocity = TargetNPC.Center - projectile.Center;
velocity.Normalize();
velocity *= AttackingVelocity;
projectile.friendly = true;
projectile.penetrate = 1;
projectile.velocity = velocity;
State = AiState.Attacking;
}
@ -111,23 +125,16 @@ namespace Decimation.Content.Projectiles
}
else if (State == AiState.Attacking)
{
if (Target >= 255)
if (TargetNPC == null || !TargetNPC.active)
{
projectile.Kill();
return;
}
Vector2 velocity = TargetNPC.Center - projectile.Center;
velocity.Normalize();
velocity *= AttackingVelocity;
projectile.friendly = true;
projectile.penetrate = 1;
projectile.velocity = velocity;
projectile.rotation += MathHelper.Pi * (1 / 64f) * (1 + Counter / 10);
}
int dust = Dust.NewDust(projectile.position, projectile.width, projectile.height, 125);
int dust = Dust.NewDust(projectile.position, projectile.width, projectile.height, 135);
Main.dust[dust].noGravity = true;
Lighting.AddLight(projectile.Center, LightingUtils.Rgb255ToRgb1(143, 214, 255));
}