卡牌更新

This commit is contained in:
SoulliesOfficial
2026-04-08 04:48:35 -04:00
parent c3b1561375
commit dd2657573a
242 changed files with 1950 additions and 926 deletions

View File

@@ -44,41 +44,31 @@ namespace Continentis.MainGame.Character
public partial class CharacterBase
{
/// <summary>
/// 获取角色的属性值自动判断属性组Core/General
/// 获取角色的属性值
/// </summary>
public int GetAttribute(string attributeName, int defaultValue = 0)
{
if (attributeSubmodule.coreAttributeGroup.current.ContainsKey(attributeName))
{
return attributeSubmodule.GetCurrentCoreAttribute(attributeName);
}
if (attributeSubmodule.generalAttributeGroup.current.ContainsKey(attributeName))
{
return attributeSubmodule.GetGeneralAttribute(attributeName);
}
Debug.LogWarning($"Attribute {attributeName} not found in any attribute group.");
Debug.LogWarning($"Attribute {attributeName} not found in attribute group.");
return defaultValue;
}
/// <summary>
/// 获取角色的原始属性值自动判断属性组Core/General
/// 获取角色的原始属性值
/// 如果属性名包含“Multiplier”默认值改为1
/// </summary>
public float GetRawAttribute(string attributeName, float defaultValue = 0)
{
if (attributeSubmodule.coreAttributeGroup.current.TryGetValue(attributeName, out float rawAttribute))
{
return rawAttribute;
}
if (attributeSubmodule.generalAttributeGroup.current.TryGetValue(attributeName, out float attribute))
{
return attribute;
}
Debug.LogWarning($"Attribute {attributeName} not found in any attribute group.");
Debug.LogWarning($"Attribute {attributeName} not found in attribute group.");
if(attributeName.Contains("Multiplier"))
{
@@ -89,47 +79,55 @@ namespace Continentis.MainGame.Character
}
/// <summary>
/// 设置角色的属性值自动判断属性组Core/General
/// 设置角色的属性值
/// </summary>
/// <param name="attributeName"></param>
/// <param name="value"></param>
public void SetAttribute(string attributeName, int value)
{
if (attributeSubmodule.coreAttributeGroup.current.ContainsKey(attributeName))
{
attributeSubmodule.coreAttributeGroup.current[attributeName] = value;
return;
}
if (attributeSubmodule.generalAttributeGroup.current.ContainsKey(attributeName))
{
attributeSubmodule.generalAttributeGroup.current[attributeName] = value;
return;
}
Debug.LogWarning($"Attribute {attributeName} not found in any attribute group.");
Debug.LogWarning($"Attribute {attributeName} not found in attribute group.");
}
/// <summary>
/// 修改角色的属性值自动判断属性组Core/General
/// 修改角色的属性值
/// </summary>
/// <param name="attributeName"></param>
/// <param name="delta"></param>
public void ModifyAttribute(string attributeName, int delta)
{
if (attributeSubmodule.coreAttributeGroup.current.ContainsKey(attributeName))
{
attributeSubmodule.coreAttributeGroup.current[attributeName] += delta;
return;
}
if (attributeSubmodule.generalAttributeGroup.current.ContainsKey(attributeName))
{
attributeSubmodule.generalAttributeGroup.current[attributeName] += delta;
return;
}
Debug.LogWarning($"Attribute {attributeName} not found in any attribute group.");
Debug.LogWarning($"Attribute {attributeName} not found in attribute group.");
}
/// <summary>
/// 修改角色的属性值并进行范围限制
/// </summary>
/// <returns>实际的添加或减少的数值(可能因为范围限制而小于 delta</returns>
public int ModifyAndClampAttribute(string attributeName, int delta, int min = 0, int max = int.MaxValue)
{
int currentAttribute = GetAttribute(attributeName);
int actualModifiedValue = delta;
if (delta < 0)
{
actualModifiedValue = Mathf.Min(-delta, currentAttribute - min);
}
else if (delta > 0)
{
actualModifiedValue = Mathf.Min(delta, max - currentAttribute);
}
ModifyAttribute(attributeName, delta);
ClampAttribute(attributeName, min, max);
return actualModifiedValue;
}
public void ClampAttribute(string attributeName, int min, int max)

View File

@@ -17,36 +17,6 @@ namespace Continentis.MainGame.Character
}
}
/// <summary>
/// Buff的角色核心属性调整模块
/// </summary>
public class CoreAttributeSubmodule : CharacterBuffSubmodule
{
public Dictionary<string, float> numericChange;
public Dictionary<string, float> percentageChangeOfAccumulation;
public Dictionary<string, float> percentageChangeOfMultiplication;
public CoreAttributeSubmodule(CharacterBuffBase buff) : base(buff)
{
this.numericChange = new Dictionary<string, float>();
this.percentageChangeOfAccumulation = new Dictionary<string, float>();
this.percentageChangeOfMultiplication = new Dictionary<string, float>();
}
public List<string> RefreshAllModifiedAttributes()
{
List<string> modifiedAttributes = new List<string>();
modifiedAttributes.AddRange(numericChange.Select(kvp => kvp.Key));
modifiedAttributes.AddRange(percentageChangeOfAccumulation.Select(kvp => kvp.Key));
modifiedAttributes.AddRange(percentageChangeOfMultiplication.Select(kvp => kvp.Key));
modifiedAttributes.ForEach(attr => character.attributeSubmodule.RefreshCoreAttribute(attr));
character.attributeSubmodule.RefreshAllGeneralAttributes(); //刷新核心属性后,需要刷新通用属性
return modifiedAttributes;
}
}
/// <summary>
/// Buff的角色通常属性调整模块
/// </summary>

