Finished Skeleton NPC.
Finished Necro Caster.
This commit is contained in:
parent
ccf993c077
commit
b3585374fe
@ -33,8 +33,8 @@ namespace Decimation.Content.NPCs
|
|||||||
npc.buffImmune[BuffID.ShadowFlame] = true;
|
npc.buffImmune[BuffID.ShadowFlame] = true;
|
||||||
npc.value = 10000;
|
npc.value = 10000;
|
||||||
npc.damage = 15;
|
npc.damage = 15;
|
||||||
npc.HitSound = SoundID.NPCHit1;
|
npc.HitSound = SoundID.DD2_SkeletonHurt;
|
||||||
npc.DeathSound = SoundID.NPCDeath1;
|
npc.DeathSound = SoundID.DD2_SkeletonDeath;
|
||||||
|
|
||||||
animationType = NPCID.Necromancer;
|
animationType = NPCID.Necromancer;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,64 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Decimation.Lib.Items;
|
||||||
using System;
|
using Decimation.Lib.Util;
|
||||||
using System.IO;
|
using Microsoft.Xna.Framework;
|
||||||
using Decimation.Content.Items.Weapons;
|
|
||||||
using Decimation.Lib.Items;
|
|
||||||
using Terraria;
|
using Terraria;
|
||||||
using Terraria.ID;
|
using Terraria.ID;
|
||||||
using Terraria.ModLoader;
|
|
||||||
|
|
||||||
namespace Decimation.Content.Projectiles
|
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()
|
protected override void Init()
|
||||||
{
|
{
|
||||||
@ -23,76 +70,112 @@ namespace Decimation.Content.Projectiles
|
|||||||
DamageType = DecimationWeapon.DamageType.Ranged;
|
DamageType = DecimationWeapon.DamageType.Ranged;
|
||||||
projectile.hostile = true;
|
projectile.hostile = true;
|
||||||
projectile.friendly = false;
|
projectile.friendly = false;
|
||||||
projectile.penetrate = 2;
|
projectile.penetrate = -1;
|
||||||
projectile.timeLeft = 60;
|
projectile.hostile = false;
|
||||||
|
projectile.friendly = false;
|
||||||
|
projectile.timeLeft = 600;
|
||||||
Damages = Main.expertMode ? 57 : 20;
|
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()
|
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]++;
|
Counter = 0;
|
||||||
projectile.timeLeft = 600;
|
State = AiState.Targeting;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
projectile.velocity = velocity;
|
Counter++;
|
||||||
projectile.ai[1]++;
|
}
|
||||||
|
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);
|
DustUtils.NewDustCircle(8, projectile.position, projectile.width, projectile.height, DustID.Blood,
|
||||||
}
|
projectile.scale * 2f);
|
||||||
|
|
||||||
public override void ReceiveExtraAI(BinaryReader reader)
|
|
||||||
{
|
|
||||||
counter = reader.ReadInt32();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnHitPlayer(Player target, int damage, bool crit)
|
public override void OnHitPlayer(Player target, int damage, bool crit)
|
||||||
{
|
{
|
||||||
if (Main.expertMode && Main.rand.Next(100) < 35) target.AddBuff(BuffID.Confused, 600);
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,6 +104,20 @@ namespace Decimation.Content.Projectiles
|
|||||||
{
|
{
|
||||||
FindTarget();
|
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;
|
State = AiState.Attacking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,23 +125,16 @@ namespace Decimation.Content.Projectiles
|
|||||||
}
|
}
|
||||||
else if (State == AiState.Attacking)
|
else if (State == AiState.Attacking)
|
||||||
{
|
{
|
||||||
if (Target >= 255)
|
if (TargetNPC == null || !TargetNPC.active)
|
||||||
{
|
{
|
||||||
projectile.Kill();
|
projectile.Kill();
|
||||||
return;
|
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);
|
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;
|
Main.dust[dust].noGravity = true;
|
||||||
Lighting.AddLight(projectile.Center, LightingUtils.Rgb255ToRgb1(143, 214, 255));
|
Lighting.AddLight(projectile.Center, LightingUtils.Rgb255ToRgb1(143, 214, 255));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user