220 lines
10 KiB
C#
220 lines
10 KiB
C#
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);
|
||
area.timeSm.AddScheduleAction(() =>
|
||
{
|
||
AudioManager.Post(AK.EVENTS.FUTUREWAND_ULTIMATEBEAMSHOOT);
|
||
feedbackSc.PlayFeedback("UltimateBeamShoot");
|
||
}, 0f);
|
||
}
|
||
|
||
private void GenerateSpinArea(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);
|
||
|
||
area.Initialize<NormalArea>(player, this, Fraction.Enemy)
|
||
.SetAttackSubmodule<NormalArea>(attackUnit)
|
||
.SetTimeSubmodule<NormalArea>(int.MaxValue, 0.5f, int.MaxValue, null, Shrink)
|
||
.SetHitSubmodule<NormalArea>(0.5f, int.MaxValue)
|
||
.SetTransformSubmodule<NormalArea>();
|
||
|
||
area.SetBoomerangMoveSubmodule(currentTarget, 10f, 360f, player.transform.forward)
|
||
.WithAutoReturn(float.MaxValue)
|
||
.WithCatch(1.5f, Shrink)
|
||
.WithTargeting(true, 25f)
|
||
.WithKeepFlat(true);
|
||
|
||
area.transformSm.ApplyScaleMove(Vector3.zero, Vector3.one * 3, 0.5f, EaseType.OutQuad);
|
||
|
||
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);
|
||
});
|
||
|
||
_activeSpinArea = area;
|
||
|
||
/*area.updateAction = () => // 消除敌方投射物
|
||
{
|
||
if (area.timeSm.enablingTimer > 3f)
|
||
{
|
||
return;
|
||
}
|
||
|
||
List<Projectile> toBeRemoved = new List<Projectile>();
|
||
|
||
foreach (Projectile projectile in CombatManager.AttackAreaSm.enemyAttackAreas.activeProjectiles)
|
||
{
|
||
if (area.areaCollider.IsPointInside(projectile.topParent.transform.position))
|
||
{
|
||
toBeRemoved.Add(projectile);
|
||
}
|
||
}
|
||
|
||
foreach (Projectile projectile in toBeRemoved)
|
||
{
|
||
projectile.Explode();
|
||
}
|
||
};*/
|
||
|
||
|
||
void Shrink()
|
||
{
|
||
if (_activeSpinArea == area)
|
||
{
|
||
_activeSpinArea = null;
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("Trying to shrink a spin area that is not active.");
|
||
}
|
||
|
||
area.transformSm.Reset().ApplyScaleMove(Vector3.one * 3, Vector3.zero, 0.5f, EaseType.OutQuad);
|
||
area.timeSm.AddScheduleAction(() => LeanPool.Despawn(area.topParent.gameObject), 0.5f);
|
||
}
|
||
}
|
||
}
|
||
}
|