Untitled

 avatar
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