From c8b07494c3fc076577d98c2cbf2709bf3f83aa1a Mon Sep 17 00:00:00 2001 From: FyloZ Date: Mon, 6 Jul 2020 15:18:38 -0400 Subject: [PATCH] Rewrote AI of the Core Spider (wall). --- Content/NPCs/CoreSpider.cs | 10 +++ Content/NPCs/CoreSpiderWall.cs | 129 ++++++++++++++++++++++++++------ Content/NPCs/CoreSpiderWall.png | Bin 1839 -> 2217 bytes 3 files changed, 115 insertions(+), 24 deletions(-) diff --git a/Content/NPCs/CoreSpider.cs b/Content/NPCs/CoreSpider.cs index 9911fa4..e96d02c 100644 --- a/Content/NPCs/CoreSpider.cs +++ b/Content/NPCs/CoreSpider.cs @@ -1,5 +1,6 @@ using System; using Decimation.Content.Tiles.ShrineoftheMoltenOne; +using Decimation.Lib.Util; using Microsoft.Xna.Framework; using Terraria; using Terraria.ID; @@ -36,11 +37,14 @@ namespace Decimation.Content.NPCs 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.HitSound = SoundID.NPCHit19; + npc.DeathSound = SoundID.NPCDeath12; } public override void FindFrame(int frameHeight) @@ -54,6 +58,12 @@ namespace Decimation.Content.NPCs } } + 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(); diff --git a/Content/NPCs/CoreSpiderWall.cs b/Content/NPCs/CoreSpiderWall.cs index 11f0ac1..b7bca14 100644 --- a/Content/NPCs/CoreSpiderWall.cs +++ b/Content/NPCs/CoreSpiderWall.cs @@ -1,4 +1,5 @@ using Decimation.Content.Tiles.ShrineoftheMoltenOne; +using Decimation.Lib.Util; using Microsoft.Xna.Framework; using Terraria; using Terraria.ID; @@ -9,43 +10,115 @@ namespace Decimation.Content.NPCs // Check line 43861 of NPC.cs internal class CoreSpiderWall : ModNPC { - private int frame; - private readonly int shootFrame = 120; + 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] = 4; + Main.npcFrameCount[npc.type] = AnimationFrameCount; } public override void SetDefaults() { - npc.CloneDefaults(NPCID.BlackRecluseWall); - npc.width = 60; - npc.height = 62; + npc.width = 52; + npc.height = 52; + npc.aiStyle = -1; npc.lifeMax = 750; - animationType = NPCID.BlackRecluseWall; - + 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() { - int x = (int) npc.Center.X / 16; - int y = (int) npc.Center.Y / 16; - bool onWall = true; - 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 = false; + 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; - if (Main.expertMode) + // Rotation + if (hasTarget) { - if (frame >= shootFrame) + Vector2 distance = target.Center - npc.Center; + if (distance.Length() > 0) { - if (Main.rand.Next(3) == 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); @@ -53,18 +126,26 @@ namespace Decimation.Content.NPCs Projectile.NewProjectile(mouthPos, projSpeed, ProjectileID.Fireball, 130, 30); } - frame = 0; + _frame = 0; } else { - frame++; + _frame++; } } - if (!onWall) - npc.Transform(ModContent.NPCType()); - else - base.AI(); + 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) diff --git a/Content/NPCs/CoreSpiderWall.png b/Content/NPCs/CoreSpiderWall.png index 264d0f5a1604c61f84872fb14ac5d080f1d816f4..f5a502a6075175290375e3d992e67c876fbfa71d 100644 GIT binary patch literal 2217 zcmV;a2v+xrP)Yrgn)t)lWGN< zEks0EK|x5ivoJ-1E6ls!g?sKhd(PaMx$n+BXPdY0{=NC;JLk;Y^E0#9F!r}FhIeCa zfX_es(#fjM{^QSIingif!%veQGk^i~=;rgw{x~=aADep*!Y9Wt?VzEOFgn9#08^mH zH~tEYzWU9-DrS#9c~m6{k`W$_VKabRpbbOEhfAi^%r?5d`POfzN`k~J&KGC6I>6lU z!SyJtXD*;xD~|R^?G+i89zcOt1DFHWj+a2zjGNF!9Hu&n=l%5dW1T+9t-G|{TzfIj zw+x#BOqn=)VL9X3*xu~Sgear8e|;pJ|LFIBItxuhfbso>bj7!TX#nm!w25>A;ZoK>SxyQq)%Ucgu&ZM9^xQ^;R zcRwTownfrW36D4qa}S`#WA=b)M^FZF9!#P`aQy16gU%!NU*GOnecFL^R9O4_usOg~ zw6k7Jzt;CL(a z{N1~MFB$sr`|$bByYF|7gC6Me)vNDyt@r+y;rq#r3*i&b2je@RJ-IyI_{g64{O9HU z4AaRBn*-c4WQ}M;_bAhETz)g$^4;xk!zY-9j^laI^;ceaIUM?U@57Z$Dixx`v(=;b8i$}6GYKEl-Y0pm{uoj4P zofOHJ?(gYzrhKjZJ}qM9Q&R@DqOI+~$ph9}ZwJiuKzW8U=^kYo-(%y%4p^%T(sj9w zjr4ok^VKn|1;$-h9&n~i_Eey_-vQ_9$y`=7cYBI4Y!+~ChEktboZ-|4=DvS)z})+5 z?2Kt>M>yc2Jty5qXI|QB6)F*_k}w*>W&l&5>#8{{KGWh{G_wUveOlU@!&G0Er1Qme zxO%{n|Ch7Uu}(bNQK+Ais!O$AQZ>V~1nIiqC`aI3>U)0*i_ zi&|;UA>eOIWNDh}UJp5D-Q&^dfOdJQ$+>vUIq|9mY|asH7BH>X9lC<4M-Q7Gm`u2o zx>;u*5H|~03YuwSIJnNUc!aGiTbwnYJj2BS4-KkuJsMkk$azS7)x)M|B!WaYtyq!=3Vh|#nJCDSR>w91rb;#I#WzFEK$aL=Z#J)3sJ zGvd1go7WyT`yrxReBZ;SC-$ed(PM8$Hupj;2kZ>bth&@(DV{mNt)gHn_QtiHn=y7fB;bZ{Q5J#$alDmI0PP}RXOTj29DoD>u zg;-oPQM>wK^1g>=0q3eYjNP%4yI#HTAyzPLM2!}cKmzeQ3o$$zxkT&a0ZYNN*hP2& zSkg%@Av`w4fvP0e-p#!S0cxA$!RhjB0dv+k)~Hd2V+*w?!`kW>Nm6lM%;GTzST}>` zuNqo|7^}6#6X&m(5Yf<`$iLK4mdqtx+Kp5$BIa8*RPG?b#;^jURTeL^}C}p%)N}1w$5uG zhsPd{MhCp^8I}VsWi%+WzEX>@en;%`R1$H;tn^S%2lxK0bpS|jRSsBk)kq>k&&P@+ zl?>naFj432ZUab-MNc%FTK@Jp6LUhi6xYQTTWa02T!=+7ZoN=Tt|%e}jPFwXm~-cH zwn3}oy_r_-C}K5$W36zt+W^MKkT?dZ=uUQ{$5>{mk@I~Iw;qN*fsvZcMvoHHz6(Ip zL)uI{bm-(ZdX$*<+C#5BTs=p3)rKF+ndXgA+iQ>^3g*&aiH(Hu_bvFFc%l5zcX4u+$>-&ia6A$c@~fF zd$?Mrw7SgM02~(=)aFDw_PDv!Luv%qU2}-`qir5WqXQWW)ATG4Dkgx!2q%900000NkvXXu0mjfxa3i> delta 1837 zcmV+|2h#Yd5w8xA7k~H&1^@s6u!V)t00001b5ch_0Itp)=>Px#1ZP1_K>z@;j|==^ z1poj532;bRa{vGi!vFvd!vV){sAK>D2E<83K~#8N?VT}*9aR*DcY_vM*u{XL;DU%) zq!CP&RTLBiyVXkDfR&Y9DzVX8A+0uQQVD_WW_f)8?<>WI6_IhS6}*1w+FdEW@qg1_DFW0Yo>whEy`Nh|E;gJC zOmMHsM)3N<7gtgQ=bt{c`soN>9&ig-7aI;awtHJGD`2oS^xO9-o<99dikB~6Oc5yK zLzx9O+<}Z9o;#W1g%9sZ5uk?efA8xQ6^FNuR`=4&ucmn8#_uVz@ea2RUBi9QSzDR? z^R*|^uYVYWy72lRDZ(iB!@Fm$rg(7hN{Zn8`43V=?Sd009!T-ykKRvl|EXtF#PjbS zzm_7_j}~=s@yoSL+pscw^W3i~0yg{B*>_U>=7(=nL~R1pC`>=M|9py{U-~RXHrw_E z1Jy2AoMC_Ax#M1X?!?*hkyhQ5XN`<2`0NMg!+$q4AA?l5fU)8 zX&Y9Qj#>g3V^h)SB%TLq{JIny29Z%vI`aTjAD~)@dR?Jff(;|{rSrx7J~ev?BE#HL zxMlHnso6sQd>iK4WmGNZ&ipfYKaA$qXf8Iqip8vJ7PRZhto?OaoZ;dx+!$#djgjWj zn15{^jghge42ccr($re>7|d+5U*&!42-t80j1FdYVr+P0G{?fL#zWX0l$Idt)&5(VF+erR45Mu^f+v_8lqdiw&2;=5oiQ+nJ1s?=rRF+?oWf z;lk0&j_K9Rf=4X}Mj9@yNf^dCZLTTxd4Hwkwg?*rsx|>L@o`<^8S@V5M^Prn8Vb*t-R)31W z@Z51PJ$K@4`ADm7%Ckns6+Tk)fm`tL{oGBf2^La z1{=<$=~bJ@V5XbV&ee$Lm@Lk4?|mJtmX203?RvZ)9*0gAqk81buWK6bS9442!rNiP zTvO339Wq#2i&&oLePLM68Uj8l3+9D^4FebeJO>0|60jMS>BumMURS7=Wq-qp$hiLt zz?RZGTdD>D8}oni*bwDe^Yzko5ogc$Jk*WOn(teh2i~J;tU&OjM-);+ZS%j{@6!arPOvzZGXe1u(@qNFSg;_ zngp$3|HZWJL>exwNf`EDJ=`*6R#a^Q&Zt^G*Dz|C=Y8=!=sTwbY?z5^l*#RN*(^{q z`|HjN7c%zK00000NkvXXu0mjfvGtS4