Untitled
unknown
csharp
a year ago
6.7 kB
7
Indexable
namespace AncientLegacy.Content.Items.Weapons.Spectre { public class LostWispBuff : ModBuff { public override string Texture => "AncientLegacy/Content/Buffs/BuffNull"; public override void SetStaticDefaults() { Main.buffNoSave[Type] = false; Main.buffNoTimeDisplay[Type] = true; } public override void Update(Player player, ref int buffIndex) { if (player.ownedProjectileCounts[ModContent.ProjectileType<LostWisp>()] > 0) { player.buffTime[buffIndex] = 18000; } else { player.DelBuff(buffIndex); buffIndex--; } } } public class LostWisp : ModProjectile { public override void SetStaticDefaults() { ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; Main.projPet[Projectile.type] = true; ProjectileID.Sets.MinionSacrificable[Projectile.type] = true; ProjectileID.Sets.CultistIsResistantTo[Projectile.type] = true; } public override bool PreAI() { Player player = Main.player[Projectile.owner]; return true; } public sealed override void SetDefaults() { Projectile.width = 16; Projectile.height = 16; Projectile.tileCollide = false; Projectile.friendly = true; Projectile.minion = true; Projectile.DamageType = DamageClass.Magic; Projectile.penetrate = 0; Projectile.light = 0.9f; Projectile.minionSlots = 1f; } public override bool? CanCutTiles() { return false; } public override bool MinionContactDamage() { return false; } public int attackCounter; public override void SendExtraAI(BinaryWriter writer) { writer.Write(attackCounter); } public override void ReceiveExtraAI(BinaryReader reader) { attackCounter = reader.ReadInt32(); } public float speed = 0.1f; private bool CheckActive(Player owner) { if (owner.dead || !owner.active) { owner.ClearBuff(ModContent.BuffType<LostWispBuff>()); return false; } if (owner.HasBuff(ModContent.BuffType<LostWispBuff>())) { Projectile.timeLeft = 2; return true; } return true; } private void GeneralBehavior(Player owner, out Vector2 vectorToIdlePosition, out float distanceToIdlePosition) { Vector2 idlePosition = owner.Center; idlePosition.Y -= 48f; // Go up 48 coordinates (three tiles from the center of the player) // If your minion doesn't aimlessly move around when it's idle, you need to "put" it into the line of other summoned minions // The index is projectile.minionPos float minionPositionOffsetX = (10 + Projectile.minionPos * 40) * -owner.direction; idlePosition.X += minionPositionOffsetX; // Go behind the player // All of this code below this line is adapted from Spazmamini code (ID 388, aiStyle 66) // Teleport to player if distance is too big vectorToIdlePosition = idlePosition - Projectile.Center; distanceToIdlePosition = vectorToIdlePosition.Length(); if (Main.myPlayer == owner.whoAmI && distanceToIdlePosition > 2000f) { // Whenever you deal with non-regular events that change the behavior or position drastically, make sure to only run the code on the owner of the projectile, // and then set netUpdate to true Projectile.position = idlePosition; Projectile.velocity *= 0.1f; Projectile.netUpdate = true; } // If your minion is flying, you want to do this independently of any conditions float overlapVelocity = 0.04f; // Fix overlap with other minions for (int i = 0; i < Main.maxProjectiles; i++) { Projectile other = Main.projectile[i]; if (i != Projectile.whoAmI && other.active && other.owner == Projectile.owner && Math.Abs(Projectile.position.X - other.position.X) + Math.Abs(Projectile.position.Y - other.position.Y) < Projectile.width) { if (Projectile.position.X < other.position.X) { Projectile.velocity.X -= overlapVelocity; } else { Projectile.velocity.X += overlapVelocity; } if (Projectile.position.Y < other.position.Y) { Projectile.velocity.Y -= overlapVelocity; } else { Projectile.velocity.Y += overlapVelocity; } } } } private void Visuals() { Lighting.AddLight(Projectile.Center, Color.Blue.ToVector3() * 0.78f); } public NPC FindClosestNPC(float maxDetectDistance) { NPC closestNPC = null; float sqrMaxDetectDistance = maxDetectDistance * maxDetectDistance; for (int k = 0; k < Main.maxNPCs; k++) { NPC target = Main.npc[k]; if (target.CanBeChasedBy()) { float sqrDistanceToTarget = Vector2.DistanceSquared(target.Center, Projectile.Center); if (sqrDistanceToTarget < sqrMaxDetectDistance) { sqrMaxDetectDistance = sqrDistanceToTarget; closestNPC = target; } } } return closestNPC; } public override void AI() { float maxDetectDistance = 1024f; Player owner = Main.player[Projectile.owner]; if (!CheckActive(owner)) { return; } if (Main.netMode != NetmodeID.MultiplayerClient) { if (attackCounter > 0) { attackCounter--; // tick down the attack counter. } } Visuals(); GeneralBehavior(owner, out Vector2 vectorToIdlePosition, out float distanceToIdlePosition); NPC closestNPC = FindClosestNPC(maxDetectDistance); if (closestNPC == null) return; if (attackCounter <= 0 && Vector2.Distance(Projectile.Center, closestNPC.Center) < 1024 && Collision.CanHit(Projectile.Center, 1, 1, closestNPC.Center, 1, 1)) { Vector2 direction = (closestNPC.Center - Projectile.Center).SafeNormalize(Vector2.UnitX); direction = direction.RotatedByRandom(MathHelper.ToRadians(1)); int projectile = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, direction * 20, ModContent.ProjectileType<OtherworldlyFlame>(), Projectile.damage, 1, Main.myPlayer); attackCounter = 20; } } } public class LostWispBuff : ModBuff { public override string Texture => "AncientLegacy/Content/Buffs/BuffNull"; public override void SetStaticDefaults() { Main.buffNoSave[Type] = false; Main.buffNoTimeDisplay[Type] = true; } public override void Update(Player player, ref int buffIndex) { if (player.ownedProjectileCounts[ModContent.ProjectileType<LostWisp>()] > 0) { player.buffTime[buffIndex] = 18000; } else { player.DelBuff(buffIndex); buffIndex--; } } } }
Editor is loading...
Leave a Comment