View File

@@ -27,7 +27,6 @@ namespace Continentis.MainGame.Character
public UnitedStackSubmodule unitedStackSubmodule;
public IndependentStackSubmodule independentStackSubmodule;
public CoreAttributeSubmodule coreAttributeSubmodule;
public GeneralAttributeSubmodule generalAttributeSubmodule;
public StatusSubmodule statusSubmodule;
}
@@ -187,14 +186,7 @@ namespace Continentis.MainGame.Character
{
private void RefreshAttributes()
{
if (coreAttributeSubmodule != null)
{
coreAttributeSubmodule.RefreshAllModifiedAttributes();
}
else
{
generalAttributeSubmodule?.RefreshAllModifiedAttributes();
}
generalAttributeSubmodule?.RefreshAllModifiedAttributes();
}
/// <summary>

View File

@@ -7,29 +7,10 @@
[GameAttributeCollection]
public static class CharacterAttributes
{
// ── 核心属性 (Core) ──────────────────────────────────
// ── 属性 (General) ───────────────────────────────
/// <summary> 等级 </summary>
public const string Level = "Level";
/// <summary> 力量 </summary>
public const string Strength = "Strength";
/// <summary> 敏捷 </summary>
public const string Agility = "Agility";
/// <summary> 智力 </summary>
public const string Intelligence = "Intelligence";
/// <summary> 体质 </summary>
public const string Physique = "Physique";
/// <summary> 感知 </summary>
public const string Perception = "Perception";
/// <summary> 魅力 </summary>
public const string Charisma = "Charisma";
// ── 通用属性 (General) ───────────────────────────────
/// <summary> 生命值 </summary>
public const string Health = "Health";
@@ -72,8 +53,8 @@
/// <summary> 闪避 </summary>
public const string Dodge = "Dodge";
/// <summary> 护盾 </summary>
public const string Shield = "Shield";
/// <summary> 临时生命 </summary>
public const string TemporaryHealth = "TemporaryHealth";
/// <summary> 回合开始时保留格挡 </summary>
public const string KeepBlockOnActionStart = "KeepBlockOnActionStart";
@@ -87,9 +68,6 @@
/// <summary> 获得闪避偏移量 </summary>
public const string DodgeGainOffset = "DodgeGainOffset";
/// <summary> 获得护盾偏移量 </summary>
public const string ShieldGainOffset = "ShieldGainOffset";
/// <summary> 闪避攻击前,闪避值乘以此值 </summary>
public const string DodgeCheckStartDamageMultiplier = "DodgeCheckStartDamageMultiplier";

View File

@@ -16,12 +16,7 @@ namespace Continentis.MainGame.Character
[TitleGroup("属性模板")]
[DictionaryDrawerSettings(KeyLabel = "属性名", ValueLabel = "属性值")]
[LabelText("核心属性 (Core)")]
[Tooltip("对应 CharacterData.coreAttributes")]
public SerializableDictionary<string, float> coreAttributes;
[DictionaryDrawerSettings(KeyLabel = "属性名", ValueLabel = "属性值")]
[LabelText("通常属性 (General)")]
[LabelText("属性 (General)")]
[Tooltip("对应 CharacterData.generalAttributes")]
public SerializableDictionary<string, float> generalAttributes;

View File

@@ -72,11 +72,7 @@ namespace Continentis.MainGame.Character
// ── Attributes ────────────────────────────────────────────────────────
[TabGroup("Data", "属性"), PropertyOrder(20)]
[Tooltip("角色的核心属性:支持智能下拉菜单")]
public SerializedDictionary<string, float, CharacterAttributePair> coreAttributes = new SerializedDictionary<string, float, CharacterAttributePair>();
[TabGroup("Data", "属性"), PropertyOrder(21)]
[Tooltip("角色的通常属性:支持智能下拉菜单")]
[Tooltip("角色的属性:支持智能下拉菜单")]
public SerializedDictionary<string, float, CharacterAttributePair> generalAttributes = new SerializedDictionary<string, float, CharacterAttributePair>();
[TabGroup("Data", "属性"), PropertyOrder(22)]

View File

@@ -40,13 +40,13 @@ namespace Continentis.MainGame.Character
}
/// <summary>
/// 消耗体力
/// 修改体力
/// </summary>
public void ModifyStamina(int staminaValue)
public void ModifyStamina(int staminaValue, bool clampMax = false)
{
ModifyAttribute("Stamina", staminaValue);
ClampAttribute("Stamina", 0, GetAttribute("MaximumStamina"));
ClampAttribute("Stamina", 0, clampMax ? GetAttribute("MaximumStamina") : int.MaxValue);
if (this is PlayerHero)
{
CombatUIManager.Instance.combatMainPage.combatResourcesDisplayer.UpdateIcons();
@@ -64,11 +64,11 @@ namespace Continentis.MainGame.Character
/// <summary>
/// 消耗魔法
/// </summary>
public void ModifyMana(int manaValue)
public void ModifyMana(int manaValue, bool clampMax = false)
{
ModifyAttribute("Mana", manaValue);
ClampAttribute("Mana", 0, GetAttribute("MaximumMana"));
ClampAttribute("Mana", 0, clampMax ? GetAttribute("MaximumMana") : int.MaxValue);
if (this is PlayerHero)
{
CombatUIManager.Instance.combatMainPage.combatResourcesDisplayer.UpdateIcons();
@@ -387,9 +387,9 @@ namespace Continentis.MainGame.Character
/// <summary>
/// 添加临时生命(不会自动清空)
/// </summary>
public void AddShield(int shield, CharacterBase target = null)
public void AddTemporaryHealth(int tempHealth, CharacterBase target = null)
{
int baseShieldAfterOffset = shield + GetAttribute("TemporaryHealthGainOffset");
int baseShieldAfterOffset = tempHealth + GetAttribute("TemporaryHealthGainOffset");
int finalShield = Mathf.RoundToInt(baseShieldAfterOffset * GetRawAttribute("TemporaryHealthGainMultiplier", 1));
target ??= this;

View File

@@ -1,15 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using Continentis.MainGame.Rules;
using SLSFramework.General;
using Unity.VisualScripting;
using UnityEngine;
namespace Continentis.MainGame.Character
{
public partial class AttributeSubmodule : SubmoduleBase<CharacterBase>
{
public AttributeGroup coreAttributeGroup;
public AttributeGroup generalAttributeGroup;
public AttributeSubmodule(CharacterBase character) : base(character)
@@ -19,10 +16,7 @@ namespace Continentis.MainGame.Character
private void Initialize(CharacterData characterData)
{
coreAttributeGroup = new AttributeGroup(characterData.coreAttributes.ToDictionary());
generalAttributeGroup = new AttributeGroup(characterData.generalAttributes.ToDictionary());
RulesManager.Instance.attributeRulesMerger.convertCoreIntoGeneral(coreAttributeGroup.current, generalAttributeGroup.original);
generalAttributeGroup.ApplyAllAttributes();
generalAttributeGroup.SetUpEndowments(characterData.runtimeGeneralAttributes.ToDictionary());
}
@@ -30,16 +24,6 @@ namespace Continentis.MainGame.Character
public partial class AttributeSubmodule
{
public float GetRawCurrentCoreAttribute(string attributeName, float defaultValue = 0)
{
return coreAttributeGroup.current.GetValueOrDefault(attributeName, defaultValue);
}
public int GetCurrentCoreAttribute(string attributeName, int defaultValue = 0)
{
return coreAttributeGroup.current.GetRoundValue(attributeName, defaultValue);
}
public float GetRawGeneralAttribute(string attributeName, float defaultValue = 0)
{
return generalAttributeGroup.current.GetValueOrDefault(attributeName, defaultValue);
@@ -51,80 +35,6 @@ namespace Continentis.MainGame.Character
}
}
public partial class AttributeSubmodule
{
/// <summary>
/// 得出对某个核心属性的检定成功概率
/// 计算方式为达到需求值为100%每低于1点属性值成功率降低20%。
/// </summary>
/// <param name="coreAttributeName">属性名</param>
/// <param name="requirement">需求值</param>
/// <param name="higherPass">设true为高于需求值算作通过probability如果为false则最终概率为1-probability</param>
/// <param name="additionalAmount">额外加成</param>
/// <returns>最终概率</returns>
public float Probability(string coreAttributeName, int requirement, bool higherPass = true, int additionalAmount = 0)
{
return Probability(GetCurrentCoreAttribute(coreAttributeName), requirement, higherPass, additionalAmount);
}
/// <summary>
/// 对某个核心属性进行检定
/// </summary>
/// <param name="coreAttributeName">属性名</param>
/// <param name="requirement">需求值</param>
/// <param name="higherPass">设true为高于需求值算作通过probability如果为false则最终概率为1-probability</param>
/// <param name="additionalAmount">额外加成</param>
/// <returns>本次检定是否通过</returns>
public bool Check(string coreAttributeName, int requirement, bool higherPass = true, int additionalAmount = 0)
{
return Check(GetCurrentCoreAttribute(coreAttributeName), requirement, higherPass, additionalAmount);
}
private float Calculate(int value, int requirement)
{
int difference = value - requirement;
return Mathf.Clamp01(1 + difference * 0.2f);
}
private float Probability(int attributeValue, int requirement, bool higherPass = true, int additionalAmount = 0)
{
float probability = Calculate(attributeValue + additionalAmount, requirement);
return higherPass ? probability : 1 - probability;
}
private bool Check(int attributeValue, int requirement, bool higherPass = true, int additionalAmount = 0)
{
float baseProbability = Probability(attributeValue, requirement, higherPass, additionalAmount);
return baseProbability >= Random.Range(0f, 1f);
}
}
public partial class AttributeSubmodule
{
public void RefreshCoreAttribute(string attributeName)
{
coreAttributeGroup.ResetAttribute(attributeName);
owner.equipmentSubmodule.GetCoreAttributeChange(attributeName, out float e_numeric, out float e_pAccumulation, out float e_pMultiplication);
owner.combatBuffSubmodule.GetCoreAttributeChange(attributeName, out float cb_numeric, out float cb_pAccumulation, out float cb_pMultiplication);
float numeric = e_numeric + cb_numeric;
float pAccumulation = e_pAccumulation + cb_pAccumulation;
float pMultiplication = e_pMultiplication * cb_pMultiplication;
coreAttributeGroup.ModifyAttribute(attributeName, numeric, pAccumulation, pMultiplication);
RulesManager.Instance.attributeRulesMerger.convertCoreIntoGeneral(coreAttributeGroup.current, generalAttributeGroup.original);
}
public void RefreshAllCoreAttributes()
{
foreach (string attributeName in coreAttributeGroup.current.Keys)
{
RefreshCoreAttribute(attributeName);
}
}
}
public partial class AttributeSubmodule
{
public void RefreshGeneralAttribute(string attributeName)
@@ -138,8 +48,6 @@ namespace Continentis.MainGame.Character
float pAccumulation = e_pAccumulation + cb_pAccumulation;
float pMultiplication = e_pMultiplication * cb_pMultiplication;
generalAttributeGroup.ModifyAttribute(attributeName, numeric, pAccumulation, pMultiplication);
//Debug.Log($"Refreshed general attribute: {attributeName}, new value: {generalAttributeGroup.current[attributeName]}");
}
public void RefreshAllGeneralAttributes()
@@ -149,15 +57,5 @@ namespace Continentis.MainGame.Character
RefreshGeneralAttribute(attributeName);
}
}
private void ModifyGeneralAttributeFromEquipments(string attributeName)
{
/*EntityEquipmentModule equipmentModule = entity.equipmentModule;
equipmentModule.GetAttributeChange(attributeName, out int numericChange,
out float percentageChangeOfAccumulation, out float percentChangeOfMultiplication);
currentCombatAttributes[attributeName] += numericChange;
currentCombatAttributes[attributeName] = (int)((1 + percentageChangeOfAccumulation) * currentCombatAttributes[attributeName]);
currentCombatAttributes[attributeName] = (int)(percentChangeOfMultiplication * currentCombatAttributes[attributeName]);*/
}
}
}

View File

@@ -106,25 +106,6 @@ namespace Continentis.MainGame.Character
public partial class CombatBuffSubmodule
{
public void GetCoreAttributeChange(string attributeName, out float numericChange,
out float percentageChangeOfAccumulation, out float percentChangeOfMultiplication)
{
numericChange = buffList.Where(buff => buff.coreAttributeSubmodule != null)
.SelectMany(buff => buff.coreAttributeSubmodule.numericChange)
.Where(change => change.Key == attributeName)
.Sum(change => change.Value);
percentageChangeOfAccumulation = buffList.Where(buff => buff.coreAttributeSubmodule != null)
.SelectMany(buff => buff.coreAttributeSubmodule.percentageChangeOfAccumulation)
.Where(change => change.Key == attributeName)
.Sum(change => change.Value);
percentChangeOfMultiplication = buffList.Where(buff => buff.coreAttributeSubmodule != null)
.SelectMany(buff => buff.coreAttributeSubmodule.percentageChangeOfMultiplication)
.Where(change => change.Key == attributeName)
.Aggregate<KeyValuePair<string, float>, float>(1, (current, change) => current * change.Value);
}
public void GetGeneralAttributeChange(string attributeName, out float numericChange,
out float percentageChangeOfAccumulation, out float percentChangeOfMultiplication)
{

View File

@@ -17,25 +17,6 @@ namespace Continentis.MainGame.Character
public partial class EquipmentSubmodule
{
public void GetCoreAttributeChange(string attributeName, out float numericChanges,
out float percentageChangesOfAccumulation, out float percentChangesOfMultiplication)
{
numericChanges = currentEquipments
.SelectMany(eq => eq.coreAttributeSubmodule.numericChange)
.Where(change => change.Key == attributeName)
.Sum(change => change.Value);
percentageChangesOfAccumulation = currentEquipments
.SelectMany(eq => eq.coreAttributeSubmodule.percentageChangeOfAccumulation)
.Where(change => change.Key == attributeName)
.Sum(change => change.Value);
percentChangesOfMultiplication = currentEquipments
.SelectMany(ew => ew.coreAttributeSubmodule.percentageChangeOfMultiplication)
.Where(change => change.Key == attributeName)
.Aggregate<KeyValuePair<string, float>, float>(1, (current, change) => current * change.Value);
}
public void GetGeneralAttributeChange(string attributeName, out float numericChanges,
out float percentageChangesOfAccumulation, out float percentChangesOfMultiplication)
{

View File

@@ -164,11 +164,9 @@ namespace Continentis.MainGame.Character
[GUIColor(0.7f, 1f, 0.7f)]
public void PasteDefaultAttributes()
{
if (coreAttributes == null) coreAttributes = new SLSUtilities.General.SerializedDictionary<string, float, CharacterAttributePair>();
if (generalAttributes == null) generalAttributes = new SLSUtilities.General.SerializedDictionary<string, float, CharacterAttributePair>();
if (runtimeGeneralAttributes == null) runtimeGeneralAttributes = new SLSUtilities.General.SerializedDictionary<string, string>();
coreAttributes.Clear();
generalAttributes.Clear();
runtimeGeneralAttributes.Clear();
@@ -181,18 +179,6 @@ namespace Continentis.MainGame.Character
foreach (var coll in collections)
{
if (coll.characterCoreAttributes != null)
{
foreach (var kvp in coll.characterCoreAttributes)
{
if (!coreAttributes.ContainsKey(kvp.Key))
{
float defaultVal = kvp.Key.Contains("Multiplier") ? 1f : 0f;
coreAttributes.Add(kvp.Key, defaultVal);
}
}
}
if (coll.characterGeneralAttributes != null)
{
foreach (var kvp in coll.characterGeneralAttributes)
@@ -220,7 +206,7 @@ namespace Continentis.MainGame.Character
}
EditorUtility.SetDirty(this);
Debug.Log($"[CharacterData] '{this.name}' 提取完毕。从 {collections.Count} 个主库中提取了 {coreAttributes.Count} 个核心属性,{generalAttributes.Count} 个通用属性以及 {runtimeGeneralAttributes.Count} 个运行时约束!");
Debug.Log($"[CharacterData] '{this.name}' 提取完毕。从 {collections.Count} 个主库中提取了 {generalAttributes.Count} 个属性以及 {runtimeGeneralAttributes.Count} 个运行时约束!");
}
// ── 内部共享辅助方法 ─────────────────────────────────────────────────