From aa893193de31e01cf771f4bcf11df6edc065f9d8 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Mon, 6 Jul 2020 14:11:49 -0400 Subject: [PATCH] Rewrote AI of the Core Spider (ground). --- Content/NPCs/CoreSpider.cs | 161 +++++++++++++++++++++++++++++++----- Content/NPCs/CoreSpider.png | Bin 2532 -> 3060 bytes 2 files changed, 140 insertions(+), 21 deletions(-) diff --git a/Content/NPCs/CoreSpider.cs b/Content/NPCs/CoreSpider.cs index 537470f..9911fa4 100644 --- a/Content/NPCs/CoreSpider.cs +++ b/Content/NPCs/CoreSpider.cs @@ -10,46 +10,170 @@ namespace Decimation.Content.NPCs // Check line 43861 of NPC.cs internal class CoreSpider : ModNPC { + private const int AnimationFps = 10; + private const int AnimationFrameCount = 8; private readonly int shootFrame = 120; private int _frame; + private int Direction + { + get => (int) npc.ai[0]; + set => npc.ai[0] = value; + } + public override void SetStaticDefaults() { DisplayName.SetDefault("Core Spider"); - Main.npcFrameCount[npc.type] = 8; + Main.npcFrameCount[npc.type] = AnimationFrameCount; } public override void SetDefaults() { - npc.CloneDefaults(NPCID.BlackRecluse); - npc.width = 84; - npc.height = 24; + npc.width = 72; + npc.height = 26; + npc.aiStyle = -1; + npc.damage = 130; npc.lifeMax = 750; - animationType = NPCID.BlackRecluse; - + npc.knockBackResist = 0.25f; npc.lavaImmune = true; + npc.buffImmune[20] = true; + npc.buffImmune[31] = false; npc.buffImmune[BuffID.OnFire] = true; npc.buffImmune[BuffID.Burning] = true; + npc.timeLeft = NPC.activeTime * 2; + } + + 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 void AI() { - int x = (int) npc.Center.X / 16; - int y = (int) npc.Center.Y / 16; - bool onWall = false; - for (int i = x - 1; i <= x + 1; i++) - for (int j = y - 1; j <= y + 1; j++) - if (Main.tile[i, j].wall > 0) - onWall = true; + if (npc.target >= 255) npc.TargetClosest(); + Player target = Main.player[npc.target]; + if (npc.Distance(target.position) > 480) npc.target = 255; + if (Math.Abs(target.position.Y - npc.position.Y) > 80) 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; - if (Main.expertMode) + // Walking + if (hasTarget) Direction = target.position.X - npc.position.X > 0 ? 1 : -1; + npc.velocity.X = 2 * Direction; + + Vector2 position = npc.position; + position.X += npc.velocity.X; + int frontTileX = (int) (position.X + npc.width / 2f + (npc.width / 2f + 1f) * Direction) / 16; + int frontTileY = (int) (position.Y + npc.height - 1) / 16; + Tile frontTile = Main.tile[frontTileX, frontTileY]; + Tile frontTileY1 = Main.tile[frontTileX, frontTileY - 1]; + Tile frontTileY2 = Main.tile[frontTileX, frontTileY - 2]; + Tile frontTileY3 = Main.tile[frontTileX, frontTileY - 3]; + Tile frontTileY4 = Main.tile[frontTileX, frontTileY - 4]; + Tile topTileY3 = Main.tile[frontTileX - Direction, frontTileY - 3]; + Tile bottomTile = Main.tile[frontTileX - Direction, frontTileY + 1]; + Tile frontTileX1 = Main.tile[frontTileX + Direction, frontTileY]; + Tile frontTileX1Y1 = Main.tile[frontTileX + Direction, frontTileY - 1]; + + if (frontTile == null) frontTile = new Tile(); + if (frontTileY1 == null) frontTileY1 = new Tile(); + if (frontTileY2 == null) frontTileY2 = new Tile(); + if (frontTileY3 == null) frontTileY3 = new Tile(); + if (frontTileY4 == null) frontTileY4 = new Tile(); + if (topTileY3 == null) topTileY3 = new Tile(); + if (bottomTile == null) bottomTile = new Tile(); + if (frontTileX1 == null) frontTileX1 = new Tile(); + if (frontTileX1Y1 == null) frontTileX1Y1 = new Tile(); + + if (frontTileX * 16 < position.X + npc.width && frontTileX * 16 + 16 > position.X && + (frontTile.nactive() && !frontTile.topSlope() && !frontTileY1.topSlope() && + Main.tileSolid[frontTile.type] && !Main.tileSolidTop[frontTile.type] || + frontTileY1.halfBrick() && frontTileY1.nactive()) && + (!frontTileY1.nactive() || !Main.tileSolid[frontTileY1.type] || Main.tileSolidTop[frontTileY1.type] || + frontTileY1.halfBrick() && (!frontTileY4.nactive() || !Main.tileSolid[frontTileY4.type] || + Main.tileSolidTop[frontTileY4.type])) && + (!frontTileY2.nactive() || !Main.tileSolid[frontTileY2.type] || Main.tileSolidTop[frontTileY2.type]) && + (!frontTileY3.nactive() || !Main.tileSolid[frontTileY3.type] || Main.tileSolidTop[frontTileY3.type]) && + (!topTileY3.nactive() || !Main.tileSolid[topTileY3.type])) + { + float newYPosition = frontTileY * 16; + if (frontTile.halfBrick()) newYPosition += 8f; + if (frontTileY1.halfBrick()) newYPosition -= 8f; + if (newYPosition < position.Y + npc.height) + { + float yDifference = position.Y + npc.height - newYPosition; + if (yDifference < 24.1f) + { + npc.gfxOffY += npc.position.Y + npc.height - newYPosition; + npc.position.Y = newYPosition - npc.height; + + if (yDifference < 9f) npc.stepSpeed = 1f; + else npc.stepSpeed = 2f; + } + } + } + + if ((frontTile.nactive() && !frontTile.topSlope() && Main.tileSolid[frontTile.type] && + !Main.tileSolidTop[frontTile.type] && + (frontTileY1.nactive() && !frontTileY1.topSlope() && Main.tileSolid[frontTileY1.type] && + !Main.tileSolidTop[frontTileY1.type] || frontTileY1.nactive() && frontTileY1.halfBrick()) || + frontTileX1.nactive() && !frontTileX1.topSlope() && Main.tileSolid[frontTileX1.type] && + !Main.tileSolidTop[frontTileX1.type] && + (frontTileX1Y1.nactive() && !frontTileX1Y1.topSlope() && Main.tileSolid[frontTileX1Y1.type] && + !Main.tileSolidTop[frontTileX1Y1.type] || + frontTileX1Y1.nactive() && frontTileX1Y1.halfBrick()) + ) && bottomTile.nactive() && (Main.tileSolid[bottomTile.type] || Main.tileSolidTop[bottomTile.type] || + bottomTile.halfBrick())) + { + if (!hasTarget && + frontTileY2.nactive() && !frontTileY2.topSlope() && Main.tileSolid[frontTileY2.type] && + !Main.tileSolidTop[frontTileY2.type] && + frontTileY3.nactive() && !frontTileY3.topSlope() && Main.tileSolid[frontTileY3.type] && + !Main.tileSolidTop[frontTileY3.type] && + frontTileY4.nactive() && !frontTileY4.topSlope() && Main.tileSolid[frontTileY4.type] && + !Main.tileSolidTop[frontTileY4.type] && !frontTileY4.halfBrick() + ) + { + // Turn around + Direction *= -1; + } + else + { + // Jump + npc.velocity.Y -= 1; + } + } + + if (npc.velocity.X < 0f) npc.spriteDirection = -1; + else if (npc.velocity.X > 0f) npc.spriteDirection = 1; + + 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 >= shootFrame) { 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); + Vector2 mouthPos = npc.Center + new Vector2(npc.width / 2f * Direction, 0); + Vector2 projSpeed = new Vector2(5 * Direction, 0); Projectile.NewProjectile(mouthPos, projSpeed, ProjectileID.Fireball, 130, 30); } @@ -61,11 +185,6 @@ namespace Decimation.Content.NPCs _frame++; } } - - if (onWall) - npc.Transform(ModContent.NPCType()); - else - base.AI(); } public override float SpawnChance(NPCSpawnInfo spawnInfo) diff --git a/Content/NPCs/CoreSpider.png b/Content/NPCs/CoreSpider.png index 67436cb17f32a3f149d85c785fab783a4c98c162..47aeb6ccf59e03533f84e562db6f13ec07a5d984 100644 GIT binary patch literal 3060 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