100 lines
3.6 KiB
C#
100 lines
3.6 KiB
C#
using System.Collections.Generic;
|
|
using Cielonos.MainGame.Characters;
|
|
using Sirenix.OdinInspector;
|
|
using SLSFramework.General;
|
|
using SLSUtilities.FunctionalAnimation;
|
|
using UnityEngine;
|
|
|
|
namespace Cielonos.MainGame.Inventory
|
|
{
|
|
[CreateAssetMenu(fileName = "Attack", menuName = "Cielonos/Items/AttackData")]
|
|
public class AttackData : SerializedScriptableObject
|
|
{
|
|
[DictionaryDrawerSettings(KeyLabel = "Attack Unit", DisplayMode = DictionaryDisplayOptions.ExpandedFoldout)]
|
|
[Searchable]
|
|
public Dictionary<string, AttackUnit> attackUnits;
|
|
|
|
public GameObject defaultHitVFX;
|
|
|
|
public AttackUnit this[string unitName] => attackUnits[unitName];
|
|
|
|
[OnInspectorGUI("UpdateUnits")]
|
|
public void UpdateUnits()
|
|
{
|
|
foreach (var unit in attackUnits.Values)
|
|
{
|
|
unit.parentData = this;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class AttackUnit : ICloneable<AttackUnit>
|
|
{
|
|
[ReadOnly]
|
|
public AttackData parentData;
|
|
|
|
public float startDamage;
|
|
public float damageDeviation;
|
|
[Tooltip("是否在多段攻击时独立计算伤害和暴击")]
|
|
public bool isIndependentPerHit = true;
|
|
|
|
public float criticalChance;
|
|
public float criticalMultiplier;
|
|
|
|
public AttackType attackType = AttackType.Kinetic;
|
|
public BreakthroughType breakthroughType = BreakthroughType.Weak;
|
|
public DisruptionType disruptionType = DisruptionType.NormalExternal;
|
|
|
|
public bool useVFXDataHit;
|
|
[HideIf("useVFXDataHit")]
|
|
public GameObject hitVFX;
|
|
[ShowIf("useVFXDataHit")]
|
|
public string vfxUnitName;
|
|
|
|
public bool overrideDamageNumber;
|
|
[ShowIf("overrideDamageNumber")]
|
|
[Tooltip("留空则使用对应的AttackType的默认伤害数字")]
|
|
public GameObject damageNumberRegularPrefab;
|
|
[ShowIf("overrideDamageNumber")]
|
|
[Tooltip("留空则使用对应的AttackType的默认伤害数字")]
|
|
public GameObject damageNumberCriticalPrefab;
|
|
|
|
public AttackValue GetAttackValue(CharacterBase attacker)
|
|
{
|
|
bool isCritical = Random.value < GetFinalCriticalChance();
|
|
float finalDamage = isCritical ? GetFinalCriticalDamage() : GetFinalRegularDamage();
|
|
return new AttackValue(attacker, isCritical, finalDamage, attackType, disruptionType, breakthroughType);
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
} |