Untitled
unknown
csharp
2 years ago
6.7 kB
8
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