Refactor and redo Shattered Prism
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user