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()); 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() || Main.tile[i, j].type == ModContent.TileType() || Main.tile[i, j].type == ModContent.TileType() || Main.tile[i, j].type == ModContent.TileType() || Main.tile[i, j].type == ModContent.TileType()) validBlockCount++; return validBlockCount >= 15 && Main.hardMode; } } }