Added new Dune Wyrm and Ancient Tomb Crawler sprites.

Added debug tools.
This commit is contained in:
FyloZ 2020-06-05 12:42:17 -04:00
parent 9c23e3284f
commit 16b387b796
40 changed files with 618 additions and 786 deletions

36
Content/Debug/DebugAI.cs Normal file
View File

@ -0,0 +1,36 @@
using Decimation.Lib.Items;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace Decimation.Content.Debug
{
public class DebugAIItem : DecimationItem
{
public override string Texture => "Terraria/Item_" + ItemID.Star;
protected override string ItemName => "Debug AI";
protected override void Init()
{
}
public override bool UseItem(Player player)
{
DebugAI.debugging = !DebugAI.debugging;
return true;
}
}
class DebugAI : GlobalNPC
{
public static bool debugging;
public override bool PreAI(NPC npc)
{
if (debugging) return false;
return base.PreAI(npc);
}
}
}

View File

@ -0,0 +1,38 @@
using Decimation.Lib.Items;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace Decimation.Content.Debug
{
public class DebugHitboxItem : DecimationItem
{
public override string Texture => "Terraria/Item_" + ItemID.Acorn;
protected override string ItemName => "Debug Hitbox";
protected override void Init()
{
}
public override bool UseItem(Player player)
{
DebugHitbox.debugging = !DebugHitbox.debugging;
return true;
}
}
internal class DebugHitbox : GlobalNPC
{
public static bool debugging;
public override bool PreDraw(NPC npc, SpriteBatch spriteBatch, Color drawColor)
{
if (debugging) npc.DrawDebugHitbox(spriteBatch);
return base.PreDraw(npc, spriteBatch, drawColor);
}
}
}

View File

@ -0,0 +1,17 @@
using Decimation.Lib.Items;
using Terraria.ID;
namespace Decimation.Content.Debug
{
public class DebugSword : DecimationWeapon
{
public override string Texture => "Terraria/Item_" + ItemID.CopperShortsword;
protected override string ItemName => "Debug Sword";
protected override int Damages => 9999999;
protected override void InitWeapon()
{
item.CloneDefaults(ItemID.CopperShortsword);
}
}
}

View File

@ -0,0 +1,25 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
namespace Decimation.Content.Debug
{
public static class DebugUtils
{
public static void DrawDebugHitbox(this NPC npc, SpriteBatch spriteBatch)
{
Texture2D debugTexture = Decimation.Instance.GetTexture("Content/Debug/pixel");
spriteBatch.Draw(
debugTexture,
new Rectangle(
(int) (npc.position.X - Main.screenPosition.X),
(int) (npc.position.Y - Main.screenPosition.Y),
(int) (npc.width * npc.scale),
(int) (npc.height * npc.scale)
),
new Color(255, 0, 0, 20)
);
}
}
}

BIN
Content/Debug/pixel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 B

View File

@ -1,15 +1,15 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using Decimation.Content.NPCs.Arachnus;
using Decimation.Content.NPCs.DuneWyrm;
using Decimation.Content.UI;
using Decimation.Lib.Util;
using Microsoft.Xna.Framework;
using Terraria; using Terraria;
using Terraria.ID; using Terraria.ID;
using Terraria.ModLoader; using Terraria.ModLoader;
using Decimation.Content.NPCs.Arachnus;
using Decimation.Content.NPCs.AncientDuneWorm;
using Decimation.Content.UI;
using System.Collections.Generic;
using Decimation.Lib.Util;
using Terraria.UI; using Terraria.UI;
using Microsoft.Xna.Framework;
namespace Decimation.Content namespace Decimation.Content
{ {
@ -93,9 +93,12 @@ namespace Decimation.Content
Mod bossChecklist = ModLoader.GetMod("BossChecklist"); Mod bossChecklist = ModLoader.GetMod("BossChecklist");
if (bossChecklist != null) if (bossChecklist != null)
{ {
bossChecklist.Call("AddBossWithInfo", "The Bloodshot Eye", 2.5f, (Func<bool>)(() => DecimationWorld.downedBloodshotEye), "INSERT LATER"); bossChecklist.Call("AddBossWithInfo", "The Bloodshot Eye", 2.5f,
bossChecklist.Call("AddBossWithInfo", "The Ancient Dune Worm", 5.7f, (Func<bool>)(() => DecimationWorld.downedDuneWorm), "INSERT LATER"); (Func<bool>) (() => DecimationWorld.downedBloodshotEye), "INSERT LATER");
bossChecklist.Call("AddBossWithInfo", "Arachnus", 20f, (Func<bool>)(() => DecimationWorld.downedArachnus), "INSERT LATER"); bossChecklist.Call("AddBossWithInfo", "The Ancient Dune Worm", 5.7f,
(Func<bool>) (() => DecimationWorld.downedDuneWorm), "INSERT LATER");
bossChecklist.Call("AddBossWithInfo", "Arachnus", 20f,
(Func<bool>) (() => DecimationWorld.downedArachnus), "INSERT LATER");
} }
} }
@ -134,14 +137,16 @@ namespace Decimation.Content
{ {
arachnus.HandlePacket(reader); arachnus.HandlePacket(reader);
} }
break; break;
case DecimationModMessageType.DuneWorm: case DecimationModMessageType.DuneWorm:
AncientDuneWormHead duneWorm = (AncientDuneWormHead)Main.npc[reader.ReadInt32()].modNPC; DuneWyrmHead duneWyrm = (DuneWyrmHead) Main.npc[reader.ReadInt32()].modNPC;
if (duneWorm != null && duneWorm.npc.active) if (duneWyrm != null && duneWyrm.npc.active)
{ {
// TODO multiplayer // TODO multiplayer
//duneWorm.HandlePacket(reader); // duneWyrm.HandlePacket(reader);
} }
break; break;
case DecimationModMessageType.SpawnBoss: case DecimationModMessageType.SpawnBoss:
int type = reader.ReadInt32(); int type = reader.ReadInt32();

View File

@ -1,5 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using Decimation.Content.NPCs.AncientDuneWorm; using Decimation.Content.NPCs.DuneWyrm;
using Decimation.Lib.Items; using Decimation.Lib.Items;
using Terraria; using Terraria;
using Terraria.ID; using Terraria.ID;
@ -32,13 +32,13 @@ namespace Decimation.Content.Items.Boss.DuneWorm
if (Main.netMode == 0) if (Main.netMode == 0)
{ {
Main.PlaySound(15, (int) player.position.X, (int) player.position.Y, 0); Main.PlaySound(15, (int) player.position.X, (int) player.position.Y, 0);
NPC.SpawnOnPlayer(player.whoAmI, ModContent.NPCType<AncientDuneWormHead>()); NPC.SpawnOnPlayer(player.whoAmI, ModContent.NPCType<DuneWyrmHead>());
return true; return true;
} }
ModPacket packet = this.mod.GetPacket(); ModPacket packet = this.mod.GetPacket();
packet.Write((byte) DecimationModMessageType.SpawnBoss); packet.Write((byte) DecimationModMessageType.SpawnBoss);
packet.Write(ModContent.NPCType<AncientDuneWormHead>()); packet.Write(ModContent.NPCType<DuneWyrmHead>());
packet.Write(player.whoAmI); packet.Write(player.whoAmI);
packet.Send(); packet.Send();
} }

View File

@ -2,7 +2,7 @@ using Decimation.Content.Items.Misc.Souls;
using Decimation.Content.Items.Placeable.DuneWorm; using Decimation.Content.Items.Placeable.DuneWorm;
using Decimation.Content.Items.Tools; using Decimation.Content.Items.Tools;
using Decimation.Content.Items.Vanity.DuneWorm; using Decimation.Content.Items.Vanity.DuneWorm;
using Decimation.Content.NPCs.AncientDuneWorm; using Decimation.Content.NPCs.DuneWyrm;
using Decimation.Lib.Items; using Decimation.Lib.Items;
using Decimation.Lib.Util; using Decimation.Lib.Util;
using Terraria; using Terraria;
@ -11,11 +11,11 @@ using Terraria.ModLoader;
namespace Decimation.Content.Items.Boss.DuneWorm namespace Decimation.Content.Items.Boss.DuneWorm
{ {
internal class DuneWormTreasureBag : DecimationItem internal class DuneWyrmTreasureBag : DecimationItem
{ {
protected override string ItemName => "Treasure Bag"; protected override string ItemName => "Treasure Bag";
protected override string ItemTooltip => "Right click to open"; protected override string ItemTooltip => "Right click to open";
public override int BossBagNPC => ModContent.NPCType<AncientDuneWormHead>(); public override int BossBagNPC => ModContent.NPCType<DuneWyrmHead>();
protected override void Init() protected override void Init()
{ {
@ -23,8 +23,7 @@ namespace Decimation.Content.Items.Boss.DuneWorm
item.width = 24; item.width = 24;
item.height = 24; item.height = 24;
item.rare = Rarity.Rainbow.GetRarityValue(); item.rare = Rarity.Rainbow.GetRarityValue();
item.expert = true;
this.item.expert = true;
} }
public override bool CanRightClick() public override bool CanRightClick()

View File

Before

Width:  |  Height:  |  Size: 585 B

After

Width:  |  Height:  |  Size: 585 B

View File

@ -12,8 +12,8 @@ namespace Decimation.Content.Items.Placeable.DuneWorm
protected override void InitPlaceable() protected override void InitPlaceable()
{ {
item.width = 30; item.width = 32;
item.height = 30; item.height = 32;
this.item.maxStack = 99; this.item.maxStack = 99;
this.item.value = Item.buyPrice(0, 5); this.item.value = Item.buyPrice(0, 5);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -12,8 +12,8 @@ namespace Decimation.Content.Items.Tools
protected override void InitTool() protected override void InitTool()
{ {
this.item.mana = 50; this.item.mana = 50;
item.width = 22; item.width = 21;
item.height = 36; item.height = 21;
item.useTime = 16; item.useTime = 16;
item.useAnimation = 16; item.useAnimation = 16;
item.useStyle = 4; item.useStyle = 4;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -12,10 +12,10 @@ namespace Decimation.Content.Items.Vanity.DuneWorm
protected override void Init() protected override void Init()
{ {
item.width = 36; item.width = 34;
item.height = 32; item.height = 34;
item.rare = Rarity.Orange.GetRarityValue(); item.rare = Rarity.Orange.GetRarityValue();
this.item.vanity = true; item.vanity = true;
} }
public override bool DrawHead() public override bool DrawHead()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -14,8 +14,8 @@ namespace Decimation.Content.Items.Weapons
protected override void InitWeapon() protected override void InitWeapon()
{ {
item.width = 35; item.width = 32;
item.height = 35; item.height = 32;
item.useTime = 28; item.useTime = 28;
item.useAnimation = 28; item.useAnimation = 28;
item.knockBack = 5; item.knockBack = 5;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -1,93 +0,0 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace Decimation.Content.NPCs
{
public class AncientTombCrawlerBody : ModNPC
{
public override void SetStaticDefaults()
{
this.DisplayName.SetDefault("Ancient Tomb Crawler");
}
public override void SetDefaults()
{
this.npc.scale = 0.7f;
this.npc.width = 62;
this.npc.height = 62;
this.npc.damage = 20;
this.npc.defense = 1;
this.npc.lifeMax = 1;
this.npc.knockBackResist = 0.0f;
this.npc.behindTiles = true;
this.npc.noTileCollide = true;
this.npc.netAlways = true;
this.npc.noGravity = true;
this.npc.dontCountMe = true;
this.npc.HitSound = SoundID.NPCHit1;
}
public override bool PreAI()
{
if (this.npc.ai[3] > 0) this.npc.realLife = (int) this.npc.ai[3];
if (this.npc.target < 0 || this.npc.target == byte.MaxValue || Main.player[this.npc.target].dead)
this.npc.TargetClosest();
if (Main.player[this.npc.target].dead && this.npc.timeLeft > 300) this.npc.timeLeft = 300;
if (Main.netMode != 1)
if (!Main.npc[(int) this.npc.ai[1]].active)
{
this.npc.life = 0;
this.npc.HitEffect();
this.npc.active = false;
NetMessage.SendData(28, -1, -1, null, this.npc.whoAmI, -1f);
}
if (this.npc.ai[1] < (double) Main.npc.Length)
{
// We're getting the center of this NPC.
Vector2 npcCenter = new Vector2(this.npc.position.X + this.npc.width * 0.5f,
this.npc.position.Y + this.npc.height * 0.5f);
// Then using that center, we calculate the direction towards the 'parent NPC' of this NPC.
float dirX = Main.npc[(int) this.npc.ai[1]].position.X + Main.npc[(int) this.npc.ai[1]].width / 2f -
npcCenter.X;
float dirY = Main.npc[(int) this.npc.ai[1]].position.Y + Main.npc[(int) this.npc.ai[1]].height / 2f -
npcCenter.Y;
// We then use Atan2 to get a correct rotation towards that parent NPC.
this.npc.rotation = (float) Math.Atan2(dirY, dirX) + 1.57f;
// We also get the length of the direction vector.
float length = (float) Math.Sqrt(dirX * dirX + dirY * dirY);
// We calculate a new, correct distance.
float dist = (length - this.npc.width) / length;
float posX = dirX * dist;
float posY = dirY * dist;
// Reset the velocity of this NPC, because we don't want it to move on its own
this.npc.velocity = Vector2.Zero;
// And set this NPCs position accordingly to that of this NPCs parent NPC.
this.npc.position.X = this.npc.position.X + posX;
this.npc.position.Y = this.npc.position.Y + posY;
}
return false;
}
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{
Texture2D texture = Main.npcTexture[this.npc.type];
Vector2 origin = new Vector2(texture.Width * 0.5f, texture.Height * 0.5f);
Main.spriteBatch.Draw(texture, this.npc.Center - Main.screenPosition, new Rectangle?(), drawColor,
this.npc.rotation, origin, this.npc.scale, SpriteEffects.None, 0);
return false;
}
public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position)
{
return false; //this make that the npc does not have a health bar
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 810 B

View File

@ -1,319 +0,0 @@
using System;
using Decimation.Content.Items.Misc.Souls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace Decimation.Content.NPCs
{
public class AncientTombCrawlerHead : ModNPC
{
public override void SetStaticDefaults()
{
this.DisplayName.SetDefault("Ancient Tomb Crawler");
}
public override void SetDefaults()
{
this.npc.lifeMax = 2500; //this is the npc health
this.npc.damage = 50; //this is the npc damage
this.npc.defense = 1; //this is the npc defense
this.npc.knockBackResist = 0f;
this.npc.scale = 0.7f;
this.npc.width = 83; //this is where you put the npc sprite width. important
this.npc.height = 83; //this is where you put the npc sprite height. important
this.npc.lavaImmune = true; //this make the npc immune to lava
this.npc.noGravity = true; //this make the npc float
this.npc.noTileCollide = true; //this make the npc go tru walls
this.npc.HitSound = SoundID.NPCHit1;
this.npc.behindTiles = true;
this.npc.DeathSound = SoundID.NPCDeath1;
Main.npcFrameCount[this.npc.type] = 1;
this.npc.value = Item.buyPrice(0, 0, 1);
this.npc.npcSlots = 1f;
this.npc.netAlways = true;
this.npc.boss = true;
}
public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
if (Main.rand.NextBool(20)) target.AddBuff(BuffID.Darkness, 600);
}
public override void OnHitPlayer(Player target, int damage, bool crit)
{
if (Main.rand.NextBool(20)) target.AddBuff(BuffID.Darkness, 600);
}
public override void NPCLoot()
{
Item.NewItem(npc.Center, ModContent.ItemType<SoulofTime>(), Main.rand.Next(5, 11));
}
public override void BossLoot(ref string name, ref int potionType)
{
name = "An Ancient Tomb Crawler";
potionType = ItemID.HealingPotion;
base.BossLoot(ref name, ref potionType);
}
public override bool PreAI()
{
if (Main.netMode != 1)
// So, we start the AI off by checking if npc.ai[0] is 0.
// This is practically ALWAYS the case with a freshly spawned NPC, so this means this is the first update.
// Since this is the first update, we can safely assume we need to spawn the rest of the worm (bodies + tail).
if (this.npc.ai[0] == 0)
{
// So, here we assing the npc.realLife value.
// The npc.realLife value is mainly used to determine which NPC loses life when we hit this NPC.
// We don't want every single piece of the worm to have its own HP pool, so this is a neat way to fix that.
this.npc.realLife = this.npc.whoAmI;
// LatestNPC is going to be used later on and I'll explain it there.
int latestNPC = this.npc.whoAmI;
// Here we determine the length of the worm.
// In this case the worm will have a length of 10 to 14 body parts.
int wormLength = 20;
for (int i = 0; i < wormLength; ++i)
{
// We spawn a new NPC, setting latestNPC to the newer NPC, whilst also using that same variable
// to set the parent of this new NPC. The parent of the new NPC (may it be a tail or body part)
// will determine the movement of this new NPC.
// Under there, we also set the realLife value of the new NPC, because of what is explained above.
latestNPC = NPC.NewNPC((int) this.npc.Center.X, (int) this.npc.Center.Y,
ModContent.NPCType<AncientTombCrawlerBody>(), this.npc.whoAmI, 0, latestNPC);
Main.npc[latestNPC].realLife = this.npc.whoAmI;
Main.npc[latestNPC].ai[3] = this.npc.whoAmI;
}
// When we're out of that loop, we want to 'close' the worm with a tail part!
latestNPC = NPC.NewNPC((int) this.npc.Center.X, (int) this.npc.Center.Y,
ModContent.NPCType<AncientTombCrawlerTail>(), this.npc.whoAmI, 0, latestNPC);
Main.npc[latestNPC].realLife = this.npc.whoAmI;
Main.npc[latestNPC].ai[3] = this.npc.whoAmI;
// We're setting npc.ai[0] to 1, so that this 'if' is not triggered again.
this.npc.ai[0] = 1;
this.npc.netUpdate = true;
}
int minTilePosX = (int) (this.npc.position.X / 16.0) - 1;
int maxTilePosX = (int) ((this.npc.position.X + this.npc.width) / 16.0) + 2;
int minTilePosY = (int) (this.npc.position.Y / 16.0) - 1;
int maxTilePosY = (int) ((this.npc.position.Y + this.npc.height) / 16.0) + 2;
if (minTilePosX < 0)
minTilePosX = 0;
if (maxTilePosX > Main.maxTilesX)
maxTilePosX = Main.maxTilesX;
if (minTilePosY < 0)
minTilePosY = 0;
if (maxTilePosY > Main.maxTilesY)
maxTilePosY = Main.maxTilesY;
bool collision = false;
// This is the initial check for collision with tiles.
for (int i = minTilePosX; i < maxTilePosX; ++i)
for (int j = minTilePosY; j < maxTilePosY; ++j)
if (Main.tile[i, j] != null &&
(Main.tile[i, j].nactive() && (Main.tileSolid[Main.tile[i, j].type] ||
Main.tileSolidTop[Main.tile[i, j].type] &&
Main.tile[i, j].frameY == 0) || Main.tile[i, j].liquid > 64))
{
Vector2 vector2;
vector2.X = i * 16;
vector2.Y = j * 16;
if (this.npc.position.X + this.npc.width > vector2.X && this.npc.position.X < vector2.X + 16.0 &&
this.npc.position.Y + this.npc.height > (double) vector2.Y &&
this.npc.position.Y < vector2.Y + 16.0)
{
collision = true;
if (Main.rand.Next(100) == 0 && Main.tile[i, j].nactive())
WorldGen.KillTile(i, j, true, true);
}
}
// If there is no collision with tiles, we check if the distance between this NPC and its target is too large, so that we can still trigger 'collision'.
if (!collision)
{
Rectangle rectangle1 = new Rectangle((int) this.npc.position.X, (int) this.npc.position.Y,
this.npc.width, this.npc.height);
int maxDistance = 1000;
bool playerCollision = true;
for (int index = 0; index < 255; ++index)
if (Main.player[index].active)
{
Rectangle rectangle2 = new Rectangle((int) Main.player[index].position.X - maxDistance,
(int) Main.player[index].position.Y - maxDistance, maxDistance * 2, maxDistance * 2);
if (rectangle1.Intersects(rectangle2))
{
playerCollision = false;
break;
}
}
if (playerCollision)
collision = true;
}
// speed determines the max speed at which this NPC can move.
// Higher value = faster speed.
float speed = 15f;
// acceleration is exactly what it sounds like. The speed at which this NPC accelerates.
float acceleration = 0.12f;
Vector2 npcCenter = new Vector2(this.npc.position.X + this.npc.width * 0.5f,
this.npc.position.Y + this.npc.height * 0.5f);
float targetXPos = Main.player[this.npc.target].position.X + Main.player[this.npc.target].width / 2f;
float targetYPos = Main.player[this.npc.target].position.Y + Main.player[this.npc.target].height / 2f;
float targetRoundedPosX = (int) (targetXPos / 16.0) * 16;
float targetRoundedPosY = (int) (targetYPos / 16.0) * 16;
npcCenter.X = (int) (npcCenter.X / 16.0) * 16;
npcCenter.Y = (int) (npcCenter.Y / 16.0) * 16;
float dirX = targetRoundedPosX - npcCenter.X;
float dirY = targetRoundedPosY - npcCenter.Y;
float length = (float) Math.Sqrt(dirX * dirX + dirY * dirY);
// If we do not have any type of collision, we want the NPC to fall down and de-accelerate along the X axis.
if (!collision)
{
this.npc.TargetClosest();
this.npc.velocity.Y = this.npc.velocity.Y + 0.11f;
if (this.npc.velocity.Y > speed) this.npc.velocity.Y = speed;
if (Math.Abs(this.npc.velocity.X) + Math.Abs(this.npc.velocity.Y) < speed * 0.4)
{
if (this.npc.velocity.X < 0.0)
this.npc.velocity.X = this.npc.velocity.X - acceleration * 1.1f;
else
this.npc.velocity.X = this.npc.velocity.X + acceleration * 1.1f;
}
else if (this.npc.velocity.Y == speed)
{
if (this.npc.velocity.X < dirX)
this.npc.velocity.X = this.npc.velocity.X + acceleration;
else if (this.npc.velocity.X > dirX) this.npc.velocity.X = this.npc.velocity.X - acceleration;
}
else if (this.npc.velocity.Y > 4.0)
{
if (this.npc.velocity.X < 0.0)
this.npc.velocity.X = this.npc.velocity.X + acceleration * 0.9f;
else
this.npc.velocity.X = this.npc.velocity.X - acceleration * 0.9f;
}
}
// Else we want to play some audio (soundDelay) and move towards our target.
else
{
if (this.npc.soundDelay == 0)
{
this.npc.soundDelay = 120;
Main.PlaySound(this.mod.GetLegacySoundSlot(SoundType.Custom, "Sounds/Custom/Earthquake"),
this.npc.Center);
}
float absDirX = Math.Abs(dirX);
float absDirY = Math.Abs(dirY);
float newSpeed = speed / length;
dirX = dirX * newSpeed;
dirY = dirY * newSpeed;
if (this.npc.velocity.X > 0.0 && dirX > 0.0 || this.npc.velocity.X < 0.0 && dirX < 0.0 ||
this.npc.velocity.Y > 0.0 && dirY > 0.0 || this.npc.velocity.Y < 0.0 && dirY < 0.0)
{
if (this.npc.velocity.X < dirX)
this.npc.velocity.X = this.npc.velocity.X + acceleration;
else if (this.npc.velocity.X > dirX) this.npc.velocity.X = this.npc.velocity.X - acceleration;
if (this.npc.velocity.Y < dirY)
this.npc.velocity.Y = this.npc.velocity.Y + acceleration;
else if (this.npc.velocity.Y > dirY) this.npc.velocity.Y = this.npc.velocity.Y - acceleration;
if (Math.Abs(dirY) < speed * 0.2 &&
(this.npc.velocity.X > 0.0 && dirX < 0.0 || this.npc.velocity.X < 0.0 && dirX > 0.0))
{
if (this.npc.velocity.Y > 0.0)
this.npc.velocity.Y = this.npc.velocity.Y + acceleration * 2f;
else
this.npc.velocity.Y = this.npc.velocity.Y - acceleration * 2f;
}
if (Math.Abs(dirX) < speed * 0.2 &&
(this.npc.velocity.Y > 0.0 && dirY < 0.0 || this.npc.velocity.Y < 0.0 && dirY > 0.0))
{
if (this.npc.velocity.X > 0.0)
this.npc.velocity.X = this.npc.velocity.X + acceleration * 2f;
else
this.npc.velocity.X = this.npc.velocity.X - acceleration * 2f;
}
}
else if (absDirX > absDirY)
{
if (this.npc.velocity.X < dirX)
this.npc.velocity.X = this.npc.velocity.X + acceleration * 1.1f;
else if (this.npc.velocity.X > dirX)
this.npc.velocity.X = this.npc.velocity.X - acceleration * 1.1f;
if (Math.Abs(this.npc.velocity.X) + Math.Abs(this.npc.velocity.Y) < speed * 0.5)
{
if (this.npc.velocity.Y > 0.0)
this.npc.velocity.Y = this.npc.velocity.Y + acceleration;
else
this.npc.velocity.Y = this.npc.velocity.Y - acceleration;
}
}
else
{
if (this.npc.velocity.Y < dirY)
this.npc.velocity.Y = this.npc.velocity.Y + acceleration * 1.1f;
else if (this.npc.velocity.Y > dirY)
this.npc.velocity.Y = this.npc.velocity.Y - acceleration * 1.1f;
if (Math.Abs(this.npc.velocity.X) + Math.Abs(this.npc.velocity.Y) < speed * 0.5)
{
if (this.npc.velocity.X > 0.0)
this.npc.velocity.X = this.npc.velocity.X + acceleration;
else
this.npc.velocity.X = this.npc.velocity.X - acceleration;
}
}
}
// Set the correct rotation for this NPC.
this.npc.rotation = (float) Math.Atan2(this.npc.velocity.Y, this.npc.velocity.X) + 1.57f;
// Some netupdate stuff (multiplayer compatibility).
if (collision)
{
if (this.npc.localAI[0] != 1) this.npc.netUpdate = true;
this.npc.localAI[0] = 1f;
}
else
{
if (this.npc.localAI[0] != 0.0) this.npc.netUpdate = true;
this.npc.localAI[0] = 0.0f;
}
if ((this.npc.velocity.X > 0.0 && this.npc.oldVelocity.X < 0.0 ||
this.npc.velocity.X < 0.0 && this.npc.oldVelocity.X > 0.0 ||
this.npc.velocity.Y > 0.0 && this.npc.oldVelocity.Y < 0.0 ||
this.npc.velocity.Y < 0.0 && this.npc.oldVelocity.Y > 0.0) &&
!this.npc.justHit) this.npc.netUpdate = true;
return false;
}
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{
Texture2D texture = Main.npcTexture[this.npc.type];
Vector2 origin = new Vector2(texture.Width * 0.5f, texture.Height * 0.5f);
Main.spriteBatch.Draw(texture, this.npc.Center - Main.screenPosition, new Rectangle?(), drawColor,
this.npc.rotation, origin, this.npc.scale, SpriteEffects.None, 0);
return false;
}
public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position)
{
scale = 1.9f; //this make the NPC Health Bar biger
return null;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 911 B

View File

@ -1,91 +0,0 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace Decimation.Content.NPCs
{
class AncientTombCrawlerTail : ModNPC
{
public override void SetStaticDefaults()
{
DisplayName.SetDefault("Ancient Tomb Crawler");
}
public override void SetDefaults()
{
npc.scale = 0.7f;
npc.width = 67; //this is where you put the npc sprite width. important
npc.height = 67; //this is where you put the npc sprite height. important
npc.damage = 20;
npc.defense = 1;
npc.lifeMax = 1;
npc.knockBackResist = 0.0f;
npc.behindTiles = true;
npc.noTileCollide = true;
npc.netAlways = true;
npc.noGravity = true;
npc.dontCountMe = true;
npc.HitSound = SoundID.NPCHit1;
}
public override bool PreAI()
{
if (npc.ai[3] > 0)
npc.realLife = (int)npc.ai[3];
if (npc.target < 0 || npc.target == byte.MaxValue || Main.player[npc.target].dead)
npc.TargetClosest(true);
if (Main.player[npc.target].dead && npc.timeLeft > 300)
npc.timeLeft = 300;
if (Main.netMode != 1)
{
if (!Main.npc[(int)npc.ai[1]].active)
{
npc.life = 0;
npc.HitEffect(0, 10.0);
npc.active = false;
NetMessage.SendData(28, -1, -1, null, npc.whoAmI, -1f, 0.0f, 0.0f, 0, 0, 0);
}
}
if (npc.ai[1] < (double)Main.npc.Length)
{
// We're getting the center of this NPC.
Vector2 npcCenter = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
// Then using that center, we calculate the direction towards the 'parent NPC' of this NPC.
float dirX = Main.npc[(int)npc.ai[1]].position.X + (float)(Main.npc[(int)npc.ai[1]].width / 2) - npcCenter.X;
float dirY = Main.npc[(int)npc.ai[1]].position.Y + (float)(Main.npc[(int)npc.ai[1]].height / 2) - npcCenter.Y;
// We then use Atan2 to get a correct rotation towards that parent NPC.
npc.rotation = (float)Math.Atan2(dirY, dirX) + 1.57f;
// We also get the length of the direction vector.
float length = (float)Math.Sqrt(dirX * dirX + dirY * dirY);
// We calculate a new, correct distance.
float dist = (length - (float)npc.width) / length;
float posX = dirX * dist;
float posY = dirY * dist;
// Reset the velocity of this NPC, because we don't want it to move on its own
npc.velocity = Vector2.Zero;
// And set this NPCs position accordingly to that of this NPCs parent NPC.
npc.position.X = npc.position.X + posX;
npc.position.Y = npc.position.Y + posY;
}
return false;
}
public override bool PreDraw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Color drawColor)
{
Texture2D texture = Main.npcTexture[npc.type];
Vector2 origin = new Vector2(texture.Width * 0.5f, texture.Height * 0.5f);
Main.spriteBatch.Draw(texture, npc.Center - Main.screenPosition, new Rectangle?(), drawColor, npc.rotation, origin, npc.scale, SpriteEffects.None, 0);
return false;
}
public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position)
{
return false; //this make that the npc does not have a health bar
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 782 B

View File

@ -783,7 +783,7 @@ namespace Decimation.Content.NPCs.Bloodshot
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor) public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{ {
Vector2 frameSize = new Vector2(110, 110); Vector2 frameSize = new Vector2(npc.width, npc.height);
Texture2D texture = mod.GetTexture("Content/NPCs/Bloodshot/BloodshotEye"); Texture2D texture = mod.GetTexture("Content/NPCs/Bloodshot/BloodshotEye");
spriteBatch.Draw spriteBatch.Draw

View File

@ -0,0 +1,146 @@
using Decimation.Content.Items.Misc.Souls;
using Decimation.Lib.NPCs;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace Decimation.Content.NPCs.DuneWyrm.AncientTombCrawler
{
public class AncientTombCrawlerHead : AncientTombCrawler
{
public override void SetDefaults()
{
npc.lifeMax = 2500;
npc.damage = 50;
npc.defense = 5;
npc.width = 38;
npc.height = 38;
npc.value = Item.buyPrice(gold: 3);
npc.npcSlots = 1f;
npc.aiStyle = -1;
npc.boss = true;
music = mod.GetSoundSlot(SoundType.Music, "Sounds/Music/The_Deserts_Call");
}
public override void Init()
{
base.Init();
head = true;
}
public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
if (Main.rand.NextBool(20)) target.AddBuff(BuffID.Darkness, 600);
}
public override void OnHitPlayer(Player target, int damage, bool crit)
{
if (Main.rand.NextBool(20)) target.AddBuff(BuffID.Darkness, 600);
}
public override void NPCLoot()
{
Item.NewItem(npc.Center, ModContent.ItemType<SoulofTime>(), Main.rand.Next(5, 11));
}
public override void BossLoot(ref string name, ref int potionType)
{
name = "An Ancient Tomb Crawler";
potionType = ItemID.HealingPotion;
base.BossLoot(ref name, ref potionType);
}
public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position)
{
scale = 1.3f; //this make the NPC Health Bar biger
return base.DrawHealthBar(hbPosition, ref scale, ref position);
}
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{
Draw("Content/NPCs/DuneWyrm/AncientTombCrawler/AncientTombCrawlerHead", spriteBatch, drawColor);
return false;
}
}
public class AncientTombCrawlerBody : AncientTombCrawler
{
public override void SetDefaults()
{
npc.width = 24;
npc.height = 24;
npc.damage = 35;
npc.defense = 2;
npc.lifeMax = 1;
npc.dontCountMe = true;
}
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{
Draw("Content/NPCs/DuneWyrm/AncientTombCrawler/AncientTombCrawlerBody", spriteBatch, drawColor);
return false;
}
}
public class AncientTombCrawlerTail : AncientTombCrawler
{
public override void SetDefaults()
{
npc.width = 20;
npc.height = 20;
npc.damage = 35;
npc.defense = 2;
npc.lifeMax = 1;
npc.dontCountMe = true;
}
public override void Init()
{
base.Init();
tail = true;
}
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{
Draw("Content/NPCs/DuneWyrm/AncientTombCrawler/AncientTombCrawlerTail", spriteBatch, drawColor);
return false;
}
}
public abstract class AncientTombCrawler : Worm
{
protected const float BaseSpeed = 10f;
public override void SetStaticDefaults()
{
DisplayName.SetDefault("Ancient Tomb Crawler");
}
public override void Init()
{
minLength = 8;
maxLength = 8;
tailType = ModContent.NPCType<AncientTombCrawlerTail>();
bodyType = ModContent.NPCType<AncientTombCrawlerBody>();
headType = ModContent.NPCType<AncientTombCrawlerHead>();
speed = BaseSpeed;
turnSpeed = 0.045f;
npc.scale = 1.5f;
npc.lavaImmune = true;
npc.noGravity = true;
npc.noTileCollide = true;
npc.behindTiles = true;
npc.knockBackResist = 0f;
npc.netAlways = true;
npc.DeathSound = SoundID.NPCDeath18;
npc.HitSound = SoundID.NPCHit1;
undergroundSound = mod.GetLegacySoundSlot(SoundType.Custom, "Sounds/Custom/Earthquake");
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

View File

@ -1,17 +1,19 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Decimation.Content.Buffs.Debuffs; using Decimation.Content.Buffs.Debuffs;
using Decimation.Lib.NPCs; using Decimation.Content.NPCs.DuneWyrm.AncientTombCrawler;
using Decimation.Content.Projectiles; using Decimation.Content.Projectiles;
using Decimation.Lib.NPCs;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria; using Terraria;
using Terraria.ID; using Terraria.ID;
using Terraria.ModLoader; using Terraria.ModLoader;
namespace Decimation.Content.NPCs.AncientDuneWorm namespace Decimation.Content.NPCs.DuneWyrm
{ {
[AutoloadBossHead] [AutoloadBossHead]
internal class AncientDuneWormHead : AncientDuneWorm internal class DuneWyrmHead : DuneWyrm
{ {
private int _attackCounter; private int _attackCounter;
private int _previousTile = -1; private int _previousTile = -1;
@ -19,25 +21,19 @@ namespace Decimation.Content.NPCs.AncientDuneWorm
public override void SetDefaults() public override void SetDefaults()
{ {
this.npc.lifeMax = 11000; npc.lifeMax = 11000;
this.npc.damage = 65; npc.damage = 65;
this.npc.defense = 15; npc.defense = 15;
this.npc.knockBackResist = 0f; npc.width = 116;
this.npc.width = 160; npc.height = 116;
this.npc.height = 154; npc.boss = true;
this.npc.boss = true; Main.npcFrameCount[npc.type] = 1;
this.npc.lavaImmune = true; npc.value = Item.buyPrice(gold: 12);
this.npc.noGravity = true; npc.npcSlots = 1f;
this.npc.noTileCollide = true; npc.aiStyle = -1;
this.npc.behindTiles = true; music = mod.GetSoundSlot(SoundType.Music, "Sounds/Music/The_Deserts_Call");
this.npc.DeathSound = SoundID.NPCDeath18;
this.npc.HitSound = SoundID.NPCHit1; DuneWyrmBody.bodyPartsCount = 0;
Main.npcFrameCount[this.npc.type] = 1;
this.npc.value = Item.buyPrice(0, 2);
this.npc.npcSlots = 1f;
this.npc.netAlways = true;
this.npc.aiStyle = -1;
music = this.mod.GetSoundSlot(SoundType.Music, "Sounds/Music/The_Deserts_Call");
} }
public override void Init() public override void Init()
@ -60,7 +56,7 @@ namespace Decimation.Content.NPCs.AncientDuneWorm
public override void BossLoot(ref string name, ref int potionType) public override void BossLoot(ref string name, ref int potionType)
{ {
name = "The Ancient Dune Worm"; name = "The Dune Wyrm";
DecimationWorld.downedDuneWorm = true; DecimationWorld.downedDuneWorm = true;
potionType = ItemID.HealingPotion; potionType = ItemID.HealingPotion;
@ -79,20 +75,20 @@ namespace Decimation.Content.NPCs.AncientDuneWorm
public override void CustomBehavior() public override void CustomBehavior()
{ {
if (this.npc.life < this.npc.lifeMax / 2f) ComputeSpeed(); if (npc.life < npc.lifeMax / 2f) ComputeSpeed();
if (Main.expertMode) SummonSandnado(); if (Main.expertMode) SummonSandnado();
if (Main.tile[(int) this.npc.Center.X / 16, (int) this.npc.Center.Y / 16].type != 0 && _previousTile == 0) if (Main.tile[(int) npc.Center.X / 16, (int) npc.Center.Y / 16].type != 0 && _previousTile == 0)
ShootAmmonite(); ShootAmmonite();
if (this.npc.life <= this.npc.lifeMax * 0.15f && if (npc.life <= npc.lifeMax * 0.15f &&
!_spawnedAncientTombCrawler && !NPC.AnyNPCs(ModContent.NPCType<AncientTombCrawlerHead>())) !_spawnedAncientTombCrawler && !NPC.AnyNPCs(ModContent.NPCType<AncientTombCrawlerHead>()))
{ {
if (Main.netMode != 1) if (Main.netMode != 1)
NPC.SpawnOnPlayer(this.npc.target, ModContent.NPCType<AncientTombCrawlerHead>()); NPC.SpawnOnPlayer(npc.target, ModContent.NPCType<AncientTombCrawlerHead>());
_spawnedAncientTombCrawler = true; _spawnedAncientTombCrawler = true;
} }
_previousTile = Main.tile[(int) this.npc.Center.X / 16, (int) this.npc.Center.Y / 16].type; _previousTile = Main.tile[(int) npc.Center.X / 16, (int) npc.Center.Y / 16].type;
} }
public override bool ShouldRun() public override bool ShouldRun()
@ -100,40 +96,40 @@ namespace Decimation.Content.NPCs.AncientDuneWorm
bool playersActive = Main.player.Any(p => p.active); bool playersActive = Main.player.Any(p => p.active);
bool playersDead = Main.player.Any(p => p.dead); bool playersDead = Main.player.Any(p => p.dead);
return !Main.player[this.npc.target].ZoneDesert || !playersActive || playersDead; return !Main.player[npc.target].ZoneDesert || !playersActive || playersDead;
} }
private void ComputeSpeed() private void ComputeSpeed()
{ {
const float ratio = 0.4545454f; const float ratio = 0.4545454f;
float deltaLife = this.npc.lifeMax / 2f - this.npc.life; float deltaLife = npc.lifeMax / 2f - npc.life;
float addedSpeed = deltaLife * ratio / 1000f; float addedSpeed = deltaLife * ratio / 1000f;
speed = BaseSpeed + addedSpeed; speed = BaseSpeed + addedSpeed;
} }
private void SummonSandnado() private void SummonSandnado()
{ {
int tile = Main.tile[(int) this.npc.Center.X / 16, (int) this.npc.Center.Y / 16].type; int tile = Main.tile[(int) npc.Center.X / 16, (int) npc.Center.Y / 16].type;
if (tile == 0 && if (tile == 0 &&
_previousTile != 0 && Main.netMode != 1) _previousTile != 0 && Main.netMode != 1)
Projectile.NewProjectile(this.npc.Center, new Vector2(0, 0), ProjectileID.SandnadoHostile, 15, 10f); Projectile.NewProjectile(npc.Center, new Vector2(0, 0), ProjectileID.SandnadoHostile, 15, 10f);
} }
private void ShootAmmonite() private void ShootAmmonite()
{ {
Main.PlaySound(SoundID.Item14, this.npc.Center); Main.PlaySound(SoundID.Item14, npc.Center);
// Smoke // Smoke
for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
{ {
int dustIndex = Dust.NewDust(new Vector2(this.npc.position.X, this.npc.position.Y), this.npc.width, int dustIndex = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y), npc.width,
this.npc.height, 31, 0f, 0f, 100, default, 2f); npc.height, 31, 0f, 0f, 100, default, 2f);
Main.dust[dustIndex].velocity *= 1.4f; Main.dust[dustIndex].velocity *= 1.4f;
} }
float x = this.npc.position.X + this.npc.width / 2f - 24f; float x = npc.position.X + npc.width / 2f - 24f;
float y = this.npc.position.Y + this.npc.height / 2f - 24f; float y = npc.position.Y + npc.height / 2f - 24f;
for (int g = 0; g < 2; g++) for (int g = 0; g < 2; g++)
{ {
@ -165,7 +161,7 @@ namespace Decimation.Content.NPCs.AncientDuneWorm
if (Main.netMode != 1) if (Main.netMode != 1)
for (int i = 0; i < ammoniteNbr; i++) for (int i = 0; i < ammoniteNbr; i++)
Projectile.NewProjectile(this.npc.Center, Projectile.NewProjectile(npc.Center,
new Vector2(Main.rand.Next(-8, 9), Main.rand.Next(8, 15)), new Vector2(Main.rand.Next(-8, 9), Main.rand.Next(8, 15)),
ModContent.ProjectileType<Ammonite>(), 15, 5f); ModContent.ProjectileType<Ammonite>(), 15, 5f);
} }
@ -175,45 +171,79 @@ namespace Decimation.Content.NPCs.AncientDuneWorm
scale = 1.9f; //this make the NPC Health Bar bigger scale = 1.9f; //this make the NPC Health Bar bigger
return null; return null;
} }
}
internal class AncientDuneWormBody : AncientDuneWorm public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{ {
public override void SetDefaults() Draw("Content/NPCs/DuneWyrm/DuneWyrmHead", spriteBatch, drawColor);
{
this.npc.width = 92; return false;
this.npc.height = 92;
this.npc.damage = 45;
this.npc.defense = 5;
this.npc.lifeMax = 1;
this.npc.knockBackResist = 0.0f;
this.npc.behindTiles = true;
this.npc.noTileCollide = true;
this.npc.netAlways = true;
this.npc.noGravity = true;
this.npc.dontCountMe = true;
this.npc.DeathSound = SoundID.NPCDeath18;
this.npc.HitSound = SoundID.NPCHit1;
} }
} }
internal class AncientDuneWormTail : AncientDuneWorm internal class DuneWyrmBody : DuneWyrm
{
public static int bodyPartsCount;
private int _bodyIndex;
public override void SetDefaults()
{
npc.width = 66;
npc.height = 66;
npc.damage = 45;
npc.defense = 5;
npc.lifeMax = 1;
npc.dontCountMe = true;
_bodyIndex = bodyPartsCount++;
}
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{
Vector2 frameSize = new Vector2(npc.width, npc.height);
Texture2D texture = mod.GetTexture("Content/NPCs/DuneWyrm/DuneWyrmBody");
Rectangle sourceRectangle = npc.frame;
if (_bodyIndex % 4 == 0)
{
texture = mod.GetTexture("Content/NPCs/DuneWyrm/DuneWyrmBody2");
sourceRectangle.Width = 88;
sourceRectangle.Height = 66;
frameSize.X += 11;
frameSize.Y -= 10;
}
Vector2 position = new Vector2(
npc.position.X - Main.screenPosition.X + frameSize.X / 2f,
npc.position.Y - Main.screenPosition.Y + frameSize.Y / 2f
);
spriteBatch.Draw
(
texture,
position,
sourceRectangle,
drawColor,
npc.rotation,
frameSize * 0.5f,
npc.scale,
SpriteEffects.None,
0f
);
return false;
}
}
internal class DuneWyrmTail : DuneWyrm
{ {
public override void SetDefaults() public override void SetDefaults()
{ {
this.npc.width = 136; npc.width = 54;
this.npc.height = 128; npc.height = 54;
this.npc.damage = 45; npc.damage = 45;
this.npc.defense = 14; npc.defense = 14;
this.npc.lifeMax = 1; npc.lifeMax = 1;
this.npc.knockBackResist = 0.0f; npc.dontCountMe = true;
this.npc.behindTiles = true;
this.npc.noTileCollide = true;
this.npc.netAlways = true;
this.npc.noGravity = true;
this.npc.dontCountMe = true;
this.npc.DeathSound = SoundID.NPCDeath18;
this.npc.HitSound = SoundID.NPCHit1;
} }
public override void Init() public override void Init()
@ -221,26 +251,43 @@ namespace Decimation.Content.NPCs.AncientDuneWorm
base.Init(); base.Init();
tail = true; tail = true;
} }
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{
Draw("Content/NPCs/DuneWyrm/DuneWyrmTail", spriteBatch, drawColor);
return false;
}
} }
public abstract class AncientDuneWorm : Worm public abstract class DuneWyrm : Worm
{ {
protected const float BaseSpeed = 10f; protected const float BaseSpeed = 10f;
public override void SetStaticDefaults() public override void SetStaticDefaults()
{ {
this.DisplayName.SetDefault("Ancient Dune Worm"); DisplayName.SetDefault("Dune Wyrm");
} }
public override void Init() public override void Init()
{ {
minLength = 16; minLength = 16;
maxLength = 16; maxLength = 16;
tailType = ModContent.NPCType<AncientDuneWormTail>(); tailType = ModContent.NPCType<DuneWyrmTail>();
bodyType = ModContent.NPCType<AncientDuneWormBody>(); bodyType = ModContent.NPCType<DuneWyrmBody>();
headType = ModContent.NPCType<AncientDuneWormHead>(); headType = ModContent.NPCType<DuneWyrmHead>();
speed = BaseSpeed; speed = BaseSpeed;
turnSpeed = 0.045f; turnSpeed = 0.045f;
npc.scale = 1.5f;
npc.lavaImmune = true;
npc.noGravity = true;
npc.noTileCollide = true;
npc.behindTiles = true;
npc.knockBackResist = 0f;
npc.netAlways = true;
npc.DeathSound = SoundID.NPCDeath18;
npc.HitSound = SoundID.NPCHit1;
undergroundSound = mod.GetLegacySoundSlot(SoundType.Custom, "Sounds/Custom/Earthquake");
} }
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 900 B

After

Width:  |  Height:  |  Size: 900 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,7 +1,8 @@
using System; using System;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria; using Terraria;
using Terraria.ID; using Terraria.Audio;
using Terraria.ModLoader; using Terraria.ModLoader;
namespace Decimation.Lib.NPCs namespace Decimation.Lib.NPCs
@ -25,76 +26,78 @@ namespace Decimation.Lib.NPCs
public float speed; public float speed;
public bool tail; public bool tail;
public int tailType; public int tailType;
public float turnSpeed; public float turnSpeed;
public LegacySoundStyle undergroundSound;
public override void AI() public override void AI()
{ {
if (this.npc.localAI[1] == 0f) if (npc.localAI[1] == 0f)
{ {
this.npc.localAI[1] = 1f; npc.localAI[1] = 1f;
Init(); Init();
} }
if (this.npc.ai[3] > 0f) this.npc.realLife = (int)this.npc.ai[3]; if (npc.ai[3] > 0f) npc.realLife = (int) npc.ai[3];
if (!head && this.npc.timeLeft < 300) this.npc.timeLeft = 300; if (!head && npc.timeLeft < 300) npc.timeLeft = 300;
if (this.npc.target < 0 || this.npc.target == 255 || Main.player[this.npc.target].dead) if (npc.target < 0 || npc.target == 255 || Main.player[npc.target].dead)
this.npc.TargetClosest(); npc.TargetClosest();
if (Main.player[this.npc.target].dead && this.npc.timeLeft > 300) this.npc.timeLeft = 300; if (Main.player[npc.target].dead && npc.timeLeft > 300) npc.timeLeft = 300;
if (Main.netMode != 1) if (Main.netMode != 1)
{ {
if (!tail && this.npc.ai[0] == 0f) if (!tail && npc.ai[0] == 0f)
{ {
if (head) if (head)
{ {
this.npc.ai[3] = this.npc.whoAmI; npc.ai[3] = npc.whoAmI;
this.npc.realLife = this.npc.whoAmI; npc.realLife = npc.whoAmI;
this.npc.ai[2] = Main.rand.Next(minLength, maxLength + 1); npc.ai[2] = Main.rand.Next(minLength, maxLength + 1);
this.npc.ai[0] = NPC.NewNPC((int)(this.npc.position.X + this.npc.width / 2), npc.ai[0] = NPC.NewNPC((int) (npc.position.X + npc.width / 2f),
(int)(this.npc.position.Y + this.npc.height), bodyType, this.npc.whoAmI); (int) (npc.position.Y + npc.height), bodyType, npc.whoAmI);
} }
else if (this.npc.ai[2] > 0f) else if (npc.ai[2] > 0f)
{ {
this.npc.ai[0] = NPC.NewNPC((int)(this.npc.position.X + this.npc.width / 2), npc.ai[0] = NPC.NewNPC((int) (npc.position.X + npc.width / 2f),
(int)(this.npc.position.Y + this.npc.height), this.npc.type, this.npc.whoAmI); (int) (npc.position.Y + npc.height), npc.type, npc.whoAmI);
} }
else else
{ {
this.npc.ai[0] = NPC.NewNPC((int)(this.npc.position.X + this.npc.width / 2), npc.ai[0] = NPC.NewNPC((int) (npc.position.X + npc.width / 2f),
(int)(this.npc.position.Y + this.npc.height), tailType, this.npc.whoAmI); (int) (npc.position.Y + npc.height), tailType, npc.whoAmI);
} }
Main.npc[(int)this.npc.ai[0]].ai[3] = this.npc.ai[3]; Main.npc[(int) npc.ai[0]].ai[3] = npc.ai[3];
Main.npc[(int)this.npc.ai[0]].realLife = this.npc.realLife; Main.npc[(int) npc.ai[0]].realLife = npc.realLife;
Main.npc[(int)this.npc.ai[0]].ai[1] = this.npc.whoAmI; Main.npc[(int) npc.ai[0]].ai[1] = npc.whoAmI;
Main.npc[(int)this.npc.ai[0]].ai[2] = this.npc.ai[2] - 1f; Main.npc[(int) npc.ai[0]].ai[2] = npc.ai[2] - 1f;
this.npc.netUpdate = true; npc.netUpdate = true;
} }
if (!head && (!Main.npc[(int)this.npc.ai[1]].active || if (!head && (!Main.npc[(int) npc.ai[1]].active ||
Main.npc[(int)this.npc.ai[1]].type != headType && Main.npc[(int) npc.ai[1]].type != headType &&
Main.npc[(int)this.npc.ai[1]].type != bodyType)) Main.npc[(int) npc.ai[1]].type != bodyType))
{ {
this.npc.life = 0; npc.life = 0;
this.npc.HitEffect(); npc.HitEffect();
this.npc.active = false; npc.active = false;
} }
if (!tail && (!Main.npc[(int)this.npc.ai[0]].active || if (!tail && (!Main.npc[(int) npc.ai[0]].active ||
Main.npc[(int)this.npc.ai[0]].type != bodyType && Main.npc[(int) npc.ai[0]].type != bodyType &&
Main.npc[(int)this.npc.ai[0]].type != tailType)) Main.npc[(int) npc.ai[0]].type != tailType))
{ {
this.npc.life = 0; npc.life = 0;
this.npc.HitEffect(); npc.HitEffect();
this.npc.active = false; npc.active = false;
} }
if (!this.npc.active && Main.netMode == 2) NetMessage.SendData(28, -1, -1, null, this.npc.whoAmI, -1f); if (!npc.active && Main.netMode == 2) NetMessage.SendData(28, -1, -1, null, npc.whoAmI, -1f);
} }
int num180 = (int)(this.npc.position.X / 16f) - 1; int num180 = (int) (npc.position.X / 16f) - 1;
int num181 = (int)((this.npc.position.X + this.npc.width) / 16f) + 2; int num181 = (int) ((npc.position.X + npc.width) / 16f) + 2;
int num182 = (int)(this.npc.position.Y / 16f) - 1; int num182 = (int) (npc.position.Y / 16f) - 1;
int num183 = (int)((this.npc.position.Y + this.npc.height) / 16f) + 2; int num183 = (int) ((npc.position.Y + npc.height) / 16f) + 2;
if (num180 < 0) num180 = 0; if (num180 < 0) num180 = 0;
if (num181 > Main.maxTilesX) num181 = Main.maxTilesX; if (num181 > Main.maxTilesX) num181 = Main.maxTilesX;
if (num182 < 0) num182 = 0; if (num182 < 0) num182 = 0;
@ -112,13 +115,13 @@ namespace Decimation.Lib.NPCs
Vector2 vector17; Vector2 vector17;
vector17.X = num184 * 16; vector17.X = num184 * 16;
vector17.Y = num185 * 16; vector17.Y = num185 * 16;
if (this.npc.position.X + this.npc.width > vector17.X && if (npc.position.X + npc.width > vector17.X &&
this.npc.position.X < vector17.X + 16f && npc.position.X < vector17.X + 16f &&
this.npc.position.Y + this.npc.height > vector17.Y && npc.position.Y + npc.height > vector17.Y &&
this.npc.position.Y < vector17.Y + 16f) npc.position.Y < vector17.Y + 16f)
{ {
flag18 = true; flag18 = true;
if (Main.rand.NextBool(100) && this.npc.behindTiles && Main.tile[num184, num185].nactive()) if (Main.rand.NextBool(100) && npc.behindTiles && Main.tile[num184, num185].nactive())
WorldGen.KillTile(num184, num185, true, true); WorldGen.KillTile(num184, num185, true, true);
if (Main.netMode != 1 && Main.tile[num184, num185].type == 2) if (Main.netMode != 1 && Main.tile[num184, num185].type == 2)
{ {
@ -129,8 +132,8 @@ namespace Decimation.Lib.NPCs
if (!flag18 && head) if (!flag18 && head)
{ {
Rectangle rectangle = new Rectangle((int)this.npc.position.X, (int)this.npc.position.Y, Rectangle rectangle = new Rectangle((int) npc.position.X, (int) npc.position.Y,
this.npc.width, this.npc.height); npc.width, npc.height);
int num186 = 1000; int num186 = 1000;
bool flag19 = true; bool flag19 = true;
for (int num187 = 0; num187 < 255; num187++) for (int num187 = 0; num187 < 255; num187++)
@ -150,17 +153,17 @@ namespace Decimation.Lib.NPCs
if (directional) if (directional)
{ {
if (this.npc.velocity.X < 0f) if (npc.velocity.X < 0f)
this.npc.spriteDirection = 1; npc.spriteDirection = 1;
else if (this.npc.velocity.X > 0f) this.npc.spriteDirection = -1; else if (npc.velocity.X > 0f) npc.spriteDirection = -1;
} }
float num188 = speed; float num188 = speed;
float num189 = turnSpeed; float num189 = turnSpeed;
Vector2 vector18 = new Vector2(this.npc.position.X + this.npc.width * 0.5f, Vector2 vector18 = new Vector2(npc.position.X + npc.width * 0.5f,
this.npc.position.Y + this.npc.height * 0.5f); npc.position.Y + npc.height * 0.5f);
float num191 = Main.player[this.npc.target].position.X + Main.player[this.npc.target].width / 2; float num191 = Main.player[npc.target].position.X + Main.player[npc.target].width / 2;
float num192 = Main.player[this.npc.target].position.Y + Main.player[this.npc.target].height / 2; float num192 = Main.player[npc.target].position.Y + Main.player[npc.target].height / 2;
num191 = (int) (num191 / 16f) * 16; num191 = (int) (num191 / 16f) * 16;
num192 = (int) (num192 / 16f) * 16; num192 = (int) (num192 / 16f) * 16;
vector18.X = (int) (vector18.X / 16f) * 16; vector18.X = (int) (vector18.X / 16f) * 16;
@ -168,73 +171,70 @@ namespace Decimation.Lib.NPCs
num191 -= vector18.X; num191 -= vector18.X;
num192 -= vector18.Y; num192 -= vector18.Y;
float num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192); float num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192);
if (this.npc.ai[1] > 0f && this.npc.ai[1] < Main.npc.Length) if (npc.ai[1] > 0f && npc.ai[1] < Main.npc.Length)
{ {
try try
{ {
vector18 = new Vector2(this.npc.position.X + this.npc.width * 0.5f, vector18 = new Vector2(npc.position.X + npc.width * 0.5f,
this.npc.position.Y + this.npc.height * 0.5f); npc.position.Y + npc.height * 0.5f);
num191 = Main.npc[(int)this.npc.ai[1]].position.X + Main.npc[(int)this.npc.ai[1]].width / 2 - num191 = Main.npc[(int) npc.ai[1]].position.X + Main.npc[(int) npc.ai[1]].width / 2 -
vector18.X; vector18.X;
num192 = Main.npc[(int)this.npc.ai[1]].position.Y + Main.npc[(int)this.npc.ai[1]].height / 2 - num192 = Main.npc[(int) npc.ai[1]].position.Y + Main.npc[(int) npc.ai[1]].height / 2 -
vector18.Y; vector18.Y;
} }
catch catch
{ {
} }
this.npc.rotation = (float)Math.Atan2(num192, num191) + 1.57f; npc.rotation = (float) Math.Atan2(num192, num191) + 1.57f;
num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192); num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192);
int num194 = this.npc.width; int num194 = npc.width;
num193 = (num193 - num194) / num193; num193 = (num193 - num194) / num193;
num191 *= num193; num191 *= num193;
num192 *= num193; num192 *= num193;
this.npc.velocity = Vector2.Zero; npc.velocity = Vector2.Zero;
this.npc.position.X = this.npc.position.X + num191; npc.position.X = npc.position.X + num191;
this.npc.position.Y = this.npc.position.Y + num192; npc.position.Y = npc.position.Y + num192;
if (directional) if (directional)
{ {
if (num191 < 0f) this.npc.spriteDirection = 1; if (num191 < 0f) npc.spriteDirection = 1;
if (num191 > 0f) this.npc.spriteDirection = -1; if (num191 > 0f) npc.spriteDirection = -1;
} }
} }
else else
{ {
if (!flag18) if (!flag18)
{ {
this.npc.TargetClosest(); npc.TargetClosest();
this.npc.velocity.Y = this.npc.velocity.Y + 0.11f; npc.velocity.Y = npc.velocity.Y + 0.11f;
if (this.npc.velocity.Y > num188) this.npc.velocity.Y = num188; if (npc.velocity.Y > num188) npc.velocity.Y = num188;
if (Math.Abs(this.npc.velocity.X) + Math.Abs(this.npc.velocity.Y) < num188 * 0.4) if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < num188 * 0.4)
{ {
if (this.npc.velocity.X < 0f) if (npc.velocity.X < 0f)
this.npc.velocity.X = this.npc.velocity.X - num189 * 1.1f; npc.velocity.X = npc.velocity.X - num189 * 1.1f;
else else
this.npc.velocity.X = this.npc.velocity.X + num189 * 1.1f; npc.velocity.X = npc.velocity.X + num189 * 1.1f;
} }
else if (this.npc.velocity.Y == num188) else if (npc.velocity.Y == num188)
{ {
if (this.npc.velocity.X < num191) if (npc.velocity.X < num191)
this.npc.velocity.X = this.npc.velocity.X + num189; npc.velocity.X = npc.velocity.X + num189;
else if (this.npc.velocity.X > num191) this.npc.velocity.X = this.npc.velocity.X - num189; else if (npc.velocity.X > num191) npc.velocity.X = npc.velocity.X - num189;
} }
else if (this.npc.velocity.Y > 4f) else if (npc.velocity.Y > 4f)
{ {
if (this.npc.velocity.X < 0f) if (npc.velocity.X < 0f)
this.npc.velocity.X = this.npc.velocity.X + num189 * 0.9f; npc.velocity.X = npc.velocity.X + num189 * 0.9f;
else else
this.npc.velocity.X = this.npc.velocity.X - num189 * 0.9f; npc.velocity.X = npc.velocity.X - num189 * 0.9f;
} }
} }
else else
{ {
if (!flies && this.npc.behindTiles && this.npc.soundDelay == 0) if (!flies && npc.behindTiles && npc.soundDelay == 0)
{ {
float num195 = num193 / 40f; npc.soundDelay = 120;
if (num195 < 10f) num195 = 10f; Main.PlaySound(undergroundSound, npc.position);
if (num195 > 20f) num195 = 20f;
this.npc.soundDelay = (int)num195;
Main.PlaySound(SoundID.Roar, this.npc.position);
} }
num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192); num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192);
@ -246,21 +246,21 @@ namespace Decimation.Lib.NPCs
if (ShouldRun()) if (ShouldRun())
{ {
if (Main.netMode != 1 && if (Main.netMode != 1 &&
this.npc.position.Y / 16f > (Main.rockLayer + Main.maxTilesY) / 2.0) npc.position.Y / 16f > (Main.rockLayer + Main.maxTilesY) / 2.0)
{ {
this.npc.active = false; npc.active = false;
int num200 = (int)this.npc.ai[0]; int num200 = (int) npc.ai[0];
while (num200 > 0 && num200 < 200 && Main.npc[num200].active && while (num200 > 0 && num200 < 200 && Main.npc[num200].active &&
Main.npc[num200].aiStyle == this.npc.aiStyle) Main.npc[num200].aiStyle == npc.aiStyle)
{ {
int num201 = (int) Main.npc[num200].ai[0]; int num201 = (int) Main.npc[num200].ai[0];
Main.npc[num200].active = false; Main.npc[num200].active = false;
this.npc.life = 0; npc.life = 0;
if (Main.netMode == 2) NetMessage.SendData(23, -1, -1, null, num200); if (Main.netMode == 2) NetMessage.SendData(23, -1, -1, null, num200);
num200 = num201; num200 = num201;
} }
if (Main.netMode == 2) NetMessage.SendData(23, -1, -1, null, this.npc.whoAmI); if (Main.netMode == 2) NetMessage.SendData(23, -1, -1, null, npc.whoAmI);
} }
num191 = 0f; num191 = 0f;
@ -268,131 +268,131 @@ namespace Decimation.Lib.NPCs
} }
bool flag21 = false; bool flag21 = false;
if (this.npc.type == 87) if (npc.type == 87)
{ {
if ((this.npc.velocity.X > 0f && num191 < 0f || this.npc.velocity.X < 0f && num191 > 0f || if ((npc.velocity.X > 0f && num191 < 0f || npc.velocity.X < 0f && num191 > 0f ||
this.npc.velocity.Y > 0f && num192 < 0f || this.npc.velocity.Y < 0f && num192 > 0f) && npc.velocity.Y > 0f && num192 < 0f || npc.velocity.Y < 0f && num192 > 0f) &&
Math.Abs(this.npc.velocity.X) + Math.Abs(this.npc.velocity.Y) > num189 / 2f && Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) > num189 / 2f &&
num193 < 300f) num193 < 300f)
{ {
flag21 = true; flag21 = true;
if (Math.Abs(this.npc.velocity.X) + Math.Abs(this.npc.velocity.Y) < num188) if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < num188)
this.npc.velocity *= 1.1f; npc.velocity *= 1.1f;
} }
if (this.npc.position.Y > Main.player[this.npc.target].position.Y || if (npc.position.Y > Main.player[npc.target].position.Y ||
Main.player[this.npc.target].position.Y / 16f > Main.worldSurface || Main.player[npc.target].position.Y / 16f > Main.worldSurface ||
Main.player[this.npc.target].dead) Main.player[npc.target].dead)
{ {
flag21 = true; flag21 = true;
if (Math.Abs(this.npc.velocity.X) < num188 / 2f) if (Math.Abs(npc.velocity.X) < num188 / 2f)
{ {
if (this.npc.velocity.X == 0f) if (npc.velocity.X == 0f)
this.npc.velocity.X = this.npc.velocity.X - this.npc.direction; npc.velocity.X = npc.velocity.X - npc.direction;
this.npc.velocity.X = this.npc.velocity.X * 1.1f; npc.velocity.X = npc.velocity.X * 1.1f;
} }
else else
{ {
if (this.npc.velocity.Y > -num188) this.npc.velocity.Y = this.npc.velocity.Y - num189; if (npc.velocity.Y > -num188) npc.velocity.Y = npc.velocity.Y - num189;
} }
} }
} }
if (!flag21) if (!flag21)
{ {
if (this.npc.velocity.X > 0f && num191 > 0f || this.npc.velocity.X < 0f && num191 < 0f || if (npc.velocity.X > 0f && num191 > 0f || npc.velocity.X < 0f && num191 < 0f ||
this.npc.velocity.Y > 0f && num192 > 0f || this.npc.velocity.Y < 0f && num192 < 0f) npc.velocity.Y > 0f && num192 > 0f || npc.velocity.Y < 0f && num192 < 0f)
{ {
if (this.npc.velocity.X < num191) if (npc.velocity.X < num191)
{ {
this.npc.velocity.X = this.npc.velocity.X + num189; npc.velocity.X = npc.velocity.X + num189;
} }
else else
{ {
if (this.npc.velocity.X > num191) this.npc.velocity.X = this.npc.velocity.X - num189; if (npc.velocity.X > num191) npc.velocity.X = npc.velocity.X - num189;
} }
if (this.npc.velocity.Y < num192) if (npc.velocity.Y < num192)
{ {
this.npc.velocity.Y = this.npc.velocity.Y + num189; npc.velocity.Y = npc.velocity.Y + num189;
} }
else else
{ {
if (this.npc.velocity.Y > num192) this.npc.velocity.Y = this.npc.velocity.Y - num189; if (npc.velocity.Y > num192) npc.velocity.Y = npc.velocity.Y - num189;
} }
if (Math.Abs(num192) < num188 * 0.2 && if (Math.Abs(num192) < num188 * 0.2 &&
(this.npc.velocity.X > 0f && num191 < 0f || this.npc.velocity.X < 0f && num191 > 0f)) (npc.velocity.X > 0f && num191 < 0f || npc.velocity.X < 0f && num191 > 0f))
{ {
if (this.npc.velocity.Y > 0f) if (npc.velocity.Y > 0f)
this.npc.velocity.Y = this.npc.velocity.Y + num189 * 2f; npc.velocity.Y = npc.velocity.Y + num189 * 2f;
else else
this.npc.velocity.Y = this.npc.velocity.Y - num189 * 2f; npc.velocity.Y = npc.velocity.Y - num189 * 2f;
} }
if (Math.Abs(num191) < num188 * 0.2 && if (Math.Abs(num191) < num188 * 0.2 &&
(this.npc.velocity.Y > 0f && num192 < 0f || this.npc.velocity.Y < 0f && num192 > 0f)) (npc.velocity.Y > 0f && num192 < 0f || npc.velocity.Y < 0f && num192 > 0f))
{ {
if (this.npc.velocity.X > 0f) if (npc.velocity.X > 0f)
this.npc.velocity.X = this.npc.velocity.X + num189 * 2f; npc.velocity.X = npc.velocity.X + num189 * 2f;
else else
this.npc.velocity.X = this.npc.velocity.X - num189 * 2f; npc.velocity.X = npc.velocity.X - num189 * 2f;
} }
} }
else else
{ {
if (num196 > num197) if (num196 > num197)
{ {
if (this.npc.velocity.X < num191) if (npc.velocity.X < num191)
this.npc.velocity.X = this.npc.velocity.X + num189 * 1.1f; npc.velocity.X = npc.velocity.X + num189 * 1.1f;
else if (this.npc.velocity.X > num191) else if (npc.velocity.X > num191)
this.npc.velocity.X = this.npc.velocity.X - num189 * 1.1f; npc.velocity.X = npc.velocity.X - num189 * 1.1f;
if (Math.Abs(this.npc.velocity.X) + Math.Abs(this.npc.velocity.Y) < num188 * 0.5) if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < num188 * 0.5)
{ {
if (this.npc.velocity.Y > 0f) if (npc.velocity.Y > 0f)
this.npc.velocity.Y = this.npc.velocity.Y + num189; npc.velocity.Y = npc.velocity.Y + num189;
else else
this.npc.velocity.Y = this.npc.velocity.Y - num189; npc.velocity.Y = npc.velocity.Y - num189;
} }
} }
else else
{ {
if (this.npc.velocity.Y < num192) if (npc.velocity.Y < num192)
this.npc.velocity.Y = this.npc.velocity.Y + num189 * 1.1f; npc.velocity.Y = npc.velocity.Y + num189 * 1.1f;
else if (this.npc.velocity.Y > num192) else if (npc.velocity.Y > num192)
this.npc.velocity.Y = this.npc.velocity.Y - num189 * 1.1f; npc.velocity.Y = npc.velocity.Y - num189 * 1.1f;
if (Math.Abs(this.npc.velocity.X) + Math.Abs(this.npc.velocity.Y) < num188 * 0.5) if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < num188 * 0.5)
{ {
if (this.npc.velocity.X > 0f) if (npc.velocity.X > 0f)
this.npc.velocity.X = this.npc.velocity.X + num189; npc.velocity.X = npc.velocity.X + num189;
else else
this.npc.velocity.X = this.npc.velocity.X - num189; npc.velocity.X = npc.velocity.X - num189;
} }
} }
} }
} }
} }
this.npc.rotation = (float)Math.Atan2(this.npc.velocity.Y, this.npc.velocity.X) + 1.57f; npc.rotation = (float) Math.Atan2(npc.velocity.Y, npc.velocity.X) + 1.57f;
if (head) if (head)
{ {
if (flag18) if (flag18)
{ {
if (this.npc.localAI[0] != 1f) this.npc.netUpdate = true; if (npc.localAI[0] != 1f) npc.netUpdate = true;
this.npc.localAI[0] = 1f; npc.localAI[0] = 1f;
} }
else else
{ {
if (this.npc.localAI[0] != 0f) this.npc.netUpdate = true; if (npc.localAI[0] != 0f) npc.netUpdate = true;
this.npc.localAI[0] = 0f; npc.localAI[0] = 0f;
} }
if ((this.npc.velocity.X > 0f && this.npc.oldVelocity.X < 0f || if ((npc.velocity.X > 0f && npc.oldVelocity.X < 0f ||
this.npc.velocity.X < 0f && this.npc.oldVelocity.X > 0f || npc.velocity.X < 0f && npc.oldVelocity.X > 0f ||
this.npc.velocity.Y > 0f && this.npc.oldVelocity.Y < 0f || npc.velocity.Y > 0f && npc.oldVelocity.Y < 0f ||
this.npc.velocity.Y < 0f && this.npc.oldVelocity.Y > 0f) && !this.npc.justHit) npc.velocity.Y < 0f && npc.oldVelocity.Y > 0f) && !npc.justHit)
{ {
this.npc.netUpdate = true; npc.netUpdate = true;
return; return;
} }
} }
@ -418,5 +418,27 @@ namespace Decimation.Lib.NPCs
{ {
return head ? (bool?) null : false; return head ? (bool?) null : false;
} }
protected void Draw(String texturePath, SpriteBatch spriteBatch, Color drawColor)
{
Vector2 frameSize = new Vector2(npc.width, npc.height);
Texture2D texture = mod.GetTexture(texturePath);
spriteBatch.Draw
(
texture,
new Vector2(
npc.position.X - Main.screenPosition.X + frameSize.X / 2,
npc.position.Y - Main.screenPosition.Y + frameSize.Y / 2
),
npc.frame,
drawColor,
npc.rotation,
frameSize * 0.5f,
npc.scale,
SpriteEffects.None,
0f
);
}
} }
} }