Files

225 lines
7.3 KiB
C#

using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;
using ForgottenWawiTech.Content.Projectiles.Transcendent;
namespace ForgottenWawiTech.Content.Players
{
public class TranscendentPlayer : ModPlayer
{
private const int AccessoryShardInterval = 90;
private const int SetShardInterval = 45;
private const int AccessoryShardBaseDamage = 220;
private const int SetShardBaseDamage = 320;
private const int AscendantDroneCount = 4;
private const int AscendantDroneBaseDamage = 360;
private const int NaniteShardBaseDamage = 260;
public bool SwarmModuleEquipped;
private Item swarmAccessorySourceItem;
private int swarmTimer;
private int naniteShardCooldown;
private bool transcendentSetActive;
public void HandleSwarmAccessory(Item sourceItem)
{
SwarmModuleEquipped = true;
swarmAccessorySourceItem = sourceItem;
}
public void EnableTranscendentSet()
{
transcendentSetActive = true;
}
public bool HasTranscendentSet => transcendentSetActive;
public override void ResetEffects()
{
SwarmModuleEquipped = false;
transcendentSetActive = false;
swarmAccessorySourceItem = null;
}
public override void PostUpdate()
{
bool swarmActive = SwarmModuleEquipped || transcendentSetActive;
if (swarmActive && Player.whoAmI == Main.myPlayer)
{
int interval = transcendentSetActive ? SetShardInterval : AccessoryShardInterval;
swarmTimer++;
if (swarmTimer >= interval)
{
swarmTimer = 0;
SpawnAscendantShards(transcendentSetActive);
}
}
else if (Player.whoAmI == Main.myPlayer && swarmTimer > 0)
{
swarmTimer = 0;
}
if (naniteShardCooldown > 0)
{
naniteShardCooldown--;
}
if (transcendentSetActive)
{
MaintainAscendantDrones();
}
if (swarmActive)
{
if (Main.rand.NextBool(transcendentSetActive ? 4 : 6))
{
Dust dust = Dust.NewDustDirect(Player.position, Player.width, Player.height, DustID.RainbowTorch, Player.velocity.X * 0.2f, Player.velocity.Y * 0.2f, 150, default, 1.1f);
dust.noGravity = true;
}
}
}
private void SpawnAscendantShards(bool fromSet)
{
int baseDamage = fromSet ? SetShardBaseDamage : AccessoryShardBaseDamage;
int damage = (int)Player.GetDamage(DamageClass.Summon).ApplyTo(baseDamage);
float knockBack = fromSet ? 4f : 3f;
float speed = fromSet ? 8f : 6f;
int shardCount = fromSet ? 2 : 1;
if (!fromSet && swarmAccessorySourceItem == null)
{
swarmAccessorySourceItem = Player.HeldItem;
}
IEntitySource source = fromSet
? Player.GetSource_Misc("TranscendentAscendantSwarm")
: Player.GetSource_Accessory(swarmAccessorySourceItem ?? Player.HeldItem);
for (int i = 0; i < shardCount; i++)
{
Vector2 velocity = Main.rand.NextVector2Circular(speed, speed);
if (velocity.LengthSquared() < 0.01f)
{
velocity = new Vector2(0f, -speed);
}
Projectile shard = Projectile.NewProjectileDirect(
source,
Player.Center,
velocity,
ModContent.ProjectileType<TranscendentBladeShard>(),
damage,
knockBack,
Player.whoAmI);
shard.originalDamage = damage;
}
}
private void MaintainAscendantDrones()
{
if (Player.whoAmI != Main.myPlayer)
{
return;
}
int droneType = ModContent.ProjectileType<TranscendentAscendantDrone>();
int owned = Player.ownedProjectileCounts[droneType];
if (owned >= AscendantDroneCount)
{
return;
}
var source = Player.GetSource_Misc("TranscendentAscendantDrones");
for (int i = owned; i < AscendantDroneCount; i++)
{
Projectile.NewProjectile(
source,
Player.Center,
Vector2.Zero,
droneType,
0,
0f,
Player.whoAmI,
i,
AscendantDroneCount);
}
}
public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
{
TrySpawnNaniteShards(target.Center, damageDone);
}
public override void OnHitNPCWithProj(Projectile proj, NPC target, NPC.HitInfo hit, int damageDone)
{
if (proj.owner != Player.whoAmI || !proj.friendly)
{
return;
}
if (proj.type == ModContent.ProjectileType<TranscendentNaniteShard>() ||
proj.type == ModContent.ProjectileType<TranscendentAscendantBolt>() ||
proj.type == ModContent.ProjectileType<TranscendentBladeShard>())
{
return;
}
TrySpawnNaniteShards(target.Center, damageDone);
}
private void TrySpawnNaniteShards(Vector2 position, int damageDone)
{
if (!transcendentSetActive || Player.whoAmI != Main.myPlayer)
{
return;
}
if (damageDone <= 0 || naniteShardCooldown > 0)
{
return;
}
naniteShardCooldown = 8;
int baseDamage = GetNaniteShardDamage(Player);
int computed = Math.Max(baseDamage, damageDone / 2);
float speed = 13f;
var source = Player.GetSource_Misc("TranscendentNaniteShards");
for (int i = 0; i < 2; i++)
{
Vector2 velocity = Main.rand.NextVector2CircularEdge(1f, 1f) * speed;
if (velocity.LengthSquared() < 0.01f)
{
velocity = new Vector2(0f, -speed);
}
Projectile shard = Projectile.NewProjectileDirect(
source,
position,
velocity,
ModContent.ProjectileType<TranscendentNaniteShard>(),
computed,
2f,
Player.whoAmI);
shard.originalDamage = computed;
}
}
public static int GetAscendantDroneDamage(Player player)
{
return (int)player.GetTotalDamage(DamageClass.Summon).ApplyTo(AscendantDroneBaseDamage);
}
public static int GetNaniteShardDamage(Player player)
{
return (int)player.GetTotalDamage(DamageClass.Generic).ApplyTo(NaniteShardBaseDamage);
}
}
}