Decimation_Mod/Content/NPCs/CoreSpiderWall.cs
2020-07-06 15:18:38 -04:00

170 lines
6.6 KiB
C#

using Decimation.Content.Tiles.ShrineoftheMoltenOne;
using Decimation.Lib.Util;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace Decimation.Content.NPCs
{
// Check line 43861 of NPC.cs
internal class CoreSpiderWall : ModNPC
{
private const int AnimationFps = 10;
private const int AnimationFrameCount = 4;
private const float Speed = 2;
private const int ShootInterval = 120;
private int _frame;
public override void SetStaticDefaults()
{
DisplayName.SetDefault("Core Spider");
Main.npcFrameCount[npc.type] = AnimationFrameCount;
}
public override void SetDefaults()
{
npc.width = 52;
npc.height = 52;
npc.aiStyle = -1;
npc.lifeMax = 750;
npc.knockBackResist = 0.25f;
npc.lavaImmune = true;
npc.value = 7000;
npc.buffImmune[20] = true;
npc.buffImmune[31] = false;
npc.buffImmune[BuffID.OnFire] = true;
npc.buffImmune[BuffID.Burning] = true;
npc.timeLeft = NPC.activeTime * 2;
npc.noGravity = true;
npc.HitSound = SoundID.NPCHit19;
npc.DeathSound = SoundID.NPCDeath12;
}
public override bool PreAI()
{
Lighting.AddLight(npc.Center, LightingUtils.Rgb255ToRgb1(255, 155, 48));
return true;
}
public override void AI()
{
if (npc.target >= 255) npc.TargetClosest();
Player target = Main.player[npc.target];
if (npc.Distance(target.position) > 480) npc.target = 255;
if (!Collision.CanHitLine(npc.position, npc.width, npc.height, target.position, target.width, target.height)
) npc.target = 255;
bool hasTarget = npc.target < 255 && target.active && !target.dead;
// Rotation
if (hasTarget)
{
Vector2 distance = target.Center - npc.Center;
if (distance.Length() > 0)
{
float rotation = distance.ToRotation();
npc.rotation = rotation;
}
}
else
{
npc.rotation += Main.rand.NextFloat(-0.05f, 0.05f);
}
Vector2 velocity = new Vector2(1, 0);
velocity.Normalize();
velocity *= Speed;
npc.velocity = velocity.RotatedBy(npc.rotation);
if (!hasTarget)
{
Vector2 frontTilePosition = npc.Center;
frontTilePosition += new Vector2(npc.width / 2f + 16, 0).RotatedBy(npc.rotation);
int frontTileX = (int) frontTilePosition.X / 16;
int frontTileY = (int) frontTilePosition.Y / 16;
Tile frontTile = Main.tile[frontTileX, frontTileY];
Tile frontTileY1 = Main.tile[frontTileX, frontTileY + 1];
Tile frontTileY2 = Main.tile[frontTileX, frontTileY - 1];
if (frontTile == null) frontTile = new Tile();
if (frontTileY1.nactive() && Main.tileSolid[frontTileY1.type] &&
!Main.tileSolidTop[frontTileY1.type] &&
(!frontTileY2.nactive() || !Main.tileSolid[frontTileY2.type] ||
Main.tileSolidTop[frontTileY2.type]))
npc.rotation += MathHelper.PiOver2;
else if (frontTileY2.nactive() && Main.tileSolid[frontTileY2.type] &&
!Main.tileSolidTop[frontTileY2.type] &&
(!frontTileY1.nactive() || !Main.tileSolid[frontTileY1.type] ||
Main.tileSolidTop[frontTileY1.type]))
npc.rotation -= MathHelper.PiOver2;
else if (frontTile.nactive() && Main.tileSolid[frontTile.type] && !Main.tileSolidTop[frontTile.type])
npc.rotation += MathHelper.Pi;
}
int currentTileX = (int) npc.Center.X / 16;
int currentTileY = (int) npc.Center.Y / 16;
bool onWall = false;
for (int x = currentTileX - 1; x <= currentTileX + 1; x++)
{
for (int y = currentTileY - 1; y <= currentTileY + 1; y++)
{
if (Main.tile[x, y].wall > 0) onWall = true;
}
}
if (!onWall) npc.Transform(ModContent.NPCType<CoreSpider>());
if (Main.expertMode && hasTarget)
{
if (_frame >= ShootInterval)
{
if (Main.rand.Next(4) == 0)
{
Vector2 mouthPos = npc.Center + new Vector2(npc.width / 2f, 0).RotatedBy(npc.rotation);
Vector2 projSpeed = new Vector2(5, 0).RotatedBy(npc.rotation);
Projectile.NewProjectile(mouthPos, projSpeed, ProjectileID.Fireball, 130, 30);
}
_frame = 0;
}
else
{
_frame++;
}
}
if (npc.spriteDirection == -1) npc.spriteDirection = 1;
}
public override void FindFrame(int frameHeight)
{
if (++npc.frameCounter >= 60f / AnimationFps)
{
npc.frameCounter = 0;
npc.frame.Y += frameHeight;
if (npc.frame.Y / frameHeight >= AnimationFrameCount) npc.frame.Y = 0;
}
}
public override bool CheckConditions(int left, int right, int top, int bottom)
{
int x = (int) Main.LocalPlayer.position.X / 16;
int y = (int) Main.LocalPlayer.position.Y / 16;
int validBlockCount = 0;
for (int i = (int) (-50 + x / 16f); i <= (int) (50 + x / 16f); i++)
for (int j = (int) (-50 + y / 16f); j <= (int) (50 + y / 16f); j++)
if (i >= 0 && i <= Main.maxTilesX && j >= 0 && j <= Main.maxTilesY)
if (Main.tile[i, j].type == ModContent.TileType<ShrineBrick>() ||
Main.tile[i, j].type == ModContent.TileType<LockedShrineDoor>() ||
Main.tile[i, j].type == ModContent.TileType<ShrineDoorClosed>() ||
Main.tile[i, j].type == ModContent.TileType<ShrineDoorOpened>() ||
Main.tile[i, j].type == ModContent.TileType<RedHotSpike>())
validBlockCount++;
return validBlockCount >= 15 && Main.hardMode;
}
}
}