Files
Cielonos/Assets/Scripts/MainGame/Items/MainWeapons/FutureWand/FutureWand_AttackAreas.cs

214 lines
10 KiB
C#
Raw Normal View History

2026-06-27 12:52:03 -04:00
using System.Collections.Generic;
using Cielonos.MainGame.Characters;
using Cielonos.MainGame.Buffs.Character;
using Lean.Pool;
using SLSUtilities.General;
using SLSUtilities.WwiseAssistance;
using UnityEngine;
namespace Cielonos.MainGame.Inventory.Collections
{
public partial class FutureWand
{
private void GenerateLightning(string vfxName, AttackUnit attackUnit, CharacterBase target)
{
if(target == null) return;
vfxData.SpawnMuzzleVFX(vfxName, player, Muzzle);
NormalArea lightning = vfxData.SpawnVFX(vfxName, player).GetComponentInChildren<NormalArea>();
lightning.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackUnit)
.SetTimeSubmodule<NormalArea>(2f, 0.1f)
.SetHitSubmodule<NormalArea>();
lightning.hitSm.AddHitEvent((enemy, hitPosition) => new LightningBuff().Apply(enemy, player, this));
lightning.topParent.transform.position = target.transform.position;
AudioManager.Post(AK.EVENTS.FUTUREWAND_MEDIUMATTACKHIT, target.transform.position);
}
private void GenerateProjectile(string vfxName, AttackUnit attackUnit,
CharacterBase target, float speed, bool hasMuzzleEffect = true, Transform muzzle = null)
{
if (hasMuzzleEffect)
{
muzzle ??= Muzzle;
vfxData.SpawnMuzzleVFX(vfxName, player, muzzle);
}
Projectile projectile = vfxData.SpawnVFX(vfxName, player).GetComponentInChildren<Projectile>();
Vector3 direction = player.transform.forward;
if (target != null)
{
direction = (target.CenterPoint.position - projectile.transform.position).normalized;
}
projectile.Initialize(player, this, false, 1, Fraction.Enemy)
.SetAttackSubmodule<Projectile>(attackUnit)
.SetTimeSubmodule<Projectile>(10f)
.SetHitSubmodule<Projectile>()
.SetAdaptiveTraceMoveSubmodule<Projectile>(target, speed, 5f, 180f, 30f, direction, detectRadius: 25f)
.SetRaycastSubmodule<Projectile>(default, 0.25f, 0.5f);
if (vfxName == "NormalBolt")
{
projectile.hitSm.AddHitSound(AK.EVENTS.FUTUREWAND_WEAKATTACKHIT);
projectile.SetImpulseSubmodule().WithDynamicForce(1f);
AudioManager.Post(AK.EVENTS.FUTUREWAND_NORMALBOLTRELEASE, projectile.gameObject);
}
else if (vfxName == "CubicBolt")
{
projectile.hitSm.AddHitSound(AK.EVENTS.FUTUREWAND_MEDIUMATTACKHIT);
projectile.SetImpulseSubmodule().WithDynamicForce(2f);
AudioManager.Post(AK.EVENTS.FUTUREWAND_CUBICBOLTRELEASE, projectile.gameObject);
}
int fusionStack = attackUnit.GetSubmodule<AttackUnit.ParameterSubmodule>().GetParameter<int>("Buff_Fusion_Stack");
projectile.hitSm.AddHitEvent((enemy, hitPosition) =>
{
new Fusion(fusionStack).Apply(enemy);
SubscribeFusionExplode(enemy);
if (!projectile.tags.Contains("Separation") && HasExtender<MissileSeparationMembrane>())
{
//如果装备了 MissileSeparationMembrane且该投射物没有“Separation”标签即不是分离出来的投射物则在命中时生成一个分离投射物指向附近的随机敌人
List<Enemy> nearbyEnemies = CombatManager.EnemySm.GetEnemiesInRadius(hitPosition, 25f).Exclude(enemy as Enemy);
if (nearbyEnemies.Count > 0)
{
Projectile separation = vfxData.SpawnVFX(vfxName, player, hitPosition, Quaternion.identity).GetComponentInChildren<Projectile>();
nearbyEnemies.TryGetRandom(out Enemy randomTarget);
Vector3 sepDirection = (randomTarget.CenterPoint.position - hitPosition).normalized;
separation.Initialize(player, this, false, 1, Fraction.Enemy)
.SetAttackSubmodule<Projectile>(attackUnit)
.SetTimeSubmodule<Projectile>(10f)
.SetHitSubmodule<Projectile>()
.SetLinearDirectionMoveModule<Projectile>(sepDirection, speed, 5f);
separation.tags.Add("Separation");
separation.hitSm.AddCheckedObject(enemy.gameObject);
separation.SetRaycastSubmodule<Projectile>(default, 0.25f, 0.5f);
}
}
});
}
private void GenerateGroundArea(string vfxName, AttackUnit attackUnit)
{
vfxData.SpawnMuzzleVFX(vfxName, player, Muzzle);
NormalArea area = vfxData.SpawnVFX(vfxName, player).GetComponentInChildren<NormalArea>();
AudioManager.Post(AK.EVENTS.FUTUREWAND_GROUNDAREA, area.gameObject);
if (!HasExtender<BlackHoleDisplacer>())
{
area.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackUnit)
.SetTimeSubmodule<NormalArea>(3f, 0.2f, 0.8f)
.SetHitSubmodule<NormalArea>(0.1f, 4);
}
else //如果装备了 BlackHoleDisplacer这个区域将向前/后进行移动
{
area.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackUnit)
.SetTimeSubmodule<NormalArea>(3f, 0.1f, 0.9f)
.SetHitSubmodule<NormalArea>(0.1f, 8)
.SetLinearDirectionMoveModule<NormalArea>(player.transform.forward, 25f, -50f, false, false, false);
}
area.SetImpulseSubmodule().WithSuction(4f);
area.hitSm.AddHitSound(AK.EVENTS.FUTUREWAND_WEAKATTACKHIT);
int fusionStack = attackUnit.GetSubmodule<AttackUnit.ParameterSubmodule>().GetParameter<int>("Buff_Fusion_Stack");
area.hitSm.AddHitEvent((enemy, hitPosition) =>
{
new Fusion(fusionStack).Apply(enemy);
SubscribeFusionExplode(enemy);
});
}
private void GenerateUltimateBeam(string vfxName, AttackUnit attackUnit)
{
vfxData.SpawnMuzzleVFX(vfxName, player, Muzzle);
NormalArea area = vfxData.SpawnVFX(vfxName, player).GetComponentInChildren<NormalArea>();
area.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackUnit)
.SetTimeSubmodule<NormalArea>(5f, 0.6f)
.SetHitSubmodule<NormalArea>();
area.SetImpulseSubmodule().WithCustomForce(player.transform.forward * 10f);
area.hitSm.AddHitSound(AK.EVENTS.FUTUREWAND_MEDIUMATTACKHIT);
AudioManager.Post(AK.EVENTS.FUTUREWAND_ULTIMATEBEAMPOWERUP, area.gameObject);
2026-07-01 06:32:50 -04:00
area.AddScheduleAction(() =>
2026-06-27 12:52:03 -04:00
{
AudioManager.Post(AK.EVENTS.FUTUREWAND_ULTIMATEBEAMSHOOT);
feedbackSc.PlayFeedback("UltimateBeamShoot");
}, 0f);
}
private void GenerateSpinArea(string vfxName, AttackUnit attackUnit)
{
2026-07-01 06:32:50 -04:00
AttackUnit upgradedAttackUnit = attackUnit.Clone();
float damageMultiplier = 1f + _spinAreaUpgradeCount * 0.25f;
upgradedAttackUnit.startDamage *= damageMultiplier;
2026-06-27 12:52:03 -04:00
vfxData.SpawnMuzzleVFX(vfxName, player, Muzzle);
NormalArea area = vfxData.SpawnVFX(vfxName, player).GetComponentInChildren<NormalArea>();
AudioManager.Post(AK.EVENTS.FUTUREWAND_GROUNDAREA, area.gameObject);
area.Initialize<NormalArea>(player, this, Fraction.Enemy)
2026-07-01 06:32:50 -04:00
.SetAttackSubmodule<NormalArea>(upgradedAttackUnit)
2026-06-27 12:52:03 -04:00
.SetTimeSubmodule<NormalArea>(int.MaxValue, 0.5f, int.MaxValue, null, Shrink)
2026-07-01 06:32:50 -04:00
.SetHitSubmodule<NormalArea>(0.25f, int.MaxValue)
.SetBoomerangMoveSubmodule<NormalArea>(currentTarget, 10f, 0f, 360f, 0f, player.transform.forward)
2026-06-27 12:52:03 -04:00
.SetTransformSubmodule<NormalArea>();
2026-07-01 06:32:50 -04:00
(area.moveSm as BoomerangMoveSubmodule)!.WithAutoReturn(5f + _spinAreaUpgradeCount * 2.5f).WithCatch(1.5f, Shrink).WithTargeting(true, 25f).WithKeepFlat(true).WithReturnParameters(20f, 10f, float.MaxValue, 0f);
2026-06-27 12:52:03 -04:00
area.transformSm.ApplyScaleMove(Vector3.zero, Vector3.one * 3, 0.5f, EaseType.OutQuad);
area.SetImpulseSubmodule().WithSuction(4f);
area.hitSm.AddHitSound(AK.EVENTS.FUTUREWAND_WEAKATTACKHIT);
2026-07-01 06:32:50 -04:00
int fusionStack = upgradedAttackUnit.GetSubmodule<AttackUnit.ParameterSubmodule>().GetParameter<int>("Buff_Fusion_Stack");
2026-06-27 12:52:03 -04:00
area.hitSm.AddHitEvent((enemy, hitPosition) =>
{
new Fusion(fusionStack).Apply(enemy);
SubscribeFusionExplode(enemy);
});
_activeSpinArea = area;
2026-07-01 06:32:50 -04:00
return;
void Shrink()
2026-06-27 12:52:03 -04:00
{
2026-07-01 06:32:50 -04:00
if(_activeSpinArea == null) return;
_activeSpinArea.transformSm.Reset().ApplyScaleMove(Vector3.one * 3, Vector3.zero, 0.5f, EaseType.OutQuad);
_activeSpinArea.AddScheduleAction(() => LeanPool.Despawn(area.topParent.gameObject), 0.5f);
_activeSpinArea = null;
}
}
}
}
2026-06-27 12:52:03 -04:00
2026-07-01 06:32:50 -04:00
/*area.updateAction = () => // 消除敌方投射物
{
if (area.timeSm.enablingTimer > 3f)
{
return;
}
List<Projectile> toBeRemoved = new List<Projectile>();
2026-06-27 12:52:03 -04:00
2026-07-01 06:32:50 -04:00
foreach (Projectile projectile in CombatManager.AttackAreaSm.enemyAttackAreas.activeProjectiles)
{
if (area.areaCollider.IsPointInside(projectile.topParent.transform.position))
2026-06-27 12:52:03 -04:00
{
2026-07-01 06:32:50 -04:00
toBeRemoved.Add(projectile);
2026-06-27 12:52:03 -04:00
}
}
2026-07-01 06:32:50 -04:00
foreach (Projectile projectile in toBeRemoved)
{
projectile.Explode();
}
};*/