//This is used for controlling certain Chaos Mode functionality public override void NPCLoot(NPC npc) { base.NPCLoot(npc); if (chaosMode()) { if (painted) { switch (npc.type) { case NPCID.EyeofCthulhu: case NPCID.Spazmatism: case NPCID.Retinazer: case NPCID.Skeleton: case NPCID.SkeletronHand: case NPCID.SkeletronPrime: case NPCID.PrimeCannon: case NPCID.PrimeLaser: case NPCID.PrimeSaw: case NPCID.PrimeVice: case NPCID.BrainofCthulhu: case NPCID.KingSlime: case NPCID.Everscream: case NPCID.SantaNK1: case NPCID.IceQueen: case NPCID.Plantera: case NPCID.MourningWood: case NPCID.WallofFlesh: case NPCID.WallofFleshEye: case NPCID.DukeFishron: case NPCID.MoonLordCore: case NPCID.QueenBee: case NPCID.DD2OgreT2: case NPCID.DD2OgreT3: case NPCID.DD2Betsy: case NPCID.DD2DarkMageT1: case NPCID.DD2DarkMageT3: if (true) { Vector2 dir = new Vector2(1, 0); List <PaintingProjectile> projectiles = new List <PaintingProjectile>(); for (int i = 0; i < 8; i++) { Vector2 rotatedDir = dir.RotatedBy((PI / 4f) * i); PaintSplatter p = createPaintSplatter(npc.whoAmI, npc.Center + rotatedDir * 48, rotatedDir * 10, 100, .5f, 2f); if (p != null) { projectiles.Add(p); } rotatedDir = rotatedDir.RotatedBy(PI / 8f); PaintSplatter p2 = createPaintSplatter(npc.whoAmI, npc.Center + rotatedDir * 32, rotatedDir * 6, 100); if (p2 != null) { projectiles.Add(p2); } } if (singlePlayer()) { for (int i = 0; i < 20; i++) { Dust d = Dust.NewDustDirect(npc.Center - npc.Size / 4f, npc.width / 2, npc.height / 2, DustType <PaintDust>(), 0, 0, 0, getColor(_paintData), 2); if (d != null) { d.velocity = (d.position - npc.Center).SafeNormalize(new Vector2(1, 0)) * 5; if (d.customData != null) { ((float[])d.customData)[0] = 0; } } } } if (server()) { PaintingProjectile.sendMultiProjNPCOwnerPacket(projectiles); } } break; } } if (npc.townNPC) { if (npc.type == NPCID.PartyGirl) { splatterColored(npc.Center, 8, new byte[] { PaintID.DeepRed, PaintID.DeepRed, PaintID.DeepOrange, PaintID.DeepYellow, PaintID.DeepGreen, PaintID.DeepBlue, PaintID.DeepPurple }, new PaintData(1, PaintMethods.BlocksAndWalls), true); for (int i = 0; i < 10; i++) { Vector2 vel = new Vector2(Main.rand.NextFloat(2, 3), 0).RotatedBy(Main.rand.NextFloat(PI * 2)); Dust.NewDust(npc.Center - npc.Size / 4f, npc.width / 2, npc.height / 2, DustID.Confetti + Main.rand.Next(0, 4), vel.X, vel.Y, 0); } } else { PaintData data = new PaintData(PaintID.DeepRed); splatter(npc.Center, 100f, 8, data, true); } } } }
public override void PostAI(Projectile projectile) { if ((singlePlayer() || server()) && painted) { switch (projectile.type) { case ProjectileID.SandnadoHostile: if (projectile.timeLeft > 930 && Main.rand.NextFloat() < .25f) { float y = Main.rand.NextFloat(projectile.height * .6f, projectile.height); Vector2 pos = new Vector2(projectile.position.X + projectile.width / 2f, projectile.position.Y + projectile.height - y); int dir = Main.rand.Next(0, 2) * 2 - 1; Projectile proj = Projectile.NewProjectileDirect(pos, new Vector2(6f * dir, -6f - (float)Math.Sqrt(y / 8f)), ProjectileType <PaintSplatter>(), 0, 0); if (proj != null) { proj.timeLeft = (int)Math.Round(30f + (2f * y)); PaintingProjectile p = proj.modProjectile as PaintingProjectile; if (p != null) { p.npcOwner = projectile.GetGlobalProjectile <WoMDProjectile>().npcOwner; if (server()) { PaintingProjectile.sendProjNPCOwnerPacket(p); } } } } break; case ProjectileID.BulletDeadeye: paint(projectile.Center, _paintData); break; case ProjectileID.PaladinsHammerHostile: if (true) { Color c = getColor(_paintData); Lighting.AddLight(projectile.Center, c.ToVector3() * .5f); NPC npc = getNPC(npcOwner); if (projectile.timeLeft % 30 == 0 && npc != null && projectile.timeLeft >= 3400) { float dSquare = ((getNPC(npcOwner).Center - projectile.Center) / 16f).LengthSquared(); //1600 is 40 blocks away from paladin //2500 is 50 blocks away from paladin if (dSquare >= 1600 && dSquare <= 2500) { Vector2 hammerTop = projectile.Center + new Vector2(0, -16 * 9).RotatedBy(projectile.rotation); List <Point> paintedTiles = new List <Point>(); paintBetweenPoints(projectile.Center, hammerTop, _paintData, paintedTiles: paintedTiles); Vector2 shaftOffset = (projectile.Center - hammerTop).SafeNormalize(default); Vector2 headOffset = shaftOffset.RotatedBy(Math.PI / 2f) * 64; for (int i = 0; i <= 64; i += 8) { paintBetweenPoints(hammerTop + (shaftOffset * i) + headOffset, hammerTop + (shaftOffset * i) - headOffset, _paintData, paintedTiles: paintedTiles); } foreach (Point p in paintedTiles) { Dust d = Dust.NewDustPerfect(p.ToWorldCoordinates(), DustType <PaintDust>(), new Vector2(0, 0), default, c, 2f); if (d != null && d.customData != null) { ((float[])d.customData)[0] = 0; } } } }
//This is used for controlling certain Chaos Mode functionality public override void PostAI(NPC npc) { base.PostAI(npc); if ((Main.netMode == NetmodeID.SinglePlayer || Main.netMode == NetmodeID.Server) && chaosMode()) { if (painted) { switch (npc.aiStyle) { case 1: //slime if (npc.oldVelocity.Y > 2 && npc.velocity.Y == 0 && Main.rand.NextFloat() < .5f) { Point minTile = npc.BottomLeft.ToTileCoordinates(); Point maxTile = npc.BottomRight.ToTileCoordinates(); if (!(WorldGen.InWorld(minTile.X, minTile.Y + 1, 10) && WorldGen.InWorld(maxTile.X, maxTile.Y + 1, 10))) { break; } bool foundGround = false; for (int i = minTile.X; i <= maxTile.X && !foundGround; i++) { if (WorldGen.SolidOrSlopedTile(i, minTile.Y + 1)) { foundGround = true; } } if (!foundGround) { break; } Vector2 startVector = new Vector2(0, -6).RotatedBy(Math.PI / -3); int numSplatters = 7; for (int i = 0; i < numSplatters; i++) { Projectile p = Projectile.NewProjectileDirect(npc.Bottom - new Vector2(0, 8), startVector.RotatedBy(((Math.PI * 2f / 3f) / (numSplatters - 1)) * i), ProjectileType <PaintSplatter>(), 0, 0); if (p != null) { PaintingProjectile proj = (PaintingProjectile)p.modProjectile; proj.npcOwner = npc.whoAmI; p.timeLeft = 60; PaintingProjectile.sendProjNPCOwnerPacket(proj); } } } break; } switch (npc.type) { case NPCID.EyeofCthulhu: //the eye starts spinning when ai[0] == 1 if (npc.ai[0] == 1 && npc.ai[1] >= 20 && npc.ai[1] % 2 == 0) { //the eye stops spinning when ai[1] > 99 (ai[1] never == 100. it is immediately reset back to 0) int count = npc.ai[1] >= 40 && npc.ai[1] <= 60 ? 2 : 1; Vector2 dir = new Vector2(1, 0).RotatedBy(Main.rand.NextFloat(0, PI * 2)); Vector2 offset = dir * ((npc.width / 2f) * npc.scale); float initialSpeed = ((float)Math.Pow(30 - Math.Abs(50 - npc.ai[1]), 2) / 900f) * 4f + 3f; for (int i = 0; i < count; i++) { if (i == 1) { dir = dir.RotatedBy(PI); offset *= -1; } float speed = initialSpeed; if (dir.Y > .5f && dir.X <= 0) { speed += 2; } else if (dir.Y < 0 && dir.X < 0) { speed += 1; } Vector2 vel = dir.RotatedBy(PI / 2f) * speed; Projectile p = Projectile.NewProjectileDirect(npc.Center + offset, vel, ProjectileType <PaintSplatter>(), 0, 0); if (p != null) { p.velocity = vel; p.timeLeft = 100; PaintingProjectile proj = p.modProjectile as PaintingProjectile; if (proj != null) { proj.npcOwner = npc.whoAmI; if (server()) { PaintingProjectile.sendProjNPCOwnerPacket(proj); } } } } } break; } } } }
//Handles assigning new projectiles npc owners public override bool PreAI(Projectile projectile) { if (server() || singlePlayer()) { if (!projectile.friendly && !setupPreAi) { if (GetInstance <WoMDConfig>().chaosModeEnabled) { setupPreAi = true; switch (projectile.type) { case ProjectileID.WoodenArrowHostile: if (true) { if (server()) { break; //running into issues making this work in multiplayer } NPC archer = Main.npc .Where(npc => npc.type == NPCID.CultistArcherBlue || npc.type == NPCID.GoblinArcher) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (archer != null) { WoMDNPC gNpc = archer.GetGlobalNPC <WoMDNPC>(); if (gNpc == null || !gNpc.painted) { break; } int projId = Projectile.NewProjectile(projectile.Center, projectile.velocity, ProjectileType <PaintArrow>(), projectile.damage, projectile.knockBack); Projectile newArrow = getProjectile(projId); if (newArrow == null) { break; } PaintArrow arrow = (PaintArrow)newArrow.modProjectile; cloneProperties(projectile, arrow.projectile); arrow.npcOwner = archer.whoAmI; arrow.projectile.GetGlobalProjectile <WoMDProjectile>().setupPreAi = true; projectile.timeLeft = 0; if (server()) { PaintingProjectile.sendProjNPCOwnerPacket(arrow); } } } break; case ProjectileID.RainNimbus: if (true) { NPC nimbus = Main.npc .Where(npc => npc.type == NPCID.AngryNimbus) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (nimbus != null) { applyPaintedFromNpc(projectile, nimbus); } } break; case ProjectileID.SandnadoHostileMark: case ProjectileID.SandnadoHostile: if (true) { NPC elemental = Main.npc .Where(npc => npc.type == NPCID.SandElemental) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (elemental != null) { applyPaintedFromNpc(projectile, elemental); } } break; case ProjectileID.BulletDeadeye: if (true) { NPC enemy = Main.npc .Where(npc => new int[] { NPCID.TacticalSkeleton, NPCID.SantaNK1, NPCID.ElfCopter, NPCID.PirateDeadeye, NPCID.PirateCaptain }.Contains(npc.type)) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); Vector2 enemyPos = enemy.Center; float range = 20; switch (enemy.type) { case NPCID.SantaNK1: enemyPos = enemy.Center + (projectile.velocity * 2.75f); range = 130; break; case NPCID.ElfCopter: range = 30; break; } float dist = Math.Abs(enemyPos.X - projectile.Center.X) + Math.Abs(enemyPos.Y - projectile.Center.Y); if (dist < range) { applyPaintedFromNpc(projectile, enemy); } } break; case ProjectileID.HappyBomb: if (true) { NPC enemy = Main.npc .Where(npc => npc.type == NPCID.Clown) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (enemy != null) { float dist = Math.Abs(enemy.Center.X - projectile.Center.X) + Math.Abs(enemy.Center.Y - projectile.Center.Y); if (dist < 64) { applyPaintedFromNpc(projectile, enemy); } } } break; case ProjectileID.InfernoHostileBolt: if (true) { NPC enemy = Main.npc .Where(npc => npc.type == NPCID.DiabolistRed || npc.type == NPCID.DiabolistWhite) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (enemy != null) { float dist = Math.Abs(enemy.Center.X - projectile.Center.X) + Math.Abs(enemy.Center.Y - projectile.Center.Y); if (dist <= 20) { applyPaintedFromNpc(projectile, enemy); } } } break; case ProjectileID.PaladinsHammerHostile: if (true) { NPC enemy = Main.npc .Where(npc => npc.type == NPCID.Paladin) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (enemy != null) { WoMDNPC gNpc = enemy.GetGlobalNPC <WoMDNPC>(); if (gNpc != null && gNpc.painted) { float dist = Math.Abs(enemy.Center.X - projectile.Center.X) + Math.Abs(enemy.Center.Y - projectile.Center.Y); if (dist <= 25) { applyPaintedFromNpc(projectile, enemy); projectile.Opacity = 0; projectile.alpha = 0; } } } } break; } } } } return(base.PreAI(projectile)); }