164 lines
5.3 KiB
C#
164 lines
5.3 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Text;
|
|||
|
|
using Cielonos.MainGame.Characters;
|
|||
|
|
using Sirenix.OdinInspector;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
namespace Cielonos.MainGame.Inventory
|
|||
|
|
{
|
|||
|
|
public enum PlayerEquipmentInputType
|
|||
|
|
{
|
|||
|
|
MainWeaponPrimary,
|
|||
|
|
MainWeaponSecondary,
|
|||
|
|
MainWeaponSpecialA,
|
|||
|
|
MainWeaponSpecialB,
|
|||
|
|
MainWeaponSpecialC,
|
|||
|
|
SupportEquipment0,
|
|||
|
|
SupportEquipment1,
|
|||
|
|
SupportEquipment2,
|
|||
|
|
SupportEquipment3
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public readonly struct PlayerEquipmentInputContext
|
|||
|
|
{
|
|||
|
|
public readonly PlayerEquipmentInputType inputType;
|
|||
|
|
public readonly List<PlayerInputModifierType> modifiers;
|
|||
|
|
public readonly int supportSlotIndex;
|
|||
|
|
|
|||
|
|
public PlayerEquipmentInputContext(PlayerEquipmentInputType inputType, List<PlayerInputModifierType> modifiers, int supportSlotIndex = -1)
|
|||
|
|
{
|
|||
|
|
this.inputType = inputType;
|
|||
|
|
this.modifiers = modifiers;
|
|||
|
|
this.supportSlotIndex = supportSlotIndex;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Serializable]
|
|||
|
|
public class EquipmentInputRule
|
|||
|
|
{
|
|||
|
|
public string name;
|
|||
|
|
|
|||
|
|
[HorizontalGroup("Rule", Width = 0.4f)]
|
|||
|
|
[HideLabel]
|
|||
|
|
public PlayerEquipmentInputType inputType;
|
|||
|
|
|
|||
|
|
[HorizontalGroup("Rule", Width = 0.2f)]
|
|||
|
|
[LabelText("Preinput")]
|
|||
|
|
public bool registerPreinput = true;
|
|||
|
|
|
|||
|
|
[HorizontalGroup("Rule", Width = 0.2f)]
|
|||
|
|
[LabelText("Priority")]
|
|||
|
|
[EnableIf(nameof(registerPreinput))]
|
|||
|
|
public int preinputPriority;
|
|||
|
|
|
|||
|
|
[LabelText("Modifier Conditions")]
|
|||
|
|
[ListDrawerSettings(ShowFoldout = true, DraggableItems = true, AddCopiesLastElement = true)]
|
|||
|
|
public List<InputModifierCondition> modifierConditions = new();
|
|||
|
|
|
|||
|
|
public bool Matches(PlayerEquipmentInputContext context)
|
|||
|
|
{
|
|||
|
|
if (inputType != context.inputType) return false;
|
|||
|
|
|
|||
|
|
foreach (InputModifierCondition condition in modifierConditions)
|
|||
|
|
{
|
|||
|
|
if (condition == null) continue;
|
|||
|
|
if (!condition.Matches(context.modifiers)) return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public int Specificity
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
HashSet<PlayerInputModifierType> modifierTypes = new();
|
|||
|
|
|
|||
|
|
foreach (InputModifierCondition condition in modifierConditions)
|
|||
|
|
{
|
|||
|
|
if (condition == null) continue;
|
|||
|
|
modifierTypes.Add(condition.modifierType);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return modifierTypes.Count;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[CreateAssetMenu(fileName = "InputData", menuName = "Cielonos/Items/Input Data")]
|
|||
|
|
public class InputData : ScriptableObject
|
|||
|
|
{
|
|||
|
|
[InfoBox("$HighPriorityWarningMessage", InfoMessageType.Warning, nameof(HasRuleAboveDashDodgePriority))]
|
|||
|
|
[ListDrawerSettings(ShowFoldout = true, DraggableItems = true,
|
|||
|
|
AddCopiesLastElement = true, ListElementLabelName = "name")]
|
|||
|
|
public List<EquipmentInputRule> rules = new();
|
|||
|
|
|
|||
|
|
public bool TryGetPreinputPriority(PlayerEquipmentInputContext context, out int priority)
|
|||
|
|
{
|
|||
|
|
EquipmentInputRule bestRule = null;
|
|||
|
|
int bestSpecificity = -1;
|
|||
|
|
|
|||
|
|
foreach (EquipmentInputRule rule in rules)
|
|||
|
|
{
|
|||
|
|
if (rule == null || !rule.Matches(context)) continue;
|
|||
|
|
|
|||
|
|
int specificity = rule.Specificity;
|
|||
|
|
if (specificity >= bestSpecificity)
|
|||
|
|
{
|
|||
|
|
bestRule = rule;
|
|||
|
|
bestSpecificity = specificity;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (bestRule is not { registerPreinput: true })
|
|||
|
|
{
|
|||
|
|
priority = 0;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
priority = bestRule.preinputPriority;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private bool HasRuleAboveDashDodgePriority()
|
|||
|
|
{
|
|||
|
|
if (rules == null) return false;
|
|||
|
|
|
|||
|
|
foreach (EquipmentInputRule rule in rules)
|
|||
|
|
{
|
|||
|
|
if (rule is not { registerPreinput: true }) continue;
|
|||
|
|
if (rule.preinputPriority > PlayerInputSubcontroller.PlayerPreinputSubmodule.DashDodgePreinputPriority) return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private string HighPriorityWarningMessage
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
StringBuilder builder = new("以下 Input Rule 的优先级高于 Dash/Dodge (100):");
|
|||
|
|
bool hasRule = false;
|
|||
|
|
|
|||
|
|
if (rules != null)
|
|||
|
|
{
|
|||
|
|
foreach (EquipmentInputRule rule in rules)
|
|||
|
|
{
|
|||
|
|
if (rule is not { registerPreinput: true }) continue;
|
|||
|
|
if (rule.preinputPriority <= PlayerInputSubcontroller.PlayerPreinputSubmodule.DashDodgePreinputPriority) continue;
|
|||
|
|
|
|||
|
|
if (hasRule) builder.Append("、");
|
|||
|
|
builder.Append(string.IsNullOrWhiteSpace(rule.name) ? rule.inputType.ToString() : rule.name);
|
|||
|
|
hasRule = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!hasRule) return string.Empty;
|
|||
|
|
builder.Append("。请确认这些输入确实应该高于 Dash/Dodge。");
|
|||
|
|
return builder.ToString();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|