public override void AI() { npc.velocity.X = 0; npc.gfxOffY = (float)Math.Sin(sinCounter) * 6f; sinCounter += 0.03f; if (npc.alpha > 0) { npc.alpha -= 10; } else { npc.alpha = 0; } if (Vector2.DistanceSquared(npc.Center, Main.LocalPlayer.Center) < EVENT_RADIUS * EVENT_RADIUS && spawnedBoss && bossWhoAmI == -1) { musicVolume = Math.Max(musicVolume - 0.0125f, 0); //Fully fade out music when event is done } else { musicVolume = Math.Min(musicVolume + 0.0125f, 1f); } if (spawnedComets && comets.Count <= 0) //once all small comets have been defeated { if (spawnedBoss) { if (NPC.AnyNPCs(ModContent.NPCType <Enemies.Archon.Archon>()) || NPC.AnyNPCs(ModContent.NPCType <Enemies.Warden.Warden>())) { musicVolume = Math.Min(musicVolume + 0.0125f, 1f); } else { npc.dontTakeDamage = false; shieldOpacity = MathHelper.Lerp(shieldOpacity, 0, 0.05f); //musicVolume = Math.Max(musicVolume - 0.0125f, 0); //Fully fade out music when event is done StarjinxPlayer localSjinxPlayer = Main.LocalPlayer.GetModPlayer <StarjinxPlayer>(); VignettePlayer localVignettePlayer = Main.LocalPlayer.GetModPlayer <VignettePlayer>(); if (localSjinxPlayer.zoneStarjinxEvent || localSjinxPlayer.oldZoneStarjinx) { localVignettePlayer.SetVignette(0, 1000, 0.75f, Color.Black, npc.Center); } } } else { int boss = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y - 400, ModContent.NPCType <Enemies.Warden.Warden>()); StarjinxEventWorld.SetMaxEnemies(2); StarjinxEventWorld.SetComets(comets.Count); spawnedBoss = true; bossWhoAmI = boss; } } if (spawnedComets) { bool anyPlayerInRange = false; for (int i = 0; i < Main.maxPlayers; i++) //Check if players are in range { Player player = Main.player[i]; if (player.active && !player.dead) { if (player.DistanceSQ(npc.Center) < EVENT_RADIUS * EVENT_RADIUS) { player.GetModPlayer <StarjinxPlayer>().zoneStarjinxEvent = true; player.GetModPlayer <StarjinxPlayer>().StarjinxPosition = npc.Center; anyPlayerInRange = true; } //else if (player.GetModPlayer<StarjinxPlayer>().oldZoneStarjinx) //{ //} } } if (!anyPlayerInRange) //Reset event { savedComets["Small"] = savedComets["Medium"] = savedComets["Large"] = -1; //So we "save" if all of them are dead IterateComets((SmallComet comet) => { savedComets[comet.Size]++; comet.npc.active = false; }); spawnedComets = false; comets.Clear(); DespawnPlatforms(); npc.life = npc.lifeMax; //Reset the meteor completely npc.dontTakeDamage = false; shieldOpacity = 0f; } if (npc.dontTakeDamage && comets.Count > 0) //Child meteor active checks { shieldOpacity = MathHelper.Lerp(shieldOpacity, 1, 0.05f); for (int i = 0; i < comets.Count; i++) { NPC comet = Main.npc[comets[i]]; int[] cometTypes = new int[] { ModContent.NPCType <LargeComet>(), ModContent.NPCType <SmallComet>(), ModContent.NPCType <MediumComet>() }; if (comet.active && comet.life > 0 && cometTypes.Contains(comet.type)) { break; } } if (updateCometOrder) { for (int i = 0; i < comets.Count; i++) //update list { NPC comet = Main.npc[comets[i]]; if (!comet.active || comet.modNPC == null || !(comet.modNPC is SmallComet)) { comets.Remove(comets[i]); i--; continue; } } if (comets.Count <= 0) { return; } NPC furthest = Main.npc[comets[0]]; for (int i = 0; i < comets.Count; i++) { NPC comet = Main.npc[comets[i]]; if (comet.active && comet.modNPC is SmallComet npc && furthest.modNPC is SmallComet far && npc.initialDistance > far.initialDistance) { furthest = comet; } } for (int i = 0; i < comets.Count; i++) { NPC comet = Main.npc[comets[i]]; if (comet.active && comet.modNPC is SmallComet) { comet.dontTakeDamage = true; } if (comet.whoAmI == furthest.whoAmI) { (comet.modNPC as SmallComet).nextUp = true; } } npc.netUpdate = true; updateCometOrder = false; StarjinxEventWorld.SetComets(comets.Count); //Update to new comet amount } bool anyVulnerable = false; foreach (int cometID in comets) { if (!Main.npc[cometID].dontTakeDamage) { anyVulnerable = true; } } if (anyVulnerable) //Make music quieter when a comet is vulnerable to damage, and bring back up the volume when it's dead { musicVolume = Math.Max(musicVolume - 0.0125f, 0.5f); } else { musicVolume = Math.Min(musicVolume + 0.0125f, 1f); } } } if (!spawnedComets && npc.life < npc.lifeMax) //Spawn meteors below max health (when I take damage) and start the event { bool validPlayer = false; for (int i = 0; i < Main.maxPlayers; ++i) //Search for valid player in order to start event { Player p = Main.player[i]; if (p.active && !p.dead && p.DistanceSQ(npc.Center) < 1500 * 1500) { validPlayer = true; break; } } if (validPlayer) { SpawnPlatforms(); spawnedComets = true; npc.dontTakeDamage = true; ModContent.GetInstance <StarjinxEventWorld>().StarjinxActive = true; NetMessage.SendData(MessageID.WorldData); SpawnComets(); } } musicVolume = MathHelper.Clamp(musicVolume, 0, 1); //Just in case, been getting some debug messages about value not being valid Main.musicFade[Main.curMusic] = musicVolume; }
private void SpawnComets() { int maxSmallComets = savedComets["Small"] == -2 ? 3 : savedComets["Small"] + 1; //Use cached values if respawning comets int maxMedComets = savedComets["Medium"] == -2 ? 2 : savedComets["Medium"] + 1; int maxLargeComets = savedComets["Large"] == -2 ? 1 : savedComets["Large"] + 1; const float MaxDist = 450; const float MinDist = 80; float FindDistance() { float maxComets = maxLargeComets + maxMedComets + maxSmallComets; return(MathHelper.Lerp(MaxDist, MinDist, comets.Count / maxComets)); } void SpawnComet(int type) { Vector2 spawnPos = npc.Center + Vector2.UnitX.RotatedByRandom(MathHelper.TwoPi) * FindDistance(); int id = NPC.NewNPC((int)spawnPos.X, (int)spawnPos.Y, type, npc.whoAmI, npc.whoAmI, comets.Count * 2, 0, -1); Main.npc[id].Center = spawnPos; Main.npc[id].dontTakeDamage = true; if (Main.netMode != NetmodeID.SinglePlayer) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, id); } if (comets.Count <= 0 && (savedComets["Small"] != -1 || savedComets["Medium"] != -1 || savedComets["Large"] != -1)) { //Kinda ugly but it makes sure the respawned comet is next up if (Main.npc[id].modNPC != null && Main.npc[id].modNPC is SmallComet comet) { comet.nextUp = true; } } comets.Add(id); npc.netUpdate = true; } for (int i = 0; i < maxSmallComets; i++) { SpawnComet(ModContent.NPCType <SmallComet>()); } for (int i = 0; i < maxMedComets; i++) { SpawnComet(ModContent.NPCType <MediumComet>()); } for (int i = 0; i < maxLargeComets; i++) { SpawnComet(ModContent.NPCType <LargeComet>()); } savedComets["Small"] = savedComets["Medium"] = savedComets["Large"] = -2; //clear out cache StarjinxUI.Initialize(); StarjinxEventWorld.SetComets(comets.Count); //Set comet amount for ui purposes StarjinxEventWorld.SetMaxEnemies(1); //Initialize max enemies as well, in case of potential edge cases }