Files
Cielonos/Assets/Scripts/MainGame/Items/MainWeapons/FutureWand/FutureWand_Extenders.cs
SoulliesOfficial b047eb5e6d 引雷标记extender
2026-07-26 09:42:03 -04:00

158 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using Cielonos.MainGame.Buffs.Character;
using Cielonos.MainGame.Characters;
using SLSUtilities.General;
using UnityEngine;
namespace Cielonos.MainGame.Inventory.Collections
{
public partial class FutureWand
{
private bool _hasMissileSeparationMembrane;
private bool _hasBlackHoleDisplacer;
private bool _hasStellarRingQuickcaster;
private bool _hasCubicScatterIndexer;
private bool _hasFusionChargeCore;
private bool _hasSigilBreakWedge;
private bool _hasLightningConcentrator;
private const int StellarRingQuickcasterSpinAreaUpgradeLevel = 1;
private const int FusionChargeCoreExtraFusionStack = 1;
private const float SigilBreakWedgeExtraStanceDepletion = 30f;
protected override void OnExtendersChanged()
{
CacheExtenderFlags();
}
private void CacheExtenderFlags()
{
_hasMissileSeparationMembrane = HasExtender<MissileSeparationMembrane>();
_hasBlackHoleDisplacer = HasExtender<BlackHoleDisplacer>();
_hasStellarRingQuickcaster = HasExtender<StellarRingQuickcaster>();
_hasCubicScatterIndexer = HasExtender<CubicScatterIndexer>();
_hasFusionChargeCore = HasExtender<FusionChargeCore>();
_hasSigilBreakWedge = HasExtender<SigilBreakWedge>();
_hasLightningConcentrator = HasExtender<LightningConcentrator>();
functionSm?["Lightning"]?.SetRuntimeTag(
nameof(LightningConcentrator),
FunctionData.FunctionUnit.DisruptionTag,
_hasLightningConcentrator);
}
private AttackUnit ApplyLightningConcentrator(AttackUnit source)
{
if (!_hasLightningConcentrator) return source;
// AttackData 已把基础倍率结算进 startDamageclone 后只修改本次 Lightning。
AttackUnit modified = source.Clone();
modified.startDamage *= 2f;
modified.damageDeviation *= 2f;
modified.breakthroughType = Breakthrough.Type.Disruption;
return modified;
}
private bool PlayStellarRingQuickcasterSpinArea()
{
if (!functionSm["SpinArea"].IsAvailable() || !fullBodyFuncAnimSm.CheckPlayability()) return false;
RecallAllSpinAreas();
//StopSpinAreaCharge(true);
RefreshPrimaryTarget();
_spinAreaUpgradeCount = StellarRingQuickcasterSpinAreaUpgradeLevel;
if (PlayReleaseSpinArea()) return true;
_spinAreaUpgradeCount = 0;
return false;
}
private List<Enemy> GetCubicScatterIndexerTargets(int targetCount, float radius = DefaultTargetingRadius)
{
List<Enemy> targets = GetCurrentTargets(targetCount, radius);
if (targets.Count <= 0 || targets.Count >= targetCount)
{
return targets;
}
List<Enemy> scatteredTargets = new List<Enemy>(targetCount);
scatteredTargets.AddRange(targets);
while (scatteredTargets.Count < targetCount)
{
targets.TryGetRandom(out Enemy randomTarget);
scatteredTargets.Add(randomTarget);
}
return scatteredTargets;
}
private int GetBaseFusionStack(AttackUnit attackUnit)
{
return attackUnit.GetSubmodule<AttackUnit.ParameterSubmodule>()?.GetParameter<int>("Buff_Fusion_Stack") ?? 0;
}
private int ApplyFusionChargeCore(int fusionStack, string vfxName)
{
if (vfxName is not ("NormalBolt" or "CubicBolt")) return fusionStack;
return fusionStack + FusionChargeCoreExtraFusionStack;
}
private void ApplySigilBreakWedge(Fusion fusion)
{
if (fusion?.attachedCharacter == null) return;
Attack.Context context = new Attack.Context(
player,
fusion.attachedCharacter,
nameof(SigilBreakWedge),
fusion.attachedCharacter.CenterPosition);
Attack.Value value = new Attack.Value(
false, 0f,
SigilBreakWedgeExtraStanceDepletion,
Attack.Type.Energy,
breakthroughType: Breakthrough.Type.None);
Attack.Result result = new Attack.Result(context, value);
fusion.attachedCharacter.TakeDepletion(result);
}
private void ApplyBlackHoleDisplacer(NormalArea area, AttackUnit attackUnit)
{
area.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);
}
private void TryGenerateMissileSeparation(
Projectile sourceProjectile,
string vfxName,
AttackUnit attackUnit,
CharacterBase hitCharacter,
Vector3 hitPosition,
float speed)
{
if (sourceProjectile.tags.Contains("Separation")) return;
List<Enemy> nearbyEnemies = CombatManager.EnemySm.Query(25f)
.From(hitPosition)
.Exclude(hitCharacter as Enemy)
.Candidates();
if (nearbyEnemies.Count <= 0) return;
Projectile separation = vfxData
.SpawnVFX(vfxName, player, hitPosition, Quaternion.identity)
.GetComponentInChildren<Projectile>();
nearbyEnemies.TryGetRandom(out Enemy randomTarget);
Vector3 separationDirection = (randomTarget.CenterPoint.position - hitPosition).normalized;
separation.Initialize(player, this, false, 1, Fraction.Enemy)
.SetAttackSubmodule<Projectile>(attackUnit)
.SetTimeSubmodule<Projectile>(10f)
.SetHitSubmodule<Projectile>()
.SetLinearDirectionMoveModule<Projectile>(separationDirection, speed, 5f);
separation.tags.Add("Separation");
separation.hitSm.AddCheckedObject(hitCharacter.gameObject);
separation.SetRaycastSubmodule<Projectile>(default, 0.25f, 0.5f);
}
}
}