我说次元斩
This commit is contained in:
@@ -0,0 +1,313 @@
|
||||
using System.Collections.Generic;
|
||||
using Cielonos.MainGame.Buffs.Character;
|
||||
using Cielonos.MainGame.Characters;
|
||||
using Cielonos.MainGame.UI;
|
||||
using SLSUtilities.FunctionalAnimation;
|
||||
using SLSUtilities.General;
|
||||
using SLSUtilities.WwiseAssistance;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cielonos.MainGame.Inventory.Collections
|
||||
{
|
||||
public partial class FutureWand : MainWeaponBase
|
||||
{
|
||||
private bool _isHoldingAttack;
|
||||
|
||||
public CharacterBase currentTarget;
|
||||
public override void OnEquipped()
|
||||
{
|
||||
base.OnEquipped();
|
||||
RegisterFunctionsToAnimSc();
|
||||
viewObjects["Wand"].SetFadeAnim(0.5f);
|
||||
//PlayerCanvas.MainWeaponUIArea.displayer.SetFrameOutline(1);
|
||||
}
|
||||
|
||||
public override void OnSwitchIn()
|
||||
{
|
||||
if(!player.inputSc.IsMoving) PlayTargetedAnimation("Equip");
|
||||
}
|
||||
|
||||
public override void OnPrimaryPress()
|
||||
{
|
||||
if (!_isHoldingAttack && player.inputSc.IsHoldingSpecialA)
|
||||
{
|
||||
PlayTargetedAnimation("HoldAttackStart", currentTarget);
|
||||
_isHoldingAttack = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (functionSm["LightAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
|
||||
{
|
||||
comboSm.main.NextCombo("L");
|
||||
functionSm["LightAttack"].Execute();
|
||||
currentTarget = CombatManager.EnemySm.GetNearestEnemy(25f);
|
||||
if (currentTarget != null)
|
||||
{
|
||||
PlayTargetedAnimation("Attack" + comboSm.main.GetCurrentNodeName(), currentTarget, 5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayTargetedAnimation("Attack" + comboSm.main.GetCurrentNodeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPrimaryRelease()
|
||||
{
|
||||
if (_isHoldingAttack)
|
||||
{
|
||||
string animName = player.animationSc.fullBodyFuncAnimSm.currentRuntimeFuncAnim?.animationName;
|
||||
if(animName == "HoldAttackLoop" || animName == "HoldAttackStart")
|
||||
{
|
||||
PlayTargetedAnimation("HoldAttackEnd");
|
||||
}
|
||||
}
|
||||
|
||||
_isHoldingAttack = false;
|
||||
}
|
||||
|
||||
public override void OnSecondaryPress()
|
||||
{
|
||||
if (_isHoldingAttack) return;
|
||||
|
||||
if (functionSm["HeavyAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
|
||||
{
|
||||
comboSm.main.NextCombo("R");
|
||||
functionSm["HeavyAttack"].Execute();
|
||||
currentTarget = CombatManager.EnemySm.GetNearestEnemy(25f);
|
||||
|
||||
if (currentTarget != null)
|
||||
{
|
||||
PlayTargetedAnimation("Attack" + comboSm.main.GetCurrentNodeName(), currentTarget, 5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayTargetedAnimation("Attack" + comboSm.main.GetCurrentNodeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class FutureWand
|
||||
{
|
||||
private void FAPF_GenerateBoltOnWand(RuntimeFuncAnim rtFuncAnim)
|
||||
{
|
||||
CustomFunction.PC_StringStringFloat p = rtFuncAnim.GetParams<CustomFunction.PC_StringStringFloat>();
|
||||
GenerateProjectile(p.str0, attackData[p.str1], currentTarget, p.float0);
|
||||
}
|
||||
|
||||
private void FAPF_GenerateBoltOnHand(RuntimeFuncAnim rtFuncAnim)
|
||||
{
|
||||
CustomFunction.PC_StringStringFloat p = rtFuncAnim.GetParams<CustomFunction.PC_StringStringFloat>();
|
||||
GenerateProjectile(p.str0, attackData[p.str1], currentTarget, p.float0, true, player.bodyPartsSc.leftHand);
|
||||
}
|
||||
|
||||
private void FAPF_GenerateUltimateBeam(RuntimeFuncAnim rtFuncAnim)
|
||||
{
|
||||
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
|
||||
GenerateUltimateBeam(p.str0, attackData[p.str1]);
|
||||
}
|
||||
|
||||
private void FAPF_GenerateGroundArea(RuntimeFuncAnim rtFuncAnim)
|
||||
{
|
||||
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
|
||||
GenerateGroundArea(p.str0, attackData[p.str1]);
|
||||
}
|
||||
|
||||
private void FAPF_GenerateMultipleBolts(RuntimeFuncAnim rtFuncAnim)
|
||||
{
|
||||
CustomFunction.PC_StringStringFloat p = rtFuncAnim.GetParams<CustomFunction.PC_StringStringFloat>();
|
||||
List<Enemy> targets = CombatManager.EnemySm.GetEnemiesInRadius(player.transform.position, 25f);
|
||||
if (targets.Count > 0) vfxData.SpawnMuzzleVFX(p.str0, player, muzzle);
|
||||
foreach (Enemy target in targets)
|
||||
{
|
||||
GenerateProjectile(p.str0, attackData[p.str1], target, p.float0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class FutureWand
|
||||
{
|
||||
private Transform muzzle => viewObjects["Wand"].functionalParts["Muzzle"].transform;
|
||||
}
|
||||
|
||||
public partial class FutureWand
|
||||
{
|
||||
private void GenerateProjectile(string vfxName, AttackUnit attackUnit,
|
||||
CharacterBase target, float speed, bool hasMuzzleEffect = true, Transform muzzle = null)
|
||||
{
|
||||
if (hasMuzzleEffect)
|
||||
{
|
||||
muzzle ??= this.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>()
|
||||
.SetAdaptiveTraceMoveModule<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>())
|
||||
{
|
||||
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
|
||||
{
|
||||
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 GenerateSquareExpandingAura(string vfxName)
|
||||
{
|
||||
vfxData.SpawnMuzzleVFX(vfxName, player, muzzle);
|
||||
NormalArea area = vfxData.SpawnVFX(vfxName, player).GetComponentInChildren<NormalArea>();
|
||||
|
||||
area.Initialize<NormalArea>(player, this, Fraction.Enemy)
|
||||
.SetAttackSubmodule<NormalArea>(attackData["SquareAura"])
|
||||
.SetTimeSubmodule<NormalArea>(4f, 0.2f, 2.8f)
|
||||
.SetHitSubmodule<NormalArea>()
|
||||
.SetTransformSubmodule<NormalArea>();
|
||||
|
||||
//audioContainer.PlaySoundFX("SquareAura", area.gameObject, true);
|
||||
|
||||
area.transformSm.ApplyScaleMove(Vector3.one, Vector3.one * 50, 1f, EaseType.OutQuart);
|
||||
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();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public partial class FutureWand
|
||||
{
|
||||
private const string FUSION_EXPLODE_KEY = nameof(FutureWand);
|
||||
|
||||
/// <summary>
|
||||
/// 订阅目标身上 Fusion Buff 的引爆事件,当引爆来源为 FutureWand 时执行专属效果。
|
||||
/// 字典 Key 天然去重,无需手动 -= +=。
|
||||
/// </summary>
|
||||
private void SubscribeFusionExplode(CharacterBase enemy)
|
||||
{
|
||||
Fusion fusion = enemy.buffSm.GetBuff<Fusion>();
|
||||
if (fusion == null) return;
|
||||
|
||||
fusion.onExploded[FUSION_EXPLODE_KEY] = new PrioritizedAction<Fusion, AttackAreaBase>(OnFusionExploded);
|
||||
}
|
||||
|
||||
private void OnFusionExploded(Fusion fusion, AttackAreaBase triggerArea)
|
||||
{
|
||||
if (triggerArea == null || triggerArea.itemSource != this) return;
|
||||
new Decay(50).Apply(fusion.attachedCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51eaf8675463d7c42aa1860698ef9bfe
|
||||
Reference in New Issue
Block a user