Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches

◆ AI_112_FairyCritter()

void Terraria.NPC.AI_112_FairyCritter ( )
inlineprivate

Definition at line 41303 of file NPC.cs.

41304 {
41305 bool flag = false;
41306 lavaImmune = true;
41307 if (Main.netMode != 1 && ai[2] > 1f)
41308 {
41309 int num = 18000;
41310 localAI[1] += 1f;
41311 if (localAI[1] >= (float)num)
41312 {
41313 ai[2] = 7f;
41314 if (Main.player[target].Center.X < base.Center.X)
41315 {
41316 direction = 1;
41317 }
41318 else
41319 {
41320 direction = -1;
41321 }
41322 netUpdate = true;
41323 }
41324 }
41325 switch ((int)ai[2])
41326 {
41327 case 0:
41328 {
41329 lavaImmune = false;
41330 noTileCollide = false;
41331 if (ai[0] == 0f && ai[1] == 0f)
41332 {
41333 ai[0] = base.Center.X;
41334 ai[1] = base.Center.Y;
41335 }
41336 if (localAI[0] == 0f)
41337 {
41338 localAI[0] = 1f;
41339 velocity = new Vector2(MathHelper.Lerp(2f, 4f, Main.rand.NextFloat()) * (float)(Main.rand.Next(2) * 2 - 1), MathHelper.Lerp(1f, 2f, Main.rand.NextFloat()) * (float)(Main.rand.Next(2) * 2 - 1));
41340 velocity *= 0.7f;
41341 netUpdate = true;
41342 }
41343 Vector2 vector4 = new Vector2(ai[0], ai[1]) - base.Center;
41344 if (vector4.Length() > 20f)
41345 {
41346 Vector2 vector5 = new Vector2((vector4.X > 0f) ? 1 : (-1), (vector4.Y > 0f) ? 1 : (-1));
41347 velocity += vector5 * 0.04f;
41348 if (Math.Abs(velocity.Y) > 2f)
41349 {
41350 velocity.Y *= 0.95f;
41351 }
41352 }
41353 TargetClosest();
41354 Player player = Main.player[target];
41355 if (!player.dead && player.Distance(base.Center) < 250f)
41356 {
41357 ai[2] = 1f;
41358 direction = ((!(player.Center.X > base.Center.X)) ? 1 : (-1));
41359 if (velocity.X * (float)direction < 0f)
41360 {
41361 velocity.X = direction * 2;
41362 }
41363 ai[3] = 0f;
41364 netUpdate = true;
41365 }
41366 break;
41367 }
41368 case 1:
41369 {
41370 lavaImmune = false;
41371 noTileCollide = false;
41372 if (collideX)
41373 {
41374 direction *= -1;
41375 velocity.X = direction * 2;
41376 }
41377 if (collideY)
41378 {
41379 velocity.Y = ((oldVelocity.Y > 0f) ? 1 : (-1));
41380 }
41381 float num12 = 4.5f;
41383 {
41384 velocity.X += (float)direction * 0.04f;
41385 if (velocity.X * (float)direction < 0f)
41386 {
41387 if (Math.Abs(velocity.X) > num12)
41388 {
41389 velocity.X += (float)direction * 0.4f;
41390 }
41391 else
41392 {
41393 velocity.X += (float)direction * 0.2f;
41394 }
41395 }
41396 else if (Math.Abs(velocity.X) > num12)
41397 {
41398 velocity.X = (float)direction * num12;
41399 }
41400 }
41401 int num13 = (int)((position.X + (float)(width / 2)) / 16f);
41402 int num14 = 20;
41403 if (direction < 0)
41404 {
41405 num13 -= num14;
41406 }
41407 int num15 = (int)((position.Y + (float)height) / 16f);
41408 bool flag5 = true;
41409 int num16 = 8;
41410 bool flag6 = false;
41411 for (int i = num13; i <= num13 + num14; i++)
41412 {
41413 for (int j = num15; j < num15 + num16; j++)
41414 {
41415 if (Main.tile[i, j] == null)
41416 {
41417 Main.tile[i, j] = new Tile();
41418 }
41419 if ((Main.tile[i, j].nactive() && Main.tileSolid[Main.tile[i, j].type]) || Main.tile[i, j].liquid > 0)
41420 {
41421 if (j < num15 + 5)
41422 {
41423 flag6 = true;
41424 }
41425 flag5 = false;
41426 break;
41427 }
41428 }
41429 }
41430 if (flag5)
41431 {
41432 velocity.Y += 0.05f;
41433 }
41434 else
41435 {
41436 velocity.Y -= 0.2f;
41437 }
41438 if (flag6)
41439 {
41440 velocity.Y -= 0.3f;
41441 }
41442 if (velocity.Y > 3f)
41443 {
41444 velocity.Y = 3f;
41445 }
41446 if (velocity.Y < -5f)
41447 {
41448 velocity.Y = -5f;
41449 }
41450 break;
41451 }
41452 case 2:
41453 {
41454 noTileCollide = true;
41456 bool flag3 = false;
41457 if (targetData.Type == NPCTargetType.Player)
41458 {
41459 flag3 = Main.player[target].dead;
41460 }
41461 if (flag3)
41462 {
41463 ai[2] = 1f;
41464 direction = ((!(targetData.Center.X > base.Center.X)) ? 1 : (-1));
41465 if (velocity.X * (float)direction < 0f)
41466 {
41467 velocity.X = direction * 2;
41468 }
41469 ai[3] = 0f;
41470 netUpdate = true;
41471 break;
41472 }
41473 Rectangle r = Utils.CenteredRectangle(targetData.Center, new Vector2(targetData.Width + 60, targetData.Height / 2));
41474 if (Main.netMode != 1 && base.Hitbox.Intersects(r))
41475 {
41477 {
41478 ai[0] = treasureCoords2.X;
41479 ai[1] = treasureCoords2.Y;
41480 ai[2] = 3f;
41481 ai[3] = 0f;
41482 netUpdate = true;
41483 }
41484 else
41485 {
41486 ai[2] = 6f;
41487 ai[3] = 0f;
41488 netUpdate = true;
41489 }
41490 break;
41491 }
41492 Vector2 vector3 = r.ClosestPointInRect(base.Center);
41494 float num8 = Distance(vector3);
41495 if (num8 > 150f)
41496 {
41497 value *= 2f;
41498 }
41499 else if (num8 > 80f)
41500 {
41501 value *= 1.5f;
41502 }
41503 velocity = Vector2.Lerp(velocity, value, 0.07f);
41504 Point point = base.Center.ToTileCoordinates();
41505 if (ai[3] < 300f)
41506 {
41508 if (goDownwards)
41509 {
41510 velocity.Y += 0.05f;
41511 }
41512 if (goUpwards)
41513 {
41514 velocity.Y -= 0.02f;
41515 }
41516 if (velocity.Y > 2f)
41517 {
41518 velocity.Y = 2f;
41519 }
41520 if (velocity.Y < -4f)
41521 {
41522 velocity.Y = -4f;
41523 }
41524 }
41525 if (WorldGen.InWorld(point.X, point.Y))
41526 {
41527 if (WorldGen.SolidTile(point))
41528 {
41529 ai[3] = Math.Min(ai[3] + 2f, 400f);
41530 }
41531 else
41532 {
41533 ai[3] = Math.Max(ai[3] - 1f, 0f);
41534 }
41535 }
41536 break;
41537 }
41538 case 3:
41539 noTileCollide = true;
41540 if (ai[3] == 15f)
41541 {
41542 SoundEngine.PlaySound(27, (int)position.X, (int)position.Y);
41543 }
41544 if (ai[3] <= 15f)
41545 {
41546 velocity *= 0.9f;
41547 }
41548 else
41549 {
41550 if (Main.player[target].Center.X > base.Center.X)
41551 {
41552 spriteDirection = -1;
41553 }
41554 else
41555 {
41556 spriteDirection = 1;
41557 }
41558 flag = true;
41559 float num6 = 0f;
41560 float num7 = ai[3] - 15f;
41561 float circleHeight = 22f;
41562 if (num7 <= 65f)
41563 {
41564 num6 = (float)Math.PI / 8f;
41565 circleHeight = 14f;
41566 }
41567 else if (num7 <= 130f)
41568 {
41569 num6 = -(float)Math.PI / 8f;
41570 circleHeight = 18f;
41571 }
41572 num6 *= (float)direction;
41576 }
41577 ai[3] += 1f;
41578 if (ai[3] >= 210f)
41579 {
41580 ai[2] = 4f;
41581 TargetClosest();
41582 ai[3] = 0f;
41583 netUpdate = true;
41584 }
41585 break;
41586 case 6:
41587 {
41588 noTileCollide = true;
41589 Vector2 vector = Main.player[target].Center - base.Center;
41590 if (vector.Length() > 100f)
41591 {
41592 ai[2] = 2f;
41593 TargetClosest();
41594 ai[3] = 0f;
41595 netUpdate = true;
41596 break;
41597 }
41598 if (!Collision.SolidCollision(position, width, height))
41599 {
41600 noTileCollide = false;
41601 if (collideX)
41602 {
41603 velocity.X *= -1f;
41604 }
41605 if (collideY)
41606 {
41607 velocity.Y *= -1f;
41608 }
41609 }
41610 if (vector.Length() > 20f)
41611 {
41612 Vector2 vector2 = new Vector2((vector.X > 0f) ? 1 : (-1), (vector.Y > 0f) ? 1 : (-1));
41613 velocity += vector2 * 0.04f;
41614 if (Math.Abs(velocity.Y) > 2f)
41615 {
41616 velocity.Y *= 0.95f;
41617 }
41618 }
41619 if (Main.netMode != 1 && GetFairyTreasureCoords(out var treasureCoords))
41620 {
41621 ai[0] = treasureCoords.X;
41622 ai[1] = treasureCoords.Y;
41623 ai[2] = 3f;
41624 ai[3] = 0f;
41625 netUpdate = true;
41626 }
41627 break;
41628 }
41629 case 4:
41630 {
41631 noTileCollide = true;
41633 bool flag4 = false;
41634 if (targetData2.Type == NPCTargetType.Player)
41635 {
41636 flag4 = Main.player[target].dead;
41637 }
41638 if (flag4)
41639 {
41640 ai[2] = 1f;
41641 direction = ((!(targetData2.Center.X > base.Center.X)) ? 1 : (-1));
41642 if (velocity.X * (float)direction < 0f)
41643 {
41644 velocity.X = direction * 2;
41645 }
41646 ai[3] = 0f;
41647 netUpdate = true;
41648 break;
41649 }
41650 Rectangle r2 = Utils.CenteredRectangle(new Vector2(ai[0] * 16f + 8f, ai[1] * 16f + 8f), Vector2.One * 5f);
41651 if (base.Hitbox.Intersects(r2))
41652 {
41653 ai[2] = 5f;
41654 ai[3] = 0f;
41655 netUpdate = true;
41656 break;
41657 }
41658 float num9 = Distance(targetData2.Center);
41659 float num10 = 300f;
41660 if (num9 > num10)
41661 {
41662 if (num9 < num10 + 100f && !Collision.SolidCollision(position, width, height))
41663 {
41664 noTileCollide = false;
41665 if (collideX)
41666 {
41667 velocity.X *= -1f;
41668 }
41669 if (collideY)
41670 {
41671 velocity.Y *= -1f;
41672 }
41673 }
41674 flag = true;
41675 if (Main.player[target].Center.X > base.Center.X)
41676 {
41677 spriteDirection = -1;
41678 }
41679 else
41680 {
41681 spriteDirection = 1;
41682 }
41684 if (num9 > num10 + 60f)
41685 {
41686 velocity += vector6 * -0.1f;
41687 if (Main.rand.Next(30) == 0)
41688 {
41689 SoundEngine.PlaySound(27, (int)position.X, (int)position.Y);
41690 }
41691 }
41692 else if (num9 < num10 + 30f)
41693 {
41694 Vector2 destination = r2.ClosestPointInRect(base.Center);
41696 velocity += vector7 * 0.1f;
41697 }
41698 if (velocity.Length() > 1f)
41699 {
41700 velocity *= 1f / velocity.Length();
41701 }
41702 break;
41703 }
41704 Vector2 vector8 = r2.ClosestPointInRect(base.Center);
41706 float num11 = Distance(vector8);
41707 if (num11 > 150f)
41708 {
41709 value2 *= 3f;
41710 }
41711 else if (num11 > 80f)
41712 {
41713 value2 *= 2f;
41714 }
41715 Point point2 = base.Center.ToTileCoordinates();
41716 if (ai[3] < 300f)
41717 {
41718 velocity = Vector2.Lerp(velocity, value2, 0.07f);
41720 if (goDownwards2)
41721 {
41722 velocity.Y += 0.05f;
41723 }
41724 if (goUpwards2)
41725 {
41726 velocity.Y -= 0.05f;
41727 }
41728 if (velocity.Y > 1f)
41729 {
41730 velocity.Y = 1f;
41731 }
41732 if (velocity.Y < -1f)
41733 {
41734 velocity.Y = -1f;
41735 }
41736 }
41737 else
41738 {
41739 velocity = Vector2.Lerp(velocity, value2, 0.07f);
41740 }
41741 if (WorldGen.SolidTile(point2))
41742 {
41743 ai[3] = Math.Min(ai[3] + 2f, 400f);
41744 }
41745 else
41746 {
41747 ai[3] = Math.Max(ai[3] - 1f, 0f);
41748 }
41749 break;
41750 }
41751 case 5:
41752 {
41753 localAI[1] = 0f;
41754 noTileCollide = true;
41755 bool flag2 = false;
41756 Tile tileSafely = Framing.GetTileSafely(new Point((int)ai[0], (int)ai[1]));
41757 if (!tileSafely.active() || !SceneMetrics.IsValidForOreFinder(tileSafely))
41758 {
41759 flag2 = true;
41760 }
41761 if (ai[3] == 15f)
41762 {
41763 SoundEngine.PlaySound(27, (int)position.X, (int)position.Y);
41764 }
41765 if (ai[3] <= 15f)
41766 {
41767 velocity *= 0.9f;
41768 }
41769 else
41770 {
41771 flag = true;
41772 float num2 = 0f;
41773 float num3 = ai[3] - 15f;
41774 float num4 = 22f;
41775 int num5 = (int)(num3 / 50f);
41776 num2 = (float)Math.Cos((float)num5 * 1f) * ((float)Math.PI * 2f) / 16f;
41777 num4 = (float)Math.Cos((float)num5 * 2f) * 10f + 8f;
41778 num2 *= (float)direction;
41782 if (Main.player[target].Center.X > base.Center.X)
41783 {
41784 spriteDirection = -1;
41785 }
41786 else
41787 {
41788 spriteDirection = 1;
41789 }
41790 }
41791 ai[3] += 1f;
41792 if (Main.netMode != 1 && ai[3] > 200f)
41793 {
41794 active = false;
41795 if (Main.netMode == 0)
41796 {
41797 FairyEffects(base.Center, type - 583);
41798 }
41799 else if (Main.netMode == 2)
41800 {
41801 netSkip = -1;
41802 life = 0;
41803 NetMessage.SendData(23, -1, -1, null, whoAmI);
41804 NetMessage.SendData(112, -1, -1, null, 2, (int)base.Center.X, (int)base.Center.Y, 0f, type - 583);
41805 }
41806 }
41807 break;
41808 }
41809 case 7:
41810 noTileCollide = true;
41811 velocity.X += 0.05f * (float)direction;
41812 velocity.X = MathHelper.Clamp(velocity.X, -10f, 10f);
41813 velocity.Y -= 0.025f;
41814 velocity.Y = MathHelper.Clamp(velocity.Y, -5f, 5f);
41815 EncourageDespawn(10);
41816 break;
41817 }
41819 for (int k = 0; k < 200; k++)
41820 {
41821 if (k != whoAmI && Main.npc[k].active && Main.npc[k].aiStyle == 112 && Math.Abs(position.X - Main.npc[k].position.X) + Math.Abs(position.Y - Main.npc[k].position.Y) < (float)width * 1.5f)
41822 {
41823 if (position.Y < Main.npc[k].position.Y)
41824 {
41825 velocity.Y -= 0.05f;
41826 }
41827 else
41828 {
41829 velocity.Y += 0.05f;
41830 }
41831 }
41832 }
41833 if (!flag)
41834 {
41835 direction = ((velocity.X >= 0f) ? 1 : (-1));
41837 }
41840 int num17 = 4;
41841 if (type == 584)
41842 {
41845 }
41846 if (type == 585)
41847 {
41850 }
41851 if ((int)Main.timeForVisualEffects % 2 == 0)
41852 {
41854 Dust dust = Dust.NewDustDirect(base.Center - new Vector2(num17) * 0.5f, num17 + 4, num17 + 4, 278, 0f, 0f, 200, Color.Lerp(value3, value4, Main.rand.NextFloat()), 0.65f);
41855 dust.velocity *= 0f;
41856 dust.velocity += velocity * 0.3f;
41857 dust.noGravity = true;
41858 dust.noLight = true;
41860 }
41861 Lighting.AddLight(base.Center, value3.ToVector3() * 0.7f);
41862 if (Main.netMode != 2)
41863 {
41864 Player localPlayer = Main.LocalPlayer;
41865 if (!localPlayer.dead && localPlayer.HitboxForBestiaryNearbyCheck.Intersects(base.Hitbox))
41866 {
41868 }
41869 }
41870 }
static float Lerp(float value1, float value2, float amount)
Definition MathHelper.cs:53
static float Clamp(float value, float min, float max)
Definition MathHelper.cs:46
static double Cos(double d)
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static double Abs(double value)
const double PI
Definition Math.cs:16
static int Sign(decimal value)
Definition Math.cs:1202
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static void PlaySound(int type, Vector2 position, int style=1)
Vector2 DirectionFrom(Vector2 Source)
Definition Entity.cs:202
Vector2 velocity
Definition Entity.cs:16
float Distance(Vector2 Other)
Definition Entity.cs:187
Vector2 position
Definition Entity.cs:14
Vector2 DirectionTo(Vector2 Destination)
Definition Entity.cs:197
static void HandleSpecialEvent(Player player, int eventID)
Vector2 netOffset
Definition NPC.cs:103
float[] localAI
Definition NPC.cs:449
int spriteDirection
Definition NPC.cs:517
void EncourageDespawn(int despawnTime)
Definition NPC.cs:1390
void TargetClosest(bool faceTarget=true)
Definition NPC.cs:69934
NPCAimedTarget GetTargetData(bool ignorePlayerTankPets=true)
Definition NPC.cs:864
bool dontTakeDamageFromHostiles
Definition NPC.cs:279
float[] ai
Definition NPC.cs:447
bool GetFairyTreasureCoords(out Point treasureCoords)
Definition NPC.cs:41935
void GetBirdFlightRecommendation(int downScanRange, int upRange, Point tCoords, out bool goDownwards, out bool goUpwards)
Definition NPC.cs:41905
bool dontTakeDamage
Definition NPC.cs:527
float value
Definition NPC.cs:523
bool collideX
Definition NPC.cs:511
bool collideY
Definition NPC.cs:513
int type
Definition NPC.cs:445
static void FairyEffects(Vector2 Position, int type)
Definition NPC.cs:41872
Vector2 GetFairyCircleOffset(float elapsedTime, float circleRotation, float circleHeight)
Definition NPC.cs:41930
bool lavaImmune
Definition NPC.cs:521
bool noTileCollide
Definition NPC.cs:505
int life
Definition NPC.cs:477
bool netUpdate
Definition NPC.cs:507
int target
Definition NPC.cs:459
int netSkip
Definition NPC.cs:169
static Color LightSeaGreen
Definition Color.cs:220
static Color Lerp(Color value1, Color value2, float amount)
Definition Color.cs:491
static Vector2 Lerp(Vector2 value1, Vector2 value2, float amount)
Definition Vector2.cs:227

References System.Math.Abs(), Terraria.Entity.active, Terraria.Lighting.AddLight(), Terraria.NPC.ai, Terraria.Utils.CenteredRectangle(), Microsoft.Xna.Framework.MathHelper.Clamp(), Terraria.NPC.collideX, Terraria.NPC.collideY, System.Math.Cos(), Terraria.Player.dead, System.destination, Terraria.Entity.direction, Terraria.Entity.DirectionFrom(), Terraria.Entity.DirectionTo(), Terraria.Entity.Distance(), Terraria.NPC.dontTakeDamage, Terraria.NPC.dontTakeDamageFromHostiles, Terraria.NPC.EncourageDespawn(), Terraria.NPC.FairyEffects(), Terraria.NPC.GetBirdFlightRecommendation(), Terraria.NPC.GetFairyCircleOffset(), Terraria.NPC.GetFairyTreasureCoords(), Terraria.NPC.GetTargetData(), Terraria.Framing.GetTileSafely(), Terraria.GameContent.Achievements.AchievementsHelper.HandleSpecialEvent(), Terraria.Entity.height, Microsoft.Xna.Framework.Color.HotPink, Terraria.WorldGen.InWorld(), Terraria.SceneMetrics.IsValidForOreFinder(), Terraria.NPC.lavaImmune, Microsoft.Xna.Framework.Vector2.Length(), Microsoft.Xna.Framework.Color.Lerp(), Microsoft.Xna.Framework.MathHelper.Lerp(), Microsoft.Xna.Framework.Vector2.Lerp(), Terraria.NPC.life, Microsoft.Xna.Framework.Color.LightBlue, Microsoft.Xna.Framework.Color.LightPink, Microsoft.Xna.Framework.Color.LightSeaGreen, Microsoft.Xna.Framework.Color.LimeGreen, Terraria.NPC.localAI, Terraria.Main.LocalPlayer, System.Math.Max(), System.Math.Min(), Terraria.Main.netMode, Terraria.NPC.netOffset, Terraria.NPC.netSkip, Terraria.NPC.netUpdate, Terraria.Dust.NewDustDirect(), Terraria.NPC.noTileCollide, Terraria.Main.npc, System.Math.PI, Terraria.Main.player, Terraria.Audio.SoundEngine.PlaySound(), Microsoft.Xna.Framework.Graphics.Point, Terraria.Entity.position, Terraria.Main.rand, Microsoft.Xna.Framework.Color.RoyalBlue, Terraria.NetMessage.SendData(), System.Math.Sign(), Terraria.Collision.SolidCollision(), Terraria.WorldGen.SolidTile(), Terraria.NPC.spriteDirection, Terraria.NPC.target, Terraria.NPC.TargetClosest(), Terraria.DataStructures.Tile, Terraria.Main.tile, Terraria.Main.tileSolid, Terraria.NPC.type, Terraria.NPC.value, Microsoft.Xna.Framework.Graphics.Vector2, Terraria.Entity.velocity, Terraria.Entity.whoAmI, Terraria.Entity.width, Microsoft.Xna.Framework.Point.X, Microsoft.Xna.Framework.Vector2.X, Microsoft.Xna.Framework.Point.Y, and Microsoft.Xna.Framework.Vector2.Y.

Referenced by Terraria.NPC.AI().