private void OnTargetNavigationComponentUpdate(TargetNavigation.Update update) { if (update.navigationFinished.Count > 0) { NPCUtils.NavigateToRandomNearbyPosition(navigation, navigation.transform.position, SimulationSettings.NPCOnFireWaypointDistance, SimulationSettings.NPCDefaultInteractionSqrDistance); } }
public override bool UseItem(Player player) { if (NPCUtils.SummonBossDirectlyWithMessage(player.Center - new Vector2(0f, 240f), ModContent.NPCType <CraterDemon>())) { Main.PlaySound(SoundID.ForceRoar, player.position, 0); } return(true); }
public static void create() { List <string> essential = new(); List <string> unique = new(); List <string> follower = new(); string essentialFile = Path.Combine(Path.GetTempPath(), "EssentialNPCs.txt"); string uniqueFile = Path.Combine(Path.GetTempPath(), "UniqueNPCs.txt"); string followerFile = Path.Combine(Path.GetTempPath(), "FollowerNPCs.txt"); string uniqueFollowers = Path.Combine(Path.GetTempPath(), "Unique+Followers.txt"); int npcs = 0; foreach (var npc in State.LoadOrder.PriorityOrder .WinningOverrides <INpcGetter>() .Where(x => !x.Configuration.Flags.HasFlag(NpcConfiguration.Flag.IsCharGenFacePreset) && x.Name != null && NPCUtils.IsFemale(x))) { var npcRace = npc.Race.Resolve <IRaceGetter>(Configuration.Cache); string race = npcRace.EditorID + " \"" + (npcRace.Name == null ? "" : npcRace.Name.String) + "\" [RACE:" + npcRace.FormKey.IDString() + "]"; string name = npc.Name == null ? "" : npc.Name.String; string mod = npc.FormKey.ModKey.FileName; string eid = npc.EditorID; string key = npc.FormKey.IDString().PadLeft(8, '0'); string line = mod + " | " + name + " | " + eid + " | " + race + " | " + key; if (NPCUtils.IsFollower(npc)) { follower.Add(line); } if (NPCUtils.IsUnique(npc)) { unique.Add(line); } if (NPCUtils.IsEssential(npc)) { essential.Add(line); } npcs++; } File.WriteAllLines(essentialFile, essential); File.WriteAllLines(uniqueFile, unique); File.WriteAllLines(followerFile, follower); File.WriteAllLines(uniqueFollowers, follower.Union(unique).Distinct()); Logger.InfoFormat("Created File: " + essentialFile); Logger.InfoFormat("Created File: " + uniqueFile); Logger.InfoFormat("Created File: " + follower); Logger.InfoFormat("Created File: " + uniqueFollowers); Logger.InfoFormat("Total NPCs for morphing: " + npcs); }
public override void AI() { //Die if parent dies or despawns if (!Parent.active || Parent.life <= 0) { projectile.active = false; } //Evenly spread out the rotations of all 3 runes if (!initialized) { rotation = RuneNumber * MathHelper.TwoPi / 3; projectile.netUpdate = true; initialized = true; } projectile.alpha = Math.Max(projectile.alpha - 5, 0); rotation += speed; speed = Math.Min(speed + ACCELERATION, MAX_SPEED); //Start decreasing in radius when speed is high enough if (speed > MAX_SPEED / 4) { radius -= 1.5f; if (radius <= MIN_RADIUS) { //Dont shoot a projectile if the target no longer exists bool playerUntargettable = (Target == null || Target.dead || !Target.active); //Only make one projectile shot directly at the player, by checking if it's the first rune that was spawned in if (RuneNumber == 0 && !playerUntargettable) { Projectile p = Projectile.NewProjectileDirect(Parent.Center, Vector2.Zero, ModContent.ProjectileType <HecateBoonProj>(), NPCUtils.ToActualDamage(Parent.damage), 1, Main.myPlayer, Parent.target); if (!Main.dedServ) { Main.PlaySound(SoundID.MaxMana, Parent.Center); ParticleHandler.SpawnParticle(new HecateSpawnParticle(p, new Color(255, 106, 250), 0.5f, 40)); } } projectile.Kill(); } } Vector2 offset = Vector2.UnitX.RotatedBy(rotation) * radius; projectile.Center = Parent.Center + offset; }
private void AddToStockpile() { var targetGameObject = NPCUtils.GetTargetGameObject(Owner.Data.targetEntityId); if (targetGameObject != null && NPCUtils.IsTargetATeamStockpile(parentBehaviour.gameObject, targetGameObject)) { var resourcesToAdd = inventory.Data.resources; SpatialOS.Commands.SendCommand(inventory, StockpileDepository.Commands.AddResource.Descriptor, new AddResource(resourcesToAdd), Owner.Data.targetEntityId, response => OnStockpileResponse(response, resourcesToAdd)); } else { Owner.TriggerTransition(LumberjackFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); } }
private void AttemptToHarvestTree() { var targetGameObject = NPCUtils.GetTargetGameObject(Owner.Data.targetEntityId); if (targetGameObject != null && NPCUtils.IsTargetAHealthyTree(parentBehaviour.gameObject, targetGameObject)) { SpatialOS.Commands.SendCommand(inventory, Harvestable.Commands.Harvest.Descriptor, new HarvestRequest(parentBehaviour.gameObject.EntityId()), Owner.Data.targetEntityId, OnHarvestResponse); } else { Owner.TriggerTransition(LumberjackFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); } }
private void StartMovingTowardsTargetEntity() { var targetGameObject = NPCUtils.GetTargetGameObject(Owner.Data.targetEntityId); if (targetGameObject == null) { Owner.TriggerTransition(WizardFSMState.StateEnum.IDLE, EntityId.InvalidEntityId, SimulationSettings.InvalidPosition); return; } if (NPCUtils.IsWithinInteractionRange(parentBehaviour.transform.position, targetGameObject.transform.position, SimulationSettings.NPCWizardSpellCastingSqrDistance)) { AttemptInteractionWithTarget(); return; } navigation.StartNavigation(Owner.Data.targetEntityId, SimulationSettings.NPCWizardSpellCastingSqrDistance); }
private EntityId FindNearestTargetToAttackOrDefend() { var layerMask = ~(1 << LayerMask.NameToLayer(SimulationSettings.TreeLayerName)); var nearestDefendableTarget = NPCUtils.FindNearestTarget(parentBehaviour.gameObject, SimulationSettings.NPCViewRadius, NPCUtils.IsTargetDefendable, layerMask); var nearestAttackableTarget = NPCUtils.FindNearestTarget(parentBehaviour.gameObject, SimulationSettings.NPCViewRadius, NPCUtils.IsTargetAttackable, layerMask); if (nearestDefendableTarget == null && nearestAttackableTarget == null) { return(EntityId.InvalidEntityId); } var sqrDistanceToNearestDefendableTarget = (nearestDefendableTarget != null) ? MathUtils.SqrDistance(parentBehaviour.transform.position, nearestDefendableTarget.transform.position) : float.MaxValue; var sqrDistanceToNearestAttackableTarget = (nearestAttackableTarget != null) ? MathUtils.SqrDistance(parentBehaviour.transform.position, nearestAttackableTarget.transform.position) : float.MaxValue; return((sqrDistanceToNearestDefendableTarget < sqrDistanceToNearestAttackableTarget) ? nearestDefendableTarget.gameObject.EntityId() : nearestAttackableTarget.gameObject.EntityId()); }
private void StartMovingTowardsTargetEntity() { var targetGameObject = NPCUtils.GetTargetGameObject(Owner.Data.targetEntityId); if (targetGameObject == null) { Owner.TriggerTransition(LumberjackFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); return; } if (NPCUtils.IsWithinInteractionRange(parentBehaviour.transform.position, targetGameObject.transform.position, SimulationSettings.NPCDefaultInteractionSqrDistance)) { InitiateInteractionWithTarget(); return; } navigation.StartNavigation(Owner.Data.targetEntityId, SimulationSettings.NPCDefaultInteractionSqrDistance); }
private void StartMovingTowardsTargetPosition() { var targetPosition = Owner.Data.targetPosition.ToVector3(); if (MathUtils.CompareEqualityEpsilon(targetPosition, SimulationSettings.InvalidPosition)) { Owner.TriggerTransition(LumberjackFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); return; } if (NPCUtils.IsWithinInteractionRange(parentBehaviour.transform.position, targetPosition, SimulationSettings.NPCDefaultInteractionSqrDistance)) { Owner.TriggerTransition(LumberjackFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); return; } navigation.StartNavigation(targetPosition, SimulationSettings.NPCDefaultInteractionSqrDistance); }
private void CastRainOnTarget() { var targetGameObject = NPCUtils.GetTargetGameObject(Owner.Data.targetEntityId); if (targetGameObject == null) { Owner.TriggerTransition(WizardFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); return; } if (NPCUtils.IsTargetDefendable(parentBehaviour.gameObject, targetGameObject)) { spellsBehaviour.CastSpell(SpellType.RAIN, targetGameObject.transform.position); } spellCastFinishDelayCoroutine = parentBehaviour.StartCoroutine(TimerUtils.WaitAndPerform(SimulationSettings.PlayerCastAnimationTime, () => { Owner.TriggerTransition(WizardFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); })); }
private void AttemptInteractionWithTarget() { var targetGameObject = NPCUtils.GetTargetGameObject(Owner.Data.targetEntityId); if (targetGameObject == null) { Owner.TriggerTransition(LumberjackFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); return; } if (NPCUtils.IsTargetAHealthyTree(parentBehaviour.gameObject, targetGameObject) && NPCUtils.IsWithinInteractionRange(parentBehaviour.transform.position, targetGameObject.transform.position, SimulationSettings.NPCDefaultInteractionSqrDistance)) { Owner.TriggerTransition(LumberjackFSMState.StateEnum.HARVESTING, Owner.Data.targetEntityId, SimulationSettings.InvalidPosition); return; } if (NPCUtils.IsTargetATeamStockpile(parentBehaviour.gameObject, targetGameObject) && NPCUtils.IsWithinInteractionRange(parentBehaviour.transform.position, targetGameObject.transform.position, SimulationSettings.NPCDefaultInteractionSqrDistance)) { Owner.TriggerTransition(LumberjackFSMState.StateEnum.STOCKPILING, Owner.Data.targetEntityId, SimulationSettings.InvalidPosition); return; } Owner.TriggerTransition(LumberjackFSMState.StateEnum.IDLE, new EntityId(), SimulationSettings.InvalidPosition); }
private void AttemptInteractionWithTarget() { var targetGameObject = NPCUtils.GetTargetGameObject(Owner.Data.targetEntityId); if (targetGameObject == null) { Owner.TriggerTransition(WizardFSMState.StateEnum.IDLE, EntityId.InvalidEntityId, SimulationSettings.InvalidPosition); return; } if (NPCUtils.IsTargetAttackable(parentBehaviour.gameObject, targetGameObject) && NPCUtils.IsWithinInteractionRange(parentBehaviour.transform.position, targetGameObject.transform.position, SimulationSettings.NPCWizardSpellCastingSqrDistance)) { Owner.TriggerTransition(WizardFSMState.StateEnum.ATTACKING_TARGET, Owner.Data.targetEntityId, SimulationSettings.InvalidPosition); return; } if (NPCUtils.IsTargetDefendable(parentBehaviour.gameObject, targetGameObject) && NPCUtils.IsWithinInteractionRange(parentBehaviour.transform.position, targetGameObject.transform.position, SimulationSettings.NPCWizardSpellCastingSqrDistance)) { Owner.TriggerTransition(WizardFSMState.StateEnum.DEFENDING_TARGET, Owner.Data.targetEntityId, SimulationSettings.InvalidPosition); return; } Owner.TriggerTransition(WizardFSMState.StateEnum.IDLE, EntityId.InvalidEntityId, SimulationSettings.InvalidPosition); }
private void CheckForNearbyTreesOrStockpiles() { GameObject targetEntity; if (inventory.HasResources()) { targetEntity = NPCUtils.FindNearestTarget(parentBehaviour.gameObject, SimulationSettings.NPCViewRadius, NPCUtils.IsTargetATeamStockpile, LayerMask.GetMask(SimulationSettings.BarrackLayerName)); if (targetEntity == null) { MoveCloserToHQ(); return; } } else { targetEntity = NPCUtils.FindNearestTarget(parentBehaviour.gameObject, SimulationSettings.NPCViewRadius, NPCUtils.IsTargetAHealthyTree, LayerMask.GetMask(SimulationSettings.TreeLayerName)); if (targetEntity == null) { MoveToRandomPlaceNearby(); return; } } MoveToEntity(targetEntity.EntityId()); }
private void BruteP1(Player Target) { int chargeTime = 40; float circleOpacity = 0.66f; int bruteSlamTime = BruteSlam.TOTALTIME; int restTime = 60; if (AiTimer < chargeTime) { npc.TargetClosest(true); } if (AiTimer <= chargeTime + bruteSlamTime) { UpdateYFrame(8, 0, 8, null, 4); _ritualCircle = Math.Min(_ritualCircle + circleOpacity / chargeTime, circleOpacity); if (AiTimer == chargeTime) { if (Main.netMode != NetmodeID.MultiplayerClient) { var proj = Projectile.NewProjectileDirect(npc.Bottom, Vector2.Zero, ModContent.ProjectileType <BruteSlam>(), NPCUtils.ToActualDamage(60, 1.5f), 1, Main.myPlayer, npc.whoAmI); proj.position.Y -= proj.height * 0.66f; if (Main.netMode != NetmodeID.SinglePlayer) { NetMessage.SendData(MessageID.SyncProjectile, -1, -1, null, proj.whoAmI); } } } } else { _ritualCircle = Math.Max(_ritualCircle - circleOpacity / restTime, 0f); UpdateYFrame(8, 8, 0, null, 0); } ResetAttackP1(chargeTime + bruteSlamTime + restTime); }
public override void Enter() { targetNavigation.ComponentUpdated += OnTargetNavigationComponentUpdate; NPCUtils.NavigateToRandomNearbyPosition(navigation, navigation.transform.position, SimulationSettings.NPCOnFireWaypointDistance, SimulationSettings.NPCDefaultInteractionSqrDistance); }
private void DaggersP1(Player target) { int daggerspintime = 40; if (AiTimer < daggerspintime) { npc.TargetClosest(true); } else { UpdateYFrame(8, 0, 8, null, 4); } if ((AiTimer == 1 || AiTimer == 20) && !Main.dedServ) { Texture2D dagger = mod.GetTexture("NPCs/Boss/Occultist/Projectiles/OccultistDagger"); Texture2D bloom = mod.GetTexture("Effects/Masks/CircleGradient"); float height = AiTimer == 1 ? 0 : -10; float radius = AiTimer == 1 ? 30 : 40; float scale = AiTimer == 1 ? 0.25f : 0.5f; float opacity = AiTimer == 1 ? 0.66f : 0.8f; float offset = AiTimer == 1 ? 0 : 10; for (int i = 0; i < 3; i++) { _rotMan.AddObject(bloom, height, radius, scale / 3, Color.Pink * opacity * 0.66f, -1, null, 60, 40 * i + offset); _rotMan.AddObject(dagger, height, radius, scale, Color.White * opacity, -1, null, 60, 40 * i + offset); } } if (AiTimer == daggerspintime && !Main.dedServ) { _rotMan.KillAllObjects(); } if (AiTimer > daggerspintime && AiTimer % 5 == 0 && AiTimer <= daggerspintime + 30) { if (Main.netMode != NetmodeID.MultiplayerClient) { float timer = AiTimer - daggerspintime + 10; if (npc.direction > 0) { timer = 40 - timer; } float angle = timer / 40 * MathHelper.Pi; Vector2 spawnPos = npc.Center - new Vector2(0, 500) + new Vector2(0, 300).RotatedBy((angle - MathHelper.PiOver2) / 2.5f); var proj = Projectile.NewProjectileDirect(spawnPos, Vector2.Zero, ModContent.ProjectileType <OccultistDagger>(), NPCUtils.ToActualDamage(40, 1.5f), 1f, Main.myPlayer, angle); proj.netUpdate = true; } } ResetAttackP1(daggerspintime + 60); }
private void WaveHandsP1(Player target) { int chargetime = 40; int attacktelegraphtime = 30; int attacktime = 30; if (AiTimer < chargetime) { npc.TargetClosest(true); if (AiTimer % 6 == 0) { AddRune(); } } if (AiTimer == chargetime && !Main.dedServ) { ParticleHandler.SpawnParticle(new OccultistTelegraphBeam(npc, (Vector2.UnitX * npc.direction).ToRotation(), 400, attacktelegraphtime)); } if (AiTimer > attacktelegraphtime + chargetime) { UpdateYFrame(11, 4, 8); if (AiTimer % 6 == 0) { Vector2 spawnPos = npc.Center + (Vector2.UnitX * npc.direction).RotatedByRandom(MathHelper.Pi / 4) * Main.rand.NextFloat(20, 40); Vector2 velocity = npc.direction * Vector2.UnitX * Main.rand.NextFloat(3, 4); if (Main.netMode != NetmodeID.MultiplayerClient) { float amplitude = Main.rand.NextFloat(5, 8); float periodOffset = Main.rand.Next(160); var proj = Projectile.NewProjectileDirect(spawnPos, velocity, ModContent.ProjectileType <OccultistHand>(), NPCUtils.ToActualDamage(40, 1.5f), 1f, Main.myPlayer, amplitude, periodOffset); proj.netUpdate = true; } } } else { UpdateYFrame(8, 0, 8, null, 4); } ResetAttackP1(attacktelegraphtime + chargetime + attacktime); }
private void SoulsP2(Player target) { npc.TargetClosest(true); int TPTime = 60; if (AiTimer <= TPTime) { npc.TargetClosest(true); Vector2 TPPosition = target.Center + Main.rand.NextVector2Unit() * Main.rand.NextFloat(150, 200); TeleportP2(TPPosition, TPTime); } else { float timer = AiTimer - TPTime; //make timing a bit simpler float attacktime = 130; frame.X = 1; UpdateYFrame(8, 4, 8); npc.velocity.Y = (float)Math.Sin(MathHelper.TwoPi * AiTimer / 90); npc.velocity.X = MathHelper.Lerp(npc.velocity.X, 0, 0.1f); if (timer % 10 == 0) { VisualSoul(2.5f); } if (AiTimer % 20 == 0 && !Main.dedServ) { ParticleHandler.SpawnParticle(new PulseCircle(npc.Center, new Color(252, 3, 148, 100) * 0.5f, 120, 12)); } if (timer % 12 == 0 && timer <= 60) { if (Main.netMode != NetmodeID.MultiplayerClient) { Vector2 vel = npc.DirectionFrom(target.Center).RotatedByRandom(MathHelper.PiOver2) * 4; Projectile.NewProjectileDirect(npc.Center + vel * Main.rand.NextFloat(10, 20), vel, ModContent.ProjectileType <OccultistSoul>(), NPCUtils.ToActualDamage(30, 1.5f), 1, Main.myPlayer, npc.whoAmI, target.whoAmI).netUpdate = true; } } if (timer > attacktime) { ResetAttackP2(); } } }
private void WaveHandsP2(Player target) { npc.TargetClosest(true); int TPTime = 60; if (AiTimer <= TPTime) { Vector2 TPPosition = target.Center + (target.velocity.X < 0 ? -1 : 1) * Vector2.UnitX * 300; TeleportP2(TPPosition, TPTime); } else { float timer = AiTimer - TPTime; //make timing a bit simpler if (timer % 6 == 0) { AddRune(); } if (timer < 80) //home in on the side of the player that's closer { Vector2 DesiredPosition = target.Center + (target.DirectionTo(npc.Center).X < 0 ? -1 : 1) * Vector2.UnitX * 300; DesiredPosition.Y += (float)Math.Sin(Main.GameUpdateCount / 10f) * 20; float accel = MathHelper.Clamp(npc.Distance(DesiredPosition) / 400, 0.1f, 0.4f); npc.AccelFlyingMovement(DesiredPosition, accel, 0.1f, 30); } else { npc.velocity = Vector2.Lerp(npc.velocity, Vector2.Zero, 0.085f); } if (timer > 80) { frame.X = 1; UpdateYFrame(8, 0, 8, delegate(int frameY) { if (frameY == 4 && Main.netMode != NetmodeID.MultiplayerClient && timer < 150) { Vector2 spawnPos = npc.Center + (Vector2.UnitX * npc.direction).RotatedByRandom(MathHelper.Pi / 4) * Main.rand.NextFloat(20, 40); float amplitude = 70; for (int i = -1; i <= 1; i++) { if (i == 0) { continue; } Projectile.NewProjectileDirect(spawnPos, npc.direction * Vector2.UnitX * 2.25f, ModContent.ProjectileType <OccultistHandFiery>(), NPCUtils.ToActualDamage(40, 1.5f), 1f, Main.myPlayer, amplitude * i, 60).netUpdate = true; } npc.velocity.X -= npc.direction * 5; npc.netUpdate = true; } }, 4); } else { frame.X = 0; UpdateYFrame(4, 0, 2); if (timer == 80) { frame.Y = 0; } } if (timer > 180) { ResetAttackP2(); } } }
private void DaggersP2(Player target) { int TPTime = 60; if (AiTimer <= TPTime) { npc.TargetClosest(true); Vector2 TPPosition = target.Center + (target.velocity.X < 0 ? -1 : 1) * Vector2.UnitX * 550 - Vector2.UnitY * 220; TeleportP2(TPPosition, TPTime); } else { float timer = AiTimer - TPTime; //make timing a bit simpler float attacktime = 140; float daggerstarttime = 40; if (timer == 1 && !Main.dedServ) { Texture2D dagger = mod.GetTexture("NPCs/Boss/Occultist/Projectiles/OccultistDagger"); Texture2D bloom = mod.GetTexture("Effects/Masks/CircleGradient"); float radius = 30; float scale = 0.5f; float opacity = 0.8f; for (int i = 0; i < 3; i++) { _rotMan.AddObject(bloom, 0, radius, scale / 3, Color.Pink * opacity * 0.66f, -1, null, 60, 40 * i, MathHelper.Pi); _rotMan.AddObject(dagger, 0, radius, scale, Color.White * opacity, -1, null, 60, 40 * i, MathHelper.Pi); } for (int j = 0; j < 5; j++) { _rotMan.AddObject(bloom, 10, radius * 1.5f, scale / 3, Color.Pink * opacity * 0.66f, -1, null, 60, 24 * j, MathHelper.Pi); _rotMan.AddObject(dagger, 10, radius * 1.5f, scale, Color.White * opacity, -1, null, 60, 24 * j, MathHelper.Pi); } } if (timer < daggerstarttime) //home in on the side of the player that's closer { Vector2 DesiredPosition = target.Center + (target.DirectionTo(npc.Center).X < 0 ? -1 : 1) * Vector2.UnitX * 550 - Vector2.UnitY * 220; float accel = MathHelper.Clamp(npc.Distance(DesiredPosition) / 400, 0.1f, 0.4f); npc.AccelFlyingMovement(DesiredPosition, accel, 0.15f, 30); } else //move in direction it's facing, with quadratic easing formula to smooth out velocity { float progress = Math.Max((timer - daggerstarttime) / (attacktime - daggerstarttime), 0); npc.velocity.Y = (float)Math.Sin(MathHelper.TwoPi * AiTimer / 90); npc.velocity.X = npc.direction * 22f * (progress < 0.5f ? 4 * (float)Math.Pow(progress, 2) : (float)Math.Pow(-2 * progress + 2, 2)); } if (timer % 7 == 0 && Main.netMode != NetmodeID.Server && timer > daggerstarttime) { var proj = Projectile.NewProjectileDirect(npc.Center + Main.rand.NextVector2CircularEdge(30, 50), Vector2.Zero, ModContent.ProjectileType <OccultistDagger>(), NPCUtils.ToActualDamage(40, 1.5f), 1f, Main.myPlayer, Main.rand.NextFloat(-0.12f, 0.12f) + MathHelper.PiOver2); proj.netUpdate = true; } frame.X = 0; UpdateYFrame(7, 0, 2); if (timer > attacktime) { if (!Main.dedServ) { _rotMan.KillAllObjects(); } ResetAttackP2(); } } }
private void SoulsP1(Player Target) { npc.TargetClosest(true); if (AiTimer <= 30) { UpdateYFrame(8, 4, 8); if (AiTimer % 15 == 0) { Vector2 vel = npc.DirectionFrom(Target.Center).RotatedByRandom(MathHelper.PiOver2) * 14; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectileDirect(npc.Center + vel, vel.RotatedByRandom(MathHelper.Pi / 12), ModContent.ProjectileType <OccultistSoul>(), NPCUtils.ToActualDamage(30, 1.5f), 1, Main.myPlayer, Main.rand.NextBool() ? -1 : 1, Target.whoAmI).netUpdate = true; } if (!Main.dedServ) { ParticleHandler.SpawnParticle(new PulseCircle(npc.Center, new Color(252, 3, 148) * 0.6f, 120, 15) { RingColor = new Color(255, 115, 239) * 0.4f }); ParticleHandler.SpawnParticle(new StarParticle(npc.Center + vel, vel / 8, Color.Lerp(Color.Red, Color.White, 0.15f), 0.5f, 20, 4f)); for (int i = 0; i < 4; i++) { ParticleHandler.SpawnParticle(new OccultistSoulVisual(npc.Center + vel * Main.rand.NextFloat(), vel.RotatedByRandom(MathHelper.Pi / 12) * Main.rand.NextFloat(0.2f, 0.7f), Main.rand.NextFloat(0.4f, 0.5f), 30)); } } } } else { UpdateYFrame(8, 8, 0, null, 0); } ResetAttackP1(150); }
public override void AI() { Player player = Main.player[npc.target]; bool expertMode = Main.expertMode; Lighting.AddLight((int)((npc.position.X + (float)(npc.width / 2)) / 16f), (int)((npc.position.Y + (float)(npc.height / 2)) / 16f), 0f, 0.075f, 0.25f); int parent = NPC.FindFirstNPC(ModContent.NPCType <SteamRaiderHead>()); if (parent < 0 || parent >= Main.npc.Length) { npc.active = false; return; } if (!Main.npc[(int)npc.ai[1]].active) { npc.life = 0; npc.HitEffect(0, 10.0); npc.active = false; } if (Main.npc[parent].ai[2] != 1) { if (Main.netMode != NetmodeID.MultiplayerClient) { npc.localAI[0] += expertMode ? 2f : 1f; if (npc.localAI[0] >= 200f) { npc.localAI[0] = 0f; npc.TargetClosest(true); if (Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height)) { Main.PlaySound(SoundID.Item, (int)npc.Center.X, (int)npc.Center.Y, 12); float num941 = 4f; //speed Vector2 vector104 = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)(npc.height / 2)); float num942 = player.position.X + (float)player.width * 0.5f - vector104.X + (float)Main.rand.Next(-20, 21); float num943 = player.position.Y + (float)player.height * 0.5f - vector104.Y + (float)Main.rand.Next(-20, 21); float num944 = (float)Math.Sqrt((double)(num942 * num942 + num943 * num943)); num944 = num941 / num944; num942 *= num944; num943 *= num944; //int num946 = 440; vector104.X += num942 * 5f; vector104.Y += num943 * 5f; int num947 = Projectile.NewProjectile(vector104.X, vector104.Y, num942, num943, ModContent.ProjectileType <GlitchLaser>(), NPCUtils.ToActualDamage(25, 1.5f), 0f, Main.myPlayer, 0f, 0f); Main.projectile[num947].timeLeft = 300; npc.netUpdate = true; } } } } else { npc.localAI[0] = 0; } if ((Main.npc[parent].life <= Main.npc[parent].lifeMax * 0.75f)) { Main.PlaySound(SoundID.Item, (int)npc.Center.X, (int)npc.Center.Y, 14); npc.life = 0; npc.HitEffect(0, 10.0); npc.active = false; NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <TailProbe>(), npc.whoAmI, 0f, 0f, 0f, 0f, 255); Main.PlaySound(SoundID.Roar, (int)npc.position.X, (int)npc.position.Y, 0); Main.PlaySound(SoundID.Item, (int)npc.position.X, (int)npc.position.Y, 4); npc.position.X = npc.position.X + (float)(npc.width / 2); npc.position.Y = npc.position.Y + (float)(npc.height / 2); npc.width = 30; npc.height = 30; npc.position.X = npc.position.X - (float)(npc.width / 2); npc.position.Y = npc.position.Y - (float)(npc.height / 2); for (int num621 = 0; num621 < 20; num621++) { int num622 = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y), npc.width, npc.height, 226, 0f, 0f, 100, default(Color), 2f); Main.dust[num622].velocity *= 3f; if (Main.rand.Next(2) == 0) { Main.dust[num622].scale = 0.5f; Main.dust[num622].fadeIn = 1f + (float)Main.rand.Next(10) * 0.1f; } } for (int num623 = 0; num623 < 40; num623++) { int num624 = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y), npc.width, npc.height, 226, 0f, 0f, 100, default(Color), 3f); Main.dust[num624].noGravity = true; Main.dust[num624].velocity *= 5f; num624 = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y), npc.width, npc.height, 180, 0f, 0f, 100, default(Color), 2f); Main.dust[num624].velocity *= 2f; } } if (Main.npc[(int)npc.ai[1]].alpha < 128) { if (npc.alpha != 0) { for (int num934 = 0; num934 < 2; num934++) { int num935 = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y), npc.width, npc.height, 226, 0f, 0f, 100, default(Color), 2f); Main.dust[num935].noGravity = true; Main.dust[num935].noLight = true; } } npc.alpha -= 42; if (npc.alpha < 0) { npc.alpha = 0; } } if (npc.ai[2] > 0) { npc.realLife = (int)npc.ai[2]; } if (npc.target < 0 || npc.target == byte.MaxValue || Main.player[npc.target].dead) { npc.TargetClosest(true); } if (npc.ai[1] < (double)Main.npc.Length) { // We're getting the center of this NPC. Vector2 npcCenter = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f); // Then using that center, we calculate the direction towards the 'parent NPC' of this NPC. float dirX = Main.npc[(int)npc.ai[1]].position.X + (float)(Main.npc[(int)npc.ai[1]].width / 2) - npcCenter.X; float dirY = Main.npc[(int)npc.ai[1]].position.Y + (float)(Main.npc[(int)npc.ai[1]].height / 2) - npcCenter.Y; // We then use Atan2 to get a correct rotation towards that parent NPC. npc.rotation = (float)Math.Atan2(dirY, dirX) + 1.57f; // We also get the length of the direction vector. float length = (float)Math.Sqrt(dirX * dirX + dirY * dirY); // We calculate a new, correct distance. float dist = (length - (float)npc.width) / length; float posX = dirX * dist; float posY = dirY * dist; // Reset the velocity of this NPC, because we don't want it to move on its own npc.velocity = Vector2.Zero; // And set this NPCs position accordingly to that of this NPCs parent NPC. npc.position.X = npc.position.X + posX; npc.position.Y = npc.position.Y + posY; } }
public override bool PreAI() { npc.TargetClosest(true); Lighting.AddLight(new Vector2(npc.Center.X, npc.Center.Y), 0.075f * 2, 0.231f * 2, 0.255f * 2); Player target = Main.player[npc.target]; npc.spriteDirection = npc.direction; Vector2 vector2_1 = target.Center - npc.Center + new Vector2(0, -100f); float distance = vector2_1.Length(); Vector2 desiredVelocity = npc.velocity; if (distance < 20) { desiredVelocity.Normalize(); } if (distance < 40.0) { desiredVelocity = vector2_1 * (5f * 0.025f); } else if (distance < 80.0) { desiredVelocity = vector2_1 * (5f * 0.075f); } else { desiredVelocity = vector2_1 * 5f; } npc.SimpleFlyMovement(desiredVelocity, 0.05f); npc.rotation = npc.velocity.X * 0.1f; if (npc.ai[0] == 0f) { for (int i = 0; i < 5; i++) { Vector2 vel = Vector2.UnitY.RotatedByRandom(MathHelper.Pi) * new Vector2(Main.rand.Next(3, 8), Main.rand.Next(3, 8)); int p = Projectile.NewProjectile(npc.Center.X + Main.rand.Next(-20, 20), npc.Center.Y + Main.rand.Next(-20, 20), vel.X, vel.Y, ModContent.ProjectileType <ElectricJellyfishOrbiter>(), NPCUtils.ToActualDamage(10, 1.5f), 0.0f, Main.myPlayer, 0.0f, npc.whoAmI); Main.projectile[p].scale = Main.rand.NextFloat(.6f, .95f); Main.projectile[p].ai[0] = npc.whoAmI; npc.ai[0] = 1f; npc.netUpdate = true; } } return(false); }
static public void HandlePacket(BinaryReader reader, int whoAmI) { Message msg = (Message)reader.ReadByte(); Dictionary <DataTag, object> tags = new Dictionary <DataTag, object>(); foreach (DataTag tag in dataTags[msg]) { tags.Add(tag, tag.read(reader)); } switch (msg) { case Message.SyncLevel: RPGPlayer p = Main.player[(int)tags[DataTag.playerId]].GetModPlayer <RPGPlayer>(); if (p.baseName == "") { p.baseName = Main.player[(int)tags[DataTag.playerId]].name; } if ((int)tags[DataTag.playerId] != Main.myPlayer) { if (Main.netMode != NetmodeID.SinglePlayer) { p.SyncLevel((int)tags[DataTag.amount]); } Main.player[(int)tags[DataTag.playerId]].name = p.baseName + " The Lvl." + p.GetLevel() + " " + (string)tags[DataTag.buffer]; } break; case Message.AddXP: Main.LocalPlayer.GetModPlayer <RPGPlayer>().AddXp((int)tags[DataTag.amount], (int)tags[DataTag.level]); break; case Message.SyncNPCSpawn: if (Main.netMode == NetmodeID.MultiplayerClient) { NPC npc = Main.npc[(int)tags[DataTag.npcId]]; if (npc.GetGlobalNPC <ARPGGlobalNPC>() == null) { AnotherRpgMod.Instance.Logger.Info(npc.GivenName); } //npc.SetDefaults(npc.type); if (npc.GetGlobalNPC <ARPGGlobalNPC>().StatsCreated == true) { return; } int tier = (int)tags[DataTag.tier]; int level = (int)tags[DataTag.level]; NPCRank rank = (NPCRank)tags[DataTag.rank]; NPCModifier modifiers = (NPCModifier)tags[DataTag.modifiers]; if (npc == null || npc.GetGlobalNPC <ARPGGlobalNPC>() == null) { return; } AnotherRpgMod.Instance.Logger.Info(npc.GivenOrTypeName + "\nTier : " + tier + " Level : " + level + " rank : " + rank + " Modifier : " + modifiers + " \n Buffer : " + (string)tags[DataTag.buffer]); Dictionary <string, string> bufferStack = Unparse((string)tags[DataTag.buffer]); WorldManager.BossDefeated = (int)tags[DataTag.WorldTier]; npc.GetGlobalNPC <ARPGGlobalNPC>().StatsCreated = true; npc.GetGlobalNPC <ARPGGlobalNPC>().modifier = modifiers; npc.GetGlobalNPC <ARPGGlobalNPC>().SetLevelTier(level, tier, (byte)rank); npc.GetGlobalNPC <ARPGGlobalNPC>().specialBuffer = bufferStack; npc.GetGlobalNPC <ARPGGlobalNPC>().SetStats(npc); npc.GivenName = NPCUtils.GetNpcNameChange(npc, tier, level, rank); //AnotherRpgMod.Instance.Logger.Info("NPC created with id : " + npc.whoAmI); //AnotherRpgMod.Instance.Logger.Info( "Client Side : \n" + npc.GetGivenOrTypeNetName() + "\nLvl." + (npc.GetGlobalNPC<ARPGGlobalNPC>().getLevel + npc.GetGlobalNPC<ARPGGlobalNPC>().getTier) + "\nHealth : " + npc.life + " / " + npc.lifeMax + "\nDamage : " + npc.damage + "\nDef : " + npc.defense + "\nTier : " + npc.GetGlobalNPC<ARPGGlobalNPC>().getRank + "\n\n"); } break; case Message.SyncNPCUpdate: if (Main.netMode == NetmodeID.MultiplayerClient) { NPC npcu = Main.npc[(int)tags[DataTag.npcId]]; if (npcu.lifeMax != (int)tags[DataTag.maxLife] || npcu.life != (int)tags[DataTag.life]) { AnotherRpgMod.Instance.Logger.Warn("DESYNC ERROR SPOTTED FOR : "); AnotherRpgMod.Instance.Logger.Warn(npcu.GivenOrTypeName + "\n" + (int)tags[DataTag.life] + " / " + (int)tags[DataTag.maxLife] + "\n" + npcu.life + " / " + npcu.lifeMax); } Main.npc[(int)tags[DataTag.npcId]].lifeMax = (int)tags[DataTag.maxLife]; Main.npc[(int)tags[DataTag.npcId]].life = (int)tags[DataTag.life]; } break; case Message.Log: if (Main.netMode == NetmodeID.MultiplayerClient) { //ErrorLogger.Log("LOG FROM SERVER"); AnotherRpgMod.Instance.Logger.Info((string)tags[DataTag.buffer]); } break; case Message.AskNpc: if (Main.netMode == NetmodeID.Server) { NPC npc = Main.npc[(int)tags[DataTag.npcId]]; if (npc.GetGlobalNPC <ARPGGlobalNPC>() == null) { return; } int tier = npc.GetGlobalNPC <ARPGGlobalNPC>().getTier; int level = npc.GetGlobalNPC <ARPGGlobalNPC>().getLevel; int rank = npc.GetGlobalNPC <ARPGGlobalNPC>().getRank; Mod mod = AnotherRpgMod.Instance; //MPDebug.Log(mod, "Server Side : \n" + npc.GetGivenOrTypeNetName() + " ID : " + npc.whoAmI + "\nLvl." + (npc.GetGlobalNPC<ARPGGlobalNPC>().getLevel + npc.GetGlobalNPC<ARPGGlobalNPC>().getTier) + "\nHealth : " + npc.life + " / " + npc.lifeMax + "\nDamage : " + npc.damage + "\nDef : " + npc.defense + "\nTier : " + npc.GetGlobalNPC<ARPGGlobalNPC>().getRank + "\n"); SendNpcSpawn(mod, npc, tier, level, npc.GetGlobalNPC <ARPGGlobalNPC>()); } break; } }
public override bool PreAI() { var exposedBodies = Main.npc.Where(x => x.active && (x.type == ModContent.NPCType <FungalDiggerBody>() || x.type == ModContent.NPCType <FungalDiggerTail>()) && x.localAI[0] > 0).Count(); if (Main.netMode != NetmodeID.MultiplayerClient) { if (exposedBodies < 7 && Main.rand.NextBool(50) || (++npc.localAI[1] % 60 == 0 && Main.rand.NextBool(50))) { if (!Exposed) { npc.localAI[0] = 1; npc.netUpdate = true; } } if (exposedBodies > 10 || (npc.localAI[1] % 60 == 0 && Main.rand.NextBool(50))) { if (Exposed) { npc.localAI[0] = 0; npc.netUpdate = true; } } if (npc.localAI[2] >= 601) { npc.localAI[2] = 0f; } } if (Exposed) { npc.defense = 22; npc.dontTakeDamage = false; } Player player = Main.player[npc.target]; if (Head.ai[2] == 1) { if (Main.netMode != NetmodeID.MultiplayerClient) { if (--npc.ai[3] == 0) { Main.PlaySound(SoundID.Item, (int)npc.position.X, (int)npc.position.Y, 9); npc.TargetClosest(true); npc.netUpdate = true; if (Main.rand.NextBool(2)) { float num941 = 1f; Vector2 vector104 = new Vector2(npc.position.X + npc.width * 0.5f, npc.position.Y + npc.height / 2); float num942 = player.position.X + player.width * 0.5f - vector104.X + Main.rand.Next(-20, 21); float num943 = player.position.Y + player.height * 0.5f - vector104.Y + Main.rand.Next(-20, 21); float num944 = (float)Math.Sqrt(num942 * num942 + num943 * num943); num944 = num941 / num944; num942 *= num944; num943 *= num944; num942 += Main.rand.Next(-10, 11) * 0.0125f; num943 += Main.rand.Next(-10, 11) * 0.0125f; int num946 = ModContent.ProjectileType <GlowingMushroom>(); vector104.X += num942 * 4f; vector104.Y += num943 * 2.5f; int num947 = Projectile.NewProjectile(vector104.X, vector104.Y, num942, num943, num946, NPCUtils.RealDamage(25, 1.25f), 0f, Main.myPlayer, 0f, 0f); Main.projectile[num947].timeLeft = 350; } } } if (Main.netMode == NetmodeID.MultiplayerClient) { if (--npc.ai[3] == 0) { Main.PlaySound(SoundID.Item, (int)npc.position.X, (int)npc.position.Y, 9); } } } else { npc.ai[3] = Main.rand.Next(175, 190); } if (!Main.npc[(int)npc.ai[1]].active) { npc.life = 0; npc.HitEffect(0, 10.0); npc.active = false; } if (npc.ai[2] > 0) { npc.realLife = (int)npc.ai[2]; } if (npc.target < 0 || npc.target == byte.MaxValue || Main.player[npc.target].dead) { npc.TargetClosest(true); } if (Main.player[npc.target].dead && npc.timeLeft > 300) { npc.timeLeft = 300; } if (npc.ai[1] < (double)Main.npc.Length) { Vector2 npcCenter = new Vector2(npc.position.X + npc.width * 0.5f, npc.position.Y + npc.height * 0.5f); float dirX = Main.npc[(int)npc.ai[1]].position.X + Main.npc[(int)npc.ai[1]].width / 2 - npcCenter.X; float dirY = Main.npc[(int)npc.ai[1]].position.Y + Main.npc[(int)npc.ai[1]].height / 2 - npcCenter.Y; npc.rotation = (float)Math.Atan2(dirY, dirX) + 1.57f; float length = (float)Math.Sqrt(dirX * dirX + dirY * dirY); float dist = (length - (float)npc.width) / length; float posX = dirX * dist; float posY = dirY * dist; npc.velocity = Vector2.Zero; npc.position.X = npc.position.X + posX; npc.position.Y = npc.position.Y + posY; } return(true); }
public override void AI() { Player player = Main.player[npc.target]; float lifeRatio = (float)npc.life / npc.lifeMax; int jumpHeight = Main.rand.Next(5); npc.TargetClosest(true); Vector2 range = npc.Center - player.Center; range.Normalize(); if (npc.velocity.Y == 0) { npc.velocity.X = 0f; } if (!player.active || player.dead) { npc.ai[1] = 0; npc.ai[2] = 0; npc.TargetClosest(false); npc.noTileCollide = true; npc.velocity.Y++; } if (npc.velocity.Y > 0 && npc.position.Y < player.Center.Y - (npc.height + 125) && !npc.collideX && !npc.collideY) { npc.noTileCollide = true; } else { npc.noTileCollide = false; } if (npc.ai[0] == 0) { trail = false; npc.ai[2]++; if (npc.ai[2] >= 600) { npc.ai[0] = 1; npc.ai[1] = 0; npc.ai[2] = 0; } npc.ai[1]++; if (npc.ai[1] >= 180 && npc.velocity.Y == 0) { if (npc.Center.X >= player.Center.X) { npc.velocity.X -= 5; } if (npc.Center.X <= player.Center.X) { npc.velocity.X += 5; } if (jumpHeight < 3) { npc.velocity.Y -= 12; } else { npc.velocity.Y -= 11; } npc.ai[1] = 0; } } if (npc.ai[0] == 1) { trail = false; text = false; npc.ai[2]++; if (npc.ai[2] >= 70 && lifeRatio >= 0.5 || npc.ai[2] >= 130 && lifeRatio < 0.5) { npc.ai[0] = 2; npc.ai[1] = 0; npc.ai[2] = 0; } npc.ai[1]++; if (npc.ai[1] == 60 && !text) { CombatText.NewText(new Rectangle((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height), new Color(20, 100, 100), "Releasing Missiles"); text = true; } if (npc.ai[1] >= 60 && npc.velocity.Y == 0) { for (int i = 0; i < 10; i++) { Main.PlaySound(SoundID.Item61, npc.Center); int p = Projectile.NewProjectile(npc.Center.X + Main.rand.Next(-60, 60), npc.Center.Y + Main.rand.Next(-60, 60), Main.rand.NextFloat(-5.3f, 5.3f), Main.rand.NextFloat(-5.3f, 5.3f), ModContent.ProjectileType <CyborgMissile>(), NPCUtils.RealDamage(20, 1.5f), 1, Main.myPlayer, 0, 0); if (Main.projectile[p].velocity == Vector2.Zero) { Main.projectile[p].velocity = new Vector2(2.5f, 2.5f); } if (Main.projectile[p].velocity.X <2.5f && Math.Sign(Main.projectile[p].velocity.X) == Math.Sign(1) || Main.projectile[p].velocity.X> -2.5f && Math.Sign(Main.projectile[p].velocity.X) == Math.Sign(-1)) { Main.projectile[p].velocity.X *= 2.35f; } } npc.ai[1] = 0; } } if (npc.ai[0] == 2) { trail = false; npc.ai[2]++; if (npc.ai[2] >= 480) { npc.ai[0] = 3; npc.ai[1] = 0; npc.ai[2] = 0; } npc.ai[1]++; if (npc.ai[1] >= 120 && npc.velocity.Y == 0) { if (npc.Center.X >= player.Center.X) { npc.velocity.X -= 5; } if (npc.Center.X <= player.Center.X) { npc.velocity.X += 5; } if (jumpHeight < 3) { npc.velocity.Y -= 12; } else { npc.velocity.Y -= 11; } npc.ai[1] = 0; } } if (npc.ai[0] == 3) { trail = true; if (!exploded) { npc.position.Y = player.Center.Y - 600f; npc.position.X = player.Center.X - npc.width * 0.5f; npc.velocity.X = 0; for (int z = 0; z < 30; z++) { Dust.NewDust(npc.position, npc.width, npc.height, DustID.Electric, 0f, 0f, 0, default, 2f);
private void Attack() { if (Main.netMode != NetmodeID.MultiplayerClient) { var vel = new Vector2(npc.direction * 5, 0); Projectile.NewProjectile(npc.Center - vel, vel, ModContent.ProjectileType <PirateLobberBarrel>(), NPCUtils.ToActualDamage(60, 1.3f), 5); } Main.PlaySound(SoundID.Item, npc.Center, 1); }
public override void AI() { Player player = Main.player[npc.target]; bool expertMode = Main.expertMode; Lighting.AddLight((int)((npc.position.X + (float)(npc.width / 2)) / 16f), (int)((npc.position.Y + (float)(npc.height / 2)) / 16f), 0f, 0.075f, 0.25f); int parent = NPC.FindFirstNPC(ModContent.NPCType <SteamRaiderHead>()); if (parent < 0 || parent >= Main.npc.Length) { npc.active = false; return; } if (!Main.npc[(int)npc.ai[1]].active) { npc.life = 0; npc.HitEffect(0, 10.0); npc.active = false; } if (Main.npc[parent].ai[2] != 1) { if (Main.netMode != NetmodeID.MultiplayerClient) { npc.localAI[0] += expertMode ? 2f : 1f; if (npc.localAI[0] >= 200f) { npc.localAI[0] = 0f; npc.TargetClosest(true); if (Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height)) { Main.PlaySound(SoundID.Item, (int)npc.Center.X, (int)npc.Center.Y, 12); float num941 = 4f; //speed Vector2 vector104 = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)(npc.height / 2)); float num942 = player.position.X + (float)player.width * 0.5f - vector104.X + (float)Main.rand.Next(-20, 21); float num943 = player.position.Y + (float)player.height * 0.5f - vector104.Y + (float)Main.rand.Next(-20, 21); float num944 = (float)Math.Sqrt((double)(num942 * num942 + num943 * num943)); num944 = num941 / num944; num942 *= num944; num943 *= num944; //int num946 = 440; vector104.X += num942 * 5f; vector104.Y += num943 * 5f; int num947 = Projectile.NewProjectile(vector104.X, vector104.Y, num942, num943, ModContent.ProjectileType <GlitchLaser>(), NPCUtils.ToActualDamage(25, 1.5f), 0f, Main.myPlayer, 0f, 0f); Main.projectile[num947].timeLeft = 300; npc.netUpdate = true; } } } } else { npc.localAI[0] = 0; } if ((Main.npc[parent].life <= Main.npc[parent].lifeMax * 0.75f)) { Main.PlaySound(SoundID.Item, (int)npc.Center.X, (int)npc.Center.Y, 14); npc.life = 0; npc.HitEffect(0, 10.0); npc.active = false; NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <TailProbe>(), npc.whoAmI, 0f, 0f, 0f, 0f, 255); Main.PlaySound(SoundID.Roar, (int)npc.position.X, (int)npc.position.Y, 0); Main.PlaySound(SoundID.Item, (int)npc.position.X, (int)npc.position.Y, 4); npc.position.X = npc.position.X + (float)(npc.width / 2); npc.position.Y = npc.position.Y + (float)(npc.height / 2); npc.width = 30; npc.height = 30; npc.position.X = npc.position.X - (float)(npc.width / 2); npc.position.Y = npc.position.Y - (float)(npc.height / 2); for (int num621 = 0; num621 < 20; num621++) { int num622 = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y), npc.width, npc.height, DustID.Electric, 0f, 0f, 100, default, 2f);
public override void ModifyHitPvp(Player target, ref int damage, ref bool crit) => damage = NPCUtils.ToActualDamage(damage);