Files
SoulliesOfficial 649b7a5ddc 更新
2026-05-23 08:27:50 -04:00

181 lines
6.1 KiB
C#
Raw Permalink 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;
using System.Collections.Generic;
using Cielonos.MainGame.Characters;
using DamageNumbersPro;
using Sirenix.OdinInspector;
using SLSUtilities.FunctionalAnimation;
using SLSUtilities.General;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Cielonos.MainGame
{
[Serializable]
[HideReferenceObjectPicker]
public partial class AttackUnit : ICloneable<AttackUnit>
{
[ReadOnly]
public AttackData parentData;
[ReadOnly]
[Tooltip("和AttackData中的key对应且用于运行时识别这个攻击单元")]
public string unitName;
[Title("Attack Parameters")]
[Tooltip("如果为true则这个攻击单元不会造成伤害也不会触发暴击等相关机制通常用于仅触发特殊效果")]
public bool isInvalidAttack;
[HideIf("isInvalidAttack")]
public Attack.Type type = Attack.Type.Kinetics;
[HideIf("isInvalidAttack")]
public float startDamage;
[HideIf("isInvalidAttack")]
public float damageDeviation;
[Tooltip("是否在多段攻击时独立计算伤害和暴击")]
[HideIf("isInvalidAttack")]
public bool isIndependentPerHit = true;
[HideIf("isInvalidAttack")]
public float criticalChance;
[HideIf("isInvalidAttack")]
public float criticalMultiplier = 1;
[Title("Hit Effects")]
public Breakthrough.Type breakthroughType = Breakthrough.Type.Weak;
public DisruptionType disruptionType = DisruptionType.NormalExternal;
[Title("Tags")]
public List<string> tags = new List<string>();
[Title("Hit VFX")]
public bool useVFXDataHit;
[HideIf("useVFXDataHit")]
public GameObject hitVFX;
[ShowIf("useVFXDataHit")]
public string vfxUnitName;
[Title("Extra Modules")]
[ListDrawerSettings(ShowFoldout = true)]
[SerializeReference]
public List<Submodule> submodules = new List<Submodule>();
public bool TryGetSubModule<T>(out T submodule) where T : Submodule
{
submodule = submodules.Find(m => m is T) as T;
return submodule != null;
}
public T GetSubmodule<T>() where T : Submodule
{
return submodules.Find(m => m is T) as T;
}
public Attack.Value GetAttackValue(CharacterBase attacker)
{
bool isCritical = Random.value < GetFinalCriticalChance();
float finalDamage = isCritical ? GetFinalCriticalDamage() : GetFinalRegularDamage();
return new Attack.Value(isCritical, finalDamage, type, disruptionType, breakthroughType, tags);
}
public GameObject GetHitVFX()
{
return hitVFX != null ? hitVFX : parentData.defaultHitVFX;
}
public float GetFinalRegularDamage()
{
return startDamage + Random.Range(-damageDeviation, damageDeviation);
// * GameManager.Player.attributeModule.currentAttributes["AttackPowerCoefficient"];
}
public float GetFinalCriticalDamage()
{
return (startDamage + Random.Range(-damageDeviation, damageDeviation)) * GetFinalCriticalMultiplier();// * GameManager.Player.attributeModule.currentAttributes["AttackPowerCoefficient"] * GetFinalCriticalMultiplier();
}
public float GetFinalCriticalChance()
{
return criticalChance;//+ GameManager.Player.attributeModule.currentAttributes["CriticalChance"];
}
public float GetFinalCriticalMultiplier()
{
return criticalMultiplier;// + GameManager.Player.attributeModule.currentAttributes["CriticalMultiplier"] + 1;
}
public AttackUnit Clone()
{
return (AttackUnit) this.MemberwiseClone();
}
}
public partial class AttackUnit
{
[Serializable]
public abstract class Submodule : SubmoduleBase<AttackUnit>
{
public Submodule(AttackUnit owner) : base(owner)
{
}
}
[Serializable]
public class ParameterSubmodule : Submodule
{
public Dictionary<string, float> floatParameters = new Dictionary<string, float>();
public Dictionary<string, int> intParameters = new Dictionary<string, int>();
public Dictionary<string, string> stringParameters = new Dictionary<string, string>();
public ParameterSubmodule() : base(null)
{
}
public ParameterSubmodule(AttackUnit owner) : base(owner)
{
}
public T GetParameter<T>(string key)
{
if (typeof(T) == typeof(float))
{
return floatParameters.TryGetValue(key, out float floatParameter) ? (T)(object)floatParameter : (T)(object)0f;
}
if (typeof(T) == typeof(int))
{
return intParameters.TryGetValue(key, out int intParameter) ? (T)(object)intParameter : (T)(object)0;
}
if (typeof(T) == typeof(string))
{
return stringParameters.TryGetValue(key, out string stringParameter) ? (T)(object)stringParameter : (T)(object)string.Empty;
}
throw new InvalidOperationException($"Unsupported parameter type: {typeof(T)}");
}
}
[Serializable]
public class DamageNumberSubmodule : Submodule
{
public DamageNumber regularPrefab;
public DamageNumber criticalPrefab;
public Dictionary<string, DamageNumber> customPrefabs = new Dictionary<string, DamageNumber>();
public DamageNumberSubmodule() : base(null)
{
}
public DamageNumberSubmodule(AttackUnit owner) : base(owner)
{
}
}
}
}