Files
ForgottenWawiTech/Content/Projectiles/FragmentedPrism/FragmentedPrismController.cs
T

152 lines
5.1 KiB
C#

using Microsoft.Xna.Framework;
using Terraria;
using Terraria.Audio;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;
namespace ForgottenWawiTech.Content.Projectiles.FragmentedPrism
{
public class FragmentedPrismController : ModProjectile
{
public const int ShardCount = 5;
public const float ChargeTimePerShard = 24f;
private const float ChargeDecayRate = 3f;
private const int ShardSpawnDelay = 4;
public static float MaxChargeTime => ChargeTimePerShard * ShardCount;
private ref float SpawnTimer => ref Projectile.ai[0];
private ref float ChargeTimer => ref Projectile.ai[1];
private ref float LastFiringCount => ref Projectile.localAI[0];
public override string Texture => "Terraria/Images/Projectile_0";
public override void SetDefaults()
{
Projectile.width = 10;
Projectile.height = 10;
Projectile.friendly = false;
Projectile.hostile = false;
Projectile.penetrate = -1;
Projectile.tileCollide = false;
Projectile.ignoreWater = true;
Projectile.hide = true;
Projectile.DamageType = DamageClass.Magic;
}
public override void AI()
{
Player player = Main.player[Projectile.owner];
int itemType = ModContent.ItemType<Items.Weapons.Magic.FragmentedPrism>();
if (!player.active || player.dead || player.HeldItem.type != itemType)
{
Projectile.Kill();
return;
}
player.heldProj = Projectile.whoAmI;
if (player.channel || ChargeTimer > 0f)
{
player.itemAnimation = player.itemTime = 2;
player.SetDummyItemTime(2);
}
Projectile.Center = player.Center;
Projectile.timeLeft = 2;
if (Main.myPlayer == player.whoAmI)
{
SpawnTimer++;
if (SpawnTimer >= ShardSpawnDelay)
{
SpawnTimer = 0f;
TrySpawnShard(player);
}
}
float maxCharge = MaxChargeTime;
if (player.channel)
{
ChargeTimer = MathHelper.Clamp(ChargeTimer + 1f, 0f, maxCharge);
}
else
{
ChargeTimer = MathHelper.Clamp(ChargeTimer - ChargeDecayRate, 0f, maxCharge);
}
int currentFiringCount = (int)MathHelper.Clamp(ChargeTimer / ChargeTimePerShard, 0f, ShardCount);
if (currentFiringCount > LastFiringCount)
{
SoundEngine.PlaySound(SoundID.Item117 with { Volume = 0.45f, Pitch = 0.3f }, player.Center);
Projectile.netUpdate = true;
}
else if (currentFiringCount < LastFiringCount)
{
Projectile.netUpdate = true;
}
LastFiringCount = currentFiringCount;
}
public override void OnKill(int timeLeft)
{
if (Main.player[Projectile.owner] is not Player player)
{
return;
}
for (int i = 0; i < Main.maxProjectiles; i++)
{
Projectile other = Main.projectile[i];
if (other.active && other.owner == Projectile.owner && other.type == ModContent.ProjectileType<FragmentedPrismShard>())
{
other.Kill();
}
}
}
private void TrySpawnShard(Player player)
{
int shardType = ModContent.ProjectileType<FragmentedPrismShard>();
bool[] occupied = new bool[ShardCount];
for (int i = 0; i < Main.maxProjectiles; i++)
{
Projectile shard = Main.projectile[i];
if (shard.active && shard.owner == player.whoAmI && shard.type == shardType)
{
int slot = (int)shard.ai[0];
if (slot >= 0 && slot < ShardCount)
{
occupied[slot] = true;
}
}
}
IEntitySource source = player.GetSource_ItemUse_WithPotentialAmmo(player.HeldItem, AmmoID.None);
bool spawnedAny = false;
for (int index = 0; index < ShardCount; index++)
{
if (occupied[index])
{
continue;
}
int proj = Projectile.NewProjectile(source, player.Center, Vector2.Zero, shardType, Projectile.damage, Projectile.knockBack, player.whoAmI, index);
if (Main.projectile.IndexInRange(proj))
{
Main.projectile[proj].originalDamage = Projectile.damage;
Main.projectile[proj].ai[1] = MathHelper.TwoPi * (index / (float)ShardCount);
}
spawnedAny = true;
}
if (spawnedAny)
{
SoundEngine.PlaySound(SoundID.Item4 with { Volume = 0.35f, Pitch = -0.3f }, player.Center);
}
}
}
}