除了充盈都做完了

This commit is contained in:
SoulliesOfficial
2025-10-31 10:02:30 -04:00
parent 5d09ef7b53
commit ee1d3d9c0a
179 changed files with 3239 additions and 200 deletions

View File

@@ -1,3 +1,4 @@
using SLSFramework.UModAssistance;
using UnityEngine;
namespace Continentis.MainGame.Character
@@ -20,4 +21,36 @@ namespace Continentis.MainGame.Character
public abstract void Apply(CharacterBase attachedCharacter, CharacterBase sourceCharacter = null);
}
public partial class CharacterBuffBase
{
/// <summary>
/// 创建一个角色战斗Buff实例
/// 注意此函数依赖ModManager的类型注册功能请确保在Mod加载时已注册对应Buff类型
/// 此函数中的T并不是原型参数而是获取Mod中注册的类型用的
/// </summary>
public T CreateCharacterBuff<T>(params object[] parameters) where T :CharacterCombatBuffBase
{
string buffTypeID = ModManager.GetTypeID(typeof(T));
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
public T CreateCharacterBuff<T>(string buffTypeID, params object[] parameters) where T :CharacterCombatBuffBase
{
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
}
}

View File

@@ -115,6 +115,13 @@ namespace Continentis.MainGame.Character
/// <returns></returns>
public bool FocusingCheck(out CharacterCombatBuffBase existingBuff)
{
if (buffType != BuffType.Focusing)
{
Debug.LogError("FocusingCheck只能用于专注类Buff");
existingBuff = null;
return false;
}
// 移除超出上限的专注类Buff
List<CharacterCombatBuffBase> focusingBuffs =
attachedCharacter.combatBuffSubmodule.buffList.Where(buff => buff.buffType == BuffType.Focusing).ToList();

View File

@@ -76,7 +76,7 @@ namespace Continentis.MainGame.Character
/// <param name="ignoreBlock">是否无视格挡</param>
/// <param name="ignoreShield">是否无视护盾</param>
/// <returns>实际造成的伤害</returns>
public int Attack(CharacterBase target, int startDamage, bool ignoreDodge = false, bool ignoreBlock = false, bool ignoreShield = false)
public AttackResult Attack(CharacterBase target, int startDamage, bool triggerAttackEvent = true, bool ignoreDodge = false, bool ignoreBlock = false, bool ignoreShield = false)
{
eventSubmodule.onStartAttack.Invoke(new List<CharacterBase> { target });
@@ -106,9 +106,12 @@ namespace Continentis.MainGame.Character
target.characterView.hudContainer.enablingHUDs["MainAttributesBar"].UpdateHud();
AttackResult attackResult = new AttackResult(this, startDamage, dodged, blocked, shielded, hurt);
eventSubmodule.onFinishAttack.Invoke(new List<CharacterBase> { target }, new List<AttackResult> { attackResult });
return hurt;
if (triggerAttackEvent)
{
eventSubmodule.onFinishAttack.Invoke(new List<CharacterBase> { target }, new List<AttackResult> { attackResult });
}
return attackResult;
}
/// <summary>

View File

@@ -27,6 +27,19 @@ namespace Continentis.MainGame.Character
{
return (T)buffList.FindAll(x => x.GetType() == typeof(T)).Find(x => x.identification == identification);
}
public bool TryGetBuff<T>(out T buff) where T : CharacterCombatBuffBase
{
buff = GetBuff<T>();
return buff != null;
}
public bool TryGetBuffs<T>(out List<T> buffs) where T : CharacterCombatBuffBase
{
List<CharacterCombatBuffBase> foundBuffs = buffList.FindAll(x => x.GetType() == typeof(T));
buffs = foundBuffs.Cast<T>().ToList();
return buffs.Count > 0;
}
public bool HasBuff<T>() where T : CharacterCombatBuffBase
{

View File

@@ -86,11 +86,11 @@ namespace Continentis.MainGame.Character
card.cardLogic.Play(targetList, owner);
}
public CommandGroup DiscardCard(CardInstance card, float interval = 0.1f)
public CommandGroup DiscardCard(CardInstance card, bool initiative, float interval = 0.1f)
{
CommandContext context = new CommandContext();
CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context,
new Cmd_DiscardCards(card.deck, new List<CardInstance>() { card }, interval),
new Cmd_DiscardCards(card.deck, new List<CardInstance>() { card }, initiative, interval),
new Cmd_Function(0, () =>
{
//Debug.Log((context.sharedInfo["DrawnCards"] as List<CardInstance>).Count); //TODO: 弃牌后的处理
@@ -99,7 +99,7 @@ namespace Continentis.MainGame.Character
return discardCardGroup;
}
public CommandGroup DiscardCards(List<CardInstance> cards, float interval = 0.1f)
public CommandGroup DiscardCards(List<CardInstance> cards,bool initiative, float interval = 0.1f)
{
Dictionary<DeckSubmodule, List<CardInstance>> groupedCards = cards.GroupBy(card => card.deck)
.ToDictionary(group => group.Key, group => group.ToList());
@@ -107,7 +107,7 @@ namespace Continentis.MainGame.Character
CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context);
foreach (var kvp in groupedCards)
{
discardCardGroup.AddCommand(new Cmd_DiscardCards(kvp.Key, kvp.Value, interval));
discardCardGroup.AddCommand(new Cmd_DiscardCards(kvp.Key, kvp.Value, initiative, interval));
}
discardCardGroup.AddCommand(new Cmd_Function(0, () =>
{

View File

@@ -8,52 +8,52 @@ namespace Continentis.MainGame.Character
{
public partial class EventSubmodule : SubmoduleBase<CharacterBase>
{
public OrderedDictionary<string, EventUnit> onCombatStart; //战斗开始时
public OrderedDictionary<string, EventUnit> onCombatEnd; //战斗结束时
public OrderedDictionary<string, PrioritizedAction> onCombatStart; //战斗开始时
public OrderedDictionary<string, PrioritizedAction> onCombatEnd; //战斗结束时
public OrderedDictionary<string, EventUnit> onRoundStart; //每回合开始时
public OrderedDictionary<string, EventUnit> onRoundEnd; //每回合结束时
public OrderedDictionary<string, PrioritizedAction> onRoundStart; //每回合开始时
public OrderedDictionary<string, PrioritizedAction> onRoundEnd; //每回合结束时
public OrderedDictionary<string, EventUnit<List<CharacterBase>>> onStartAttack; //开始攻击时,参数为被攻击目标列表
public OrderedDictionary<string, EventUnit<List<CharacterBase>, List<AttackResult>>> onFinishAttack; //完成攻击时,参数为被攻击目标列表和对应的攻击结果列表
public OrderedDictionary<string, EventUnit<CharacterBase, AttackResult>> onGetAttacked; //被攻击时,参数为攻击者和攻击结果
public OrderedDictionary<string, PrioritizedAction<List<CharacterBase>>> onStartAttack; //开始攻击时,参数为被攻击目标列表
public OrderedDictionary<string, PrioritizedAction<List<CharacterBase>, List<AttackResult>>> onFinishAttack; //完成攻击时,参数为被攻击目标列表和对应的攻击结果列表
public OrderedDictionary<string, PrioritizedAction<CharacterBase, AttackResult>> onGetAttacked; //被攻击时,参数为攻击者和攻击结果
public OrderedDictionary<string, EventUnit> onActionStart; //每次行动开始时
public OrderedDictionary<string, EventUnit> onActionEnd; //每次行动结束时
public OrderedDictionary<string, PrioritizedAction> onActionStart; //每次行动开始时
public OrderedDictionary<string, PrioritizedAction> onActionEnd; //每次行动结束时
public OrderedDictionary<string, EventUnit<CardInstance, List<CharacterBase>>> onBeforePlayCard; //使用卡牌前,参数为使用的卡牌
public OrderedDictionary<string, EventUnit<CardInstance, List<CharacterBase>>> onAfterPlayCard; //使用卡牌后,参数为使用的卡牌
public OrderedDictionary<string, PrioritizedAction<CardInstance, List<CharacterBase>>> onBeforePlayCard; //使用卡牌前,参数为使用的卡牌
public OrderedDictionary<string, PrioritizedAction<CardInstance, List<CharacterBase>>> onAfterPlayCard; //使用卡牌后,参数为使用的卡牌
public EventSubmodule(CharacterBase character) : base(character)
{
onCombatStart = new OrderedDictionary<string, EventUnit>();
onCombatEnd = new OrderedDictionary<string, EventUnit>();
onCombatStart = new OrderedDictionary<string, PrioritizedAction>();
onCombatEnd = new OrderedDictionary<string, PrioritizedAction>();
onRoundStart = new OrderedDictionary<string, EventUnit>();
onRoundEnd = new OrderedDictionary<string, EventUnit>();
onRoundStart = new OrderedDictionary<string, PrioritizedAction>();
onRoundEnd = new OrderedDictionary<string, PrioritizedAction>();
onActionStart = new OrderedDictionary<string, EventUnit>();
onActionEnd = new OrderedDictionary<string, EventUnit>();
onActionStart = new OrderedDictionary<string, PrioritizedAction>();
onActionEnd = new OrderedDictionary<string, PrioritizedAction>();
onStartAttack = new OrderedDictionary<string, EventUnit<List<CharacterBase>>>();
onFinishAttack = new OrderedDictionary<string, EventUnit<List<CharacterBase>, List<AttackResult>>>();
onGetAttacked = new OrderedDictionary<string, EventUnit<CharacterBase, AttackResult>>();
onStartAttack = new OrderedDictionary<string, PrioritizedAction<List<CharacterBase>>>();
onFinishAttack = new OrderedDictionary<string, PrioritizedAction<List<CharacterBase>, List<AttackResult>>>();
onGetAttacked = new OrderedDictionary<string, PrioritizedAction<CharacterBase, AttackResult>>();
onBeforePlayCard = new OrderedDictionary<string, EventUnit<CardInstance, List<CharacterBase>>>();
onAfterPlayCard = new OrderedDictionary<string, EventUnit<CardInstance, List<CharacterBase>>>();
onBeforePlayCard = new OrderedDictionary<string, PrioritizedAction<CardInstance, List<CharacterBase>>>();
onAfterPlayCard = new OrderedDictionary<string, PrioritizedAction<CardInstance, List<CharacterBase>>>();
onActionStart.InsertByPriority("StaminaRecover", new EventUnit(() =>
onActionStart.InsertByPriority("StaminaRecover", new PrioritizedAction(() =>
{
owner.ModifyAttribute("Stamina", owner.GetAttribute("StaminaRecoverPerAction"));
owner.ClampAttribute("Stamina", 0, owner.GetAttribute("MaximumStamina"));
}, 999));
onActionStart.InsertByPriority("ManaRecover", new EventUnit(() =>
onActionStart.InsertByPriority("ManaRecover", new PrioritizedAction(() =>
{
owner.ModifyAttribute("Mana", owner.GetAttribute("ManaRecoverPerAction"));
owner.ClampAttribute("Mana", 0, owner.GetAttribute("MaximumMana"));
}, 999));
onActionStart.InsertByPriority("DefenseReset", new EventUnit(() =>
onActionStart.InsertByPriority("DefenseReset", new PrioritizedAction(() =>
{
if (owner.GetAttribute("KeepBlockOnActionStart") <= 0)
{