Decimation_Mod/Content/NPCs/DuneWyrm/DuneWyrm.cs
2020-06-05 12:42:17 -04:00

293 lines
9.6 KiB
C#

using System.IO;
using System.Linq;
using Decimation.Content.Buffs.Debuffs;
using Decimation.Content.NPCs.DuneWyrm.AncientTombCrawler;
using Decimation.Content.Projectiles;
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
{
[AutoloadBossHead]
internal class DuneWyrmHead : DuneWyrm
{
private int _attackCounter;
private int _previousTile = -1;
private bool _spawnedAncientTombCrawler;
public override void SetDefaults()
{
npc.lifeMax = 11000;
npc.damage = 65;
npc.defense = 15;
npc.width = 116;
npc.height = 116;
npc.boss = true;
Main.npcFrameCount[npc.type] = 1;
npc.value = Item.buyPrice(gold: 12);
npc.npcSlots = 1f;
npc.aiStyle = -1;
music = mod.GetSoundSlot(SoundType.Music, "Sounds/Music/The_Deserts_Call");
DuneWyrmBody.bodyPartsCount = 0;
}
public override void Init()
{
base.Init();
head = true;
}
public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
if (Main.rand.NextBool(5) || !Main.expertMode && Main.rand.NextBool(2))
target.AddBuff(ModContent.BuffType<Hyperthermic>(), Main.expertMode ? 600 : 300);
}
public override void OnHitPlayer(Player target, int damage, bool crit)
{
if (Main.rand.NextBool(5) || !Main.expertMode && Main.rand.NextBool(2))
target.AddBuff(ModContent.BuffType<Hyperthermic>(), Main.expertMode ? 600 : 300);
}
public override void BossLoot(ref string name, ref int potionType)
{
name = "The Dune Wyrm";
DecimationWorld.downedDuneWorm = true;
potionType = ItemID.HealingPotion;
base.BossLoot(ref name, ref potionType);
}
public override void SendExtraAI(BinaryWriter writer)
{
writer.Write(_attackCounter);
}
public override void ReceiveExtraAI(BinaryReader reader)
{
_attackCounter = reader.ReadInt32();
}
public override void CustomBehavior()
{
if (npc.life < npc.lifeMax / 2f) ComputeSpeed();
if (Main.expertMode) SummonSandnado();
if (Main.tile[(int) npc.Center.X / 16, (int) npc.Center.Y / 16].type != 0 && _previousTile == 0)
ShootAmmonite();
if (npc.life <= npc.lifeMax * 0.15f &&
!_spawnedAncientTombCrawler && !NPC.AnyNPCs(ModContent.NPCType<AncientTombCrawlerHead>()))
{
if (Main.netMode != 1)
NPC.SpawnOnPlayer(npc.target, ModContent.NPCType<AncientTombCrawlerHead>());
_spawnedAncientTombCrawler = true;
}
_previousTile = Main.tile[(int) npc.Center.X / 16, (int) npc.Center.Y / 16].type;
}
public override bool ShouldRun()
{
bool playersActive = Main.player.Any(p => p.active);
bool playersDead = Main.player.Any(p => p.dead);
return !Main.player[npc.target].ZoneDesert || !playersActive || playersDead;
}
private void ComputeSpeed()
{
const float ratio = 0.4545454f;
float deltaLife = npc.lifeMax / 2f - npc.life;
float addedSpeed = deltaLife * ratio / 1000f;
speed = BaseSpeed + addedSpeed;
}
private void SummonSandnado()
{
int tile = Main.tile[(int) npc.Center.X / 16, (int) npc.Center.Y / 16].type;
if (tile == 0 &&
_previousTile != 0 && Main.netMode != 1)
Projectile.NewProjectile(npc.Center, new Vector2(0, 0), ProjectileID.SandnadoHostile, 15, 10f);
}
private void ShootAmmonite()
{
Main.PlaySound(SoundID.Item14, npc.Center);
// Smoke
for (int i = 0; i < 50; i++)
{
int dustIndex = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y), npc.width,
npc.height, 31, 0f, 0f, 100, default, 2f);
Main.dust[dustIndex].velocity *= 1.4f;
}
float x = npc.position.X + npc.width / 2f - 24f;
float y = npc.position.Y + npc.height / 2f - 24f;
for (int g = 0; g < 2; g++)
{
int goreIndex =
Gore.NewGore(
new Vector2(x, y), default, Main.rand.Next(61, 64));
Main.gore[goreIndex].scale = 1.5f;
Main.gore[goreIndex].velocity.X += 1.5f;
Main.gore[goreIndex].velocity.Y += 1.5f;
goreIndex = Gore.NewGore(
new Vector2(x, y), default, Main.rand.Next(61, 64));
Main.gore[goreIndex].scale = 1.5f;
Main.gore[goreIndex].velocity.X -= 1.5f;
Main.gore[goreIndex].velocity.Y += 1.5f;
goreIndex = Gore.NewGore(
new Vector2(x, y), default, Main.rand.Next(61, 64));
Main.gore[goreIndex].scale = 1.5f;
Main.gore[goreIndex].velocity.X += 1.5f;
Main.gore[goreIndex].velocity.Y -= 1.5f;
goreIndex = Gore.NewGore(
new Vector2(x, y), default, Main.rand.Next(61, 64));
Main.gore[goreIndex].scale = 1.5f;
Main.gore[goreIndex].velocity.X -= 1.5f;
Main.gore[goreIndex].velocity.Y -= 1.5f;
}
// Ammonite
int ammoniteNbr = Main.rand.Next(5, 9);
if (Main.netMode != 1)
for (int i = 0; i < ammoniteNbr; i++)
Projectile.NewProjectile(npc.Center,
new Vector2(Main.rand.Next(-8, 9), Main.rand.Next(8, 15)),
ModContent.ProjectileType<Ammonite>(), 15, 5f);
}
public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position)
{
scale = 1.9f; //this make the NPC Health Bar bigger
return null;
}
public override bool PreDraw(SpriteBatch spriteBatch, Color drawColor)
{
Draw("Content/NPCs/DuneWyrm/DuneWyrmHead", spriteBatch, drawColor);
return false;
}
}
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()
{
npc.width = 54;
npc.height = 54;
npc.damage = 45;
npc.defense = 14;
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/DuneWyrmTail", spriteBatch, drawColor);
return false;
}
}
public abstract class DuneWyrm : Worm
{
protected const float BaseSpeed = 10f;
public override void SetStaticDefaults()
{
DisplayName.SetDefault("Dune Wyrm");
}
public override void Init()
{
minLength = 16;
maxLength = 16;
tailType = ModContent.NPCType<DuneWyrmTail>();
bodyType = ModContent.NPCType<DuneWyrmBody>();
headType = ModContent.NPCType<DuneWyrmHead>();
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");
}
}
}