225 lines
7.3 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|