ZZLU6UG75ALN7BYLP4SLGT4SIHDKJPFZPMNSYST25RQT3KLTFHPAC ETEF4UXJYHL5BG775IMDIBI5EZIFNS62IF6VOJGCB4LG6WEL7OUAC G4XIS2NEM4WHRP2775YBCLFDT7JZZS52CMEHY3PA43QSXL45XNDAC 62YQ7EMUYX7GS3AB6FAJDKNX53LVG6T2EH6NMVS6JV36J5VCOKIAC VZRSH4U473FCZOP5EXURPXXN5J6F3ZLT435YY7A2JHLG2ZZB5KLQC M2C63XUU3TKYAUPPSPEFVF4CMBQMCVLZATANFWQW35MMYNRB2SEAC DGC7DHJWSP6BZMDKZ6FG6YS7P2RXZWKFROBYHEX4KZCG7HFBLSUQC RZAMG2H2NY73KZJIV4VXLJHJVSRGJDRWWZJERAI6O7AVDW64JEQQC S5OSCH7CRN2YEKVTCTJXNLYR2B3PEGCCBUGTN2M6QOCKBNJR62NAC 6BA5NHNF3UWSL65KCWSXLRTPGYVS4N4NORDJ4FZTZ5SRRDPI4YZAC HXTSBPAP75A7EC4RKWYQMVPPHPNZFPHUORBZWDHGEB6MPAGI7G7AC MHN2B5YZ2Y4G3O7UOZJKFQ3SSP5HTNJCXFKCO3KYY46I2GHM3TIQC GRTHEQW3VTYOB4CSVAB4VBEAW6MRVAJRV4CBXOIRSUFMO7SK3GCAC QOAVQCDV2MRAPUX62ZLDTUB6AXYSAGEEWIEZIG4TGIQKCLP5T5GAC KAROCU3SAOGWWSFXGCLE5OW76VTDJR4HDIVTK62BIAESN5SOHVDAC WKHLLZ3K732M7VJ5KWDSLRWZUARDNDP6ODAXD6SW43CHCT5DX5SAC S256EPZUSOF4TV2KGOFZDJXUFDD57GZFYTCARFJ3SD24RPC56PHAC IA2O33JCJVSJ3IVBBHX2XQU4BCPL3X6JDDZ2R2KNGUFPWXAUKO7QC QZXURLSF73UL67TIXDHMVS7DCFZLQJAPJ6BAGRGXOHH46VMNKGPQC 2ICHN37Z2OZ455ALKTMXTV5JOULQBN5UN46OM6JCHMF3CPNHFF3AC 5YUI4V7A6ONEYREG5CXWHMBYCOP6Q3GMMQD2OTHXZAGKCGM4FWBAC 2SLVO3SYIJQOEV2YNSD73BSUSWQNZVROQCGHJCPCDSMCCNKZTQFQC EF6FXKYIVJCURLSC2CLS27FCTECIIIU2EEPI352ZTCIKYKW5VOBQC N6YTMLNYZLR4BEDGYC7RJQ43KJ3XZFILZ6ODN26Z7RF3LZ6LVUOQC A6K2SVTQ3JQ3TC3F44H3ERSX47TRQ6R5EJGIRJKFGKZG6I4HOATQC NQXDEYOPZBO7AZJHBEBNMBR3QFE4OAQFK4FHOIGKD7TXE256X23AC 2ZZM2HIS7HNIMK3Q6ALHIMQYLKNIHUOL6FJ57O6SR77VAMEINLWAC O236B5LO6PHJ4TPZGYXDVSLB5EGXXRRLYYVWI46DPL5LEGXEIHZQC XF52N4U7HWXOF4PDSCR7LCUENLTSXLWEZGS2IJ6562KYI567Z2GAC XIPU27GAVXMAKDP42DDSYNA6DSN5WBHH6AG4EK6YIIM43AQQHQAAC NZIEX6J6Q6DSJKNSCTHNIA6EJDQEGMK3ZSP3LKX2UAEDHURQPRVQC CD5FF75KTOBTMVMTMCKMR6F5DFKOF26I5K43ITNHGBI3ZAZHA4RAC 4PLSNSVW4VOQW5ZXXZGUWB56WI33SXTGWOCD7PNE36OWDGD7NRJAC 5I5QA3YK5G5QQCXMSDOEAX3A74LVXV7PYWAIHMLFANR2GUFWMKGQC LTG4LQJEMFY22QOI6E5HM3U4OE3JCYRFJ6VGW3KI3AFTMHZCTWRAC P5O6MKCMZL3DK7ZO5SBWTCHOQB6O2MZA5VPSCQX6X4LJQVOWYV7AC HUULCHM5GFGZ7GKLCULFHC333LQ3LBI62VKII3YL5O4C5CDGCT4AC OXMN3LHBNH7CWHEZRPSZTN244O3ACTOEKZEAKQNKFXQ7VQSM26YQC DIEGZM3YMQCKTQW3NLESFZBOGMWW6FT6TZOUL7IUAJD2X5IISUYAC 4JF2MUNF23IFAVVECZNP3JJLFPEB36V7FDRQOKIZNF6Q2FAGOFRQC 3JTZIZGE6WPLZCIWXXLG3SQA2LVSVP26P7U52YBMBTY2VCC6LBLAC FIMVA3BI72IWMBRN5T3PKDCKSJW667BH25INKDWSPWGHLRKCNAPAC JCJJQHBBV2KJGV46NWH3RHF5XSFVZUB56DVGR5XTCUOXHWD2KCJAC MQD6ISMHW27RCHAGJUINEULYXSY3JQ3UKVQPEM5PYDMM32TUYAYQC 5VVJCVERFU6ZMLSEW5TWRUHOLYL2ATFLNMWAEEJBXCG2RM3MJGSAC S6LIARO3HIMP67ZDRIPPU3NC4GM6JQQODDIFGZH5HBN75JHFFSQAC ROTMK5LNNK7T5YXVOMUODVMCQWIHPZYOME4WDIAMZJ4VXD7SOEBAC 4JF64OZ2FPMTXL5XV3Z6HCEKKGCLXPLMNV3YCNX35RL5CXL42VNQC VUAVVMQEUYSXHBIUJHGRX237EZFT5MCB73ZKVWMGJDRHYZH4XZKAC R475KN7MR3OG7EBLVNOO7QRIKXDGY2PIDXXV3HW4KBD5QM7B5OJQC FNS4LRFQNFM4BCB23CYHOWA2N4MG2DEUMNK6D55BQ26TX6OJLIBQC 577EKAKIUP5R4STCPLRNJT6IJR6G232FAJ2T7DSCK2LOJZ5EG55QC MML56TWYWB6SUY5JEWHG2PNLAH3JY72PGCEXIGOYE54EAC2WSWBAC VPXUP5WZTVC3OVD73TNKPK43IAGFXGUGCEJT56JM4IT4APYQXUHAC [SerializeField] Inventory _inventory;[SerializeField] List<CombatFormRef> _knownForms;Weapon _equippedWeapon;CombatForm _equippedForm;Dictionary<Weapon, CombatForm> _preferedCombatFormByWeapon = new();Line<IAction> _plannedActions = new(capacity: 6);
public class Weaver : MonoBehaviour{[SerializeField] Inventory _inventory;[SerializeField] List<CombatFormRef> _knownForms;Weapon _equippedWeapon;CombatForm _equippedForm;Dictionary<Weapon, CombatForm> _preferedCombatFormByWeapon = new();Line<IAction> _plannedActions = new(capacity: 6);
public event EventHandler<WeaponEquippedEventArgs> WeaponEquipped;public event EventHandler<CombatFormEquippedEventArgs> CombatFormEquipped;public event EventHandler<TakeActionEventArgs> ActionTaken;public event EventHandler<UnitActionEventArgs> PlannedActionsChanged;
public event EventHandler<WeaponEquippedEventArgs> WeaponEquipping;public event EventHandler<WeaponEquippedEventArgs> WeaponEquipped;public event EventHandler<CombatFormEquippedEventArgs> CombatFormEquipped;public event EventHandler<TakeActionEventArgs> ActionTaken;public event EventHandler<UnitActionEventArgs> PlannedActionsChanged;
protected void OnActionTaken(TakeActionEventArgs e) {ActionTaken?.Invoke(this, e);}protected void OnPlannedActionsChanged(UnitActionEventArgs e) {PlannedActionsChanged?.Invoke(this, e);}
protected void OnCombatFormEquipped(CombatFormEquippedEventArgs e) {CombatFormEquipped?.Invoke(this, e);}protected void OnActionTaken(TakeActionEventArgs e) {ActionTaken?.Invoke(this, e);}protected void OnPlannedActionsChanged(UnitActionEventArgs e) {PlannedActionsChanged?.Invoke(this, e);}protected void Start() {EquipAnyWeapon();}
protected void Update() {if (_plannedActions.TryPeek(out var action)) {var actionState = action.Advance();OnActionTaken(new(actionState));
if (!actionState.IsAdvanced) {action.Dispose();_plannedActions.TryGetFirstOutOfLine(out var _);OnPlannedActionsChanged(new(transform));}}}
if (!actionState.IsAdvanced) {action.Cancel();_plannedActions.TryGetFirstOutOfLine(out var _);
bool PlanAction(IAction action) {var success = false;if (_plannedActions.TryWaitInLine(action)) {
bool PlanAction(IAction action) {var success = false;if (_plannedActions.TryWaitInLine(action)) {OnPlannedActionsChanged(new(transform));success = true;
void SetCombatForm(CombatForm combatForm) {_equippedForm = combatForm;OnCombatFormEquipped(new(_equippedForm, this));
void SetCombatForm(CombatForm combatForm) {_equippedForm = combatForm;OnCombatFormEquipped(new(_equippedForm, this));}
void EquipPreferredCombatFormOfWeapon(Weapon weapon) {_preferedCombatFormByWeapon.TryGetValue(weapon, out var tryEquipForm);SetCombatForm(tryEquipForm);}
void EquipPreferredCombatFormOfWeapon(Weapon weapon) {_preferedCombatFormByWeapon.TryGetValue(weapon, out var tryEquipForm);SetCombatForm(tryEquipForm);}void EquipAnyWeapon() {var tryEquipWeapon = _inventory.GetAvailableWeapons().First();if (tryEquipWeapon != null) {TryDrawWeapon(tryEquipWeapon.Name);}}public bool TryDrawWeapon(string weaponName) {var isWeaponInInventory = false;if (_inventory) {isWeaponInInventory = _inventory.TryGetWeaponByName(weaponName, out var tryEquipWeapon);if (isWeaponInInventory) {ClearActionPlan();_equippedWeapon = tryEquipWeapon;OnWeaponEquipped(new(_equippedWeapon, this));EquipPreferredCombatFormOfWeapon(_equippedWeapon);
void EquipAnyWeapon() {var tryEquipWeapon = _inventory.GetAvailableWeapons().First();if (tryEquipWeapon != null) {TryDrawWeapon(tryEquipWeapon.Name);
return isWeaponInInventory;}public bool TryEquipCombatForm(string combatFormName) {CombatForm combatForm = GetAvailableCombatFormsForEquipedWeapon().Where(combatForm => combatForm.name == combatFormName).FirstOrDefault();_preferedCombatFormByWeapon[_equippedWeapon] = combatForm;SetCombatForm(combatForm);
public bool TryDrawWeapon(string weaponName) {var isWeaponInInventory = false;if (_inventory) {isWeaponInInventory = _inventory.TryGetWeaponByName(weaponName, out var tryEquipWeapon);if (isWeaponInInventory) {ClearActionPlan();var previousWeapon = _equippedWeapon;_equippedWeapon = tryEquipWeapon;OnWeaponEquipping(new(previousWeapon, _equippedWeapon, this));EquipPreferredCombatFormOfWeapon(_equippedWeapon);OnWeaponEquipped(new(previousWeapon, _equippedWeapon, this));}}
return combatForm != null;}
return isWeaponInInventory;}public bool TryEquipCombatForm(string combatFormName) {CombatForm combatForm = GetAvailableCombatFormsForEquipedWeapon().Where(combatForm => combatForm.name == combatFormName).FirstOrDefault();_preferedCombatFormByWeapon[_equippedWeapon] = combatForm;SetCombatForm(combatForm);
public bool TryQueueWeave(RuneWeavingContainer weaving, Transform target) {WeaveAction weaveAction = new(this, weaving, target, _equippedWeapon.GetRange());var success = PlanAction(weaveAction);return success;}
return combatForm != null;}
public bool TryQueueFollow(Transform target) {FollowAction followAction = new(this, target, _equippedWeapon.GetRange());var success = PlanAction(followAction);return success;}
public bool TryQueueWeave(RuneWeavingContainer weaving, Transform target) {WeaveAction weaveAction = new(this, weaving, target, GetComponent<Resources.Range>());var success = PlanAction(weaveAction);return success;}
public bool TryQueueMove(Vector3 target) {MoveToAction moveToAction = new(this, target);var success = PlanAction(moveToAction);return success;}
public bool TryQueueFollow(Transform target) {FollowAction followAction = new(this, target);var success = PlanAction(followAction);return success;}
public void ClearActionPlan() {foreach (var action in _plannedActions) {action.Cancel();
public bool TryQueueMove(Vector3 target) {MoveToAction moveToAction = new(this, target);var success = PlanAction(moveToAction);return success;
public bool TryRemoveActionFromPlan(int index) {var success = false;if (_plannedActions.TryRemoveAt(index, out var _)) {success = true;
public void ClearActionPlan() {foreach (var action in _plannedActions) {action.Dispose();}_plannedActions.Clear();
return success;}
public bool TryRemoveActionFromPlan(int index) {var success = false;if (_plannedActions.TryRemoveAt(index, out var _)) {success = true;OnPlannedActionsChanged(new(transform));}return success;}
public bool CanUseWeave(RuneWeaving weave) {var weaponMoveSet = _equippedWeapon.GetCombatMoveSetRef().CombatMoveSet.CombatMoves();var weaveMoveSet = weave.MartialSequence.GetSequence().Select(moveRef => moveRef.CombatMove);return weaveMoveSet.All(weaveMove => weaponMoveSet.Any(weaponMove => weaveMove.MoveName == weaponMove.CombatMove.MoveName));}
public bool CanUseWeave(RuneWeaving weave) {var weaponMoveSet = _equippedWeapon.GetCombatMoveSetRef().CombatMoveSet.CombatMoves();var weaveMoveSet = weave.MartialSequence.GetSequence().Select(moveRef => moveRef.CombatMove);return weaveMoveSet.All(weaveMove => weaponMoveSet.Any(weaponMove => weaveMove.MoveName == weaponMove.CombatMove.MoveName));}
public Weapon EquippedWeapon => _equippedWeapon;public CombatForm EquippedForm => _equippedForm;public IEnumerable<Weapon> GetWeaponsInInventory() => _inventory.GetAvailableWeapons();public IEnumerable<CombatFormRef> GetAvailableCombatFormsForEquipedWeapon() => _knownForms.Select(combatFormRef => combatFormRef).Intersect(_equippedWeapon.GetCompatibleFormRefs());public IEnumerable<IAction> GetPlannedActions() => _plannedActions;
public Weapon EquippedWeapon => _equippedWeapon;public CombatForm EquippedForm => _equippedForm;public IEnumerable<Weapon> GetWeaponsInInventory() => _inventory.GetAvailableWeapons();public IEnumerable<CombatFormRef> GetAvailableCombatFormsForEquipedWeapon() => _knownForms.Select(combatFormRef => combatFormRef).Intersect(_equippedWeapon.GetCompatibleFormRefs());public IEnumerable<IAction> GetPlannedActions() => _plannedActions;
public class WeaponEquippedEventArgs : EventArgs{public Weapon Weapon { get; }public Weaver Weaver { get; }public WeaponEquippedEventArgs(Weapon weapon, Weaver weaver) {Weapon = weapon;Weaver = weaver;
public class WeaponEquippedEventArgs : EventArgs{public Weapon PreviousWeapon { get; }public Weapon CurrentWeapon { get; }public Weaver Weaver { get; }public WeaponEquippedEventArgs(Weapon previousWeapon, Weapon currentWeapon, Weaver weaver) {PreviousWeapon = previousWeapon;CurrentWeapon = currentWeapon;Weaver = weaver;}
}public class CombatFormEquippedEventArgs : EventArgs{public CombatForm CombatForm { get; }public Weaver Weaver { get; }public CombatFormEquippedEventArgs(CombatForm combatForm, Weaver weaver) {CombatForm = combatForm;Weaver = weaver;
public class CombatFormEquippedEventArgs : EventArgs{public CombatForm CombatForm { get; }public Weaver Weaver { get; }public CombatFormEquippedEventArgs(CombatForm combatForm, Weaver weaver) {CombatForm = combatForm;Weaver = weaver;}
public class TakeActionEventArgs : EventArgs{public IActionState ActionState { get; }public TakeActionEventArgs(IActionState actionState) {ActionState = actionState;
public class TakeActionEventArgs : EventArgs{public IActionState ActionState { get; }public TakeActionEventArgs(IActionState actionState) {ActionState = actionState;}
[SerializeField] List<WeaponSet> _weaponSets;int _currentActiveSet = -1;Weaver _watchedWeaver;
[RequireComponent(typeof(Weaver))]public class WeaponSwap : MonoBehaviour{[SerializeField] List<WeaponSet> _weaponSets;int _currentActiveSet = -1;Weaver _watchedWeaver;void SetWatchedWeaver(Weaver weaver) {if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipping -= OnWeaponEquipping;}_watchedWeaver = weaver;
void SetWatchedWeaver(Weaver weaver) {if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped -= OnWeaponEquipped;
if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipping += OnWeaponEquipping;}}protected void Awake() {SetWatchedWeaver(GetComponent<Weaver>());
if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped += OnWeaponEquipped;
void ApplyItemEffects(Weapon item) {Debug.Log($"ApplyItemEffects on {_watchedWeaver}");var context = new EffectContext(new EffectSystem(GameObject.Find("RippleOutVfx").GetComponent<ParticleSystem>())) {EffectLocation = _watchedWeaver.transform,Caster = _watchedWeaver.transform};foreach (var effect in item.MainHandEffects()) {effect.Mode.ImmediateAction(context, effect.Effect);}
}protected void Awake() {SetWatchedWeaver(GetComponent<Weaver>());}protected void OnDestroy() {SetWatchedWeaver(null);}void OnWeaponEquipped(object sender, Weaver.WeaponEquippedEventArgs e) {ChangeActiveWeaponSet(e.Weapon.Name);}void ChangeActiveWeaponSet(string weaponName) {var newActiveSet = _weaponSets.FindIndex(set => set.Weapon.Value.Name == weaponName);if (newActiveSet == -1) {print($"WeaponSwap {weaponName} cannot be found");return;}if (newActiveSet != _currentActiveSet) {foreach (var weapon in _weaponSets[newActiveSet].WeaponProps) {weapon.SetActive(true);
void ChangeActiveWeaponSet(string weaponName) {var newActiveSet = _weaponSets.FindIndex(set => set.Weapon.Value.Name == weaponName);if (newActiveSet == -1) {print($"WeaponSwap {weaponName} cannot be found");return;
[Serializable]public class WeaponSet{public WeaponRef Weapon;public List<GameObject> WeaponProps;
[Serializable]public class WeaponSet{public WeaponRef Weapon;public List<GameObject> WeaponProps;}
[SerializeField] List<WeaponRef> _availableWeapons;Dictionary<string, Weapon> _availableWeaponsByName;
[CreateAssetMenu(fileName = "Inventory", menuName = "Combat/Inventory")]public class Inventory : ScriptableObject{[SerializeField] List<WeaponRef> _availableWeapons;Dictionary<string, Weapon> _availableWeaponsByName;
protected void OnEnable() {if (_availableWeapons?.Any() == true) {_availableWeaponsByName = _availableWeapons.Distinct().ToDictionary(weaponRef => weaponRef.Value.Name, weaponRef => weaponRef.Value);
protected void OnEnable() {if (_availableWeapons?.Any() == true) {_availableWeaponsByName = _availableWeapons.Distinct().ToDictionary(weaponRef => weaponRef.Value.Name, weaponRef => weaponRef.Value);}
public bool TryGetWeaponByName(string weaponName, out Weapon weapon) {var isWeaponInInventory = false;weapon = null;if (_availableWeaponsByName != null) {isWeaponInInventory = _availableWeaponsByName.TryGetValue(weaponName, out weapon);
public bool TryGetWeaponByName(string weaponName, out Weapon weapon) {var isWeaponInInventory = false;weapon = null;if (_availableWeaponsByName != null) {isWeaponInInventory = _availableWeaponsByName.TryGetValue(weaponName, out weapon);}return isWeaponInInventory;
List<string> _idleStatesNames = new();string _idleStateName;string _runStateName;
[RequireComponent(typeof(Weaver))]public class AnimationManager : MonoBehaviour{List<string> _idleStatesNames = new();string _idleStateName;string _runStateName;
Animator _animator;AnimatorOverrideController _animatorOverrideController;List<KeyValuePair<AnimationClip, AnimationClip>> _clipOverrides;
Animator _animator;AnimatorOverrideController _animatorOverrideController;List<KeyValuePair<AnimationClip, AnimationClip>> _clipOverrides;
[SerializeField] AnimationClipSetBank _animationBank;Dictionary<string, string> _moveToStateMap = new();Dictionary<string, float> _animationLengths = new();
[SerializeField] AnimationClipSetBank _animationBank;Dictionary<string, string> _moveToStateMap = new();Dictionary<string, float> _animationLengths = new();
void SetWatchedWeaver(Weaver weaver) {if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped -= OnWeaponEquipped;_watchedWeaver.ActionTaken -= OnActionTaken;}
void SetWatchedWeaver(Weaver weaver) {if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped -= OnWeaponEquipped;_watchedWeaver.ActionTaken -= OnActionTaken;}
if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped += OnWeaponEquipped;_watchedWeaver.ActionTaken += OnActionTaken;
if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped += OnWeaponEquipped;_watchedWeaver.ActionTaken += OnActionTaken;}
}protected void Awake() {_animator = GetComponentInChildren<Animator>();_currentActionState = default(IdleState);_nextActionState = default(IdleState);
protected void Awake() {_animator = GetComponentInChildren<Animator>();_currentActionState = default(IdleState);_nextActionState = default(IdleState);
SetWatchedWeaver(GetComponent<Weaver>());}protected void OnDestroy() {SetWatchedWeaver(null);}
SetWatchedWeaver(GetComponent<Weaver>());}protected void OnDestroy() {SetWatchedWeaver(null);}
void OnActionTaken(object sender, Weaver.TakeActionEventArgs e) {SetActionState(e.ActionState);}
void OnActionTaken(object sender, Weaver.TakeActionEventArgs e) {SetActionState(e.ActionState);}
void OnWeaponEquipped(object sender, Weaver.WeaponEquippedEventArgs e) {ChangeClipSet(e.Weapon.Name);}
void OnWeaponEquipped(object sender, Weaver.WeaponEquippedEventArgs e) {ChangeClipSet(e.CurrentWeapon.Name);}
void ChangeClipSet(string weaponName) {var weaponIdx = _animationBank.AnimationClipSets.FindIndex(set => set.Weapon.Value.Name == weaponName);
void ChangeClipSet(string weaponName) {var weaponIdx = _animationBank.AnimationClipSets.FindIndex(set => set.Weapon.Value.Name == weaponName);
if (weaponIdx != -1) {PopulateAnimations(_animationBank.AnimationClipSets[weaponIdx].ClipSet);ResetNextState();_idleStateName = GetNewIdleState();_animator.Play(_idleStateName, _layer, 0f);
if (weaponIdx != -1) {PopulateAnimations(_animationBank.AnimationClipSets[weaponIdx].ClipSet);ResetNextState();_idleStateName = GetNewIdleState();_animator.Play(_idleStateName, _layer, 0f);}
void PopulateAnimations(AnimationClipSet animationClipSet) {_animationLengths.Clear();_moveToStateMap.Clear();_idleStatesNames.Clear();
void PopulateAnimations(AnimationClipSet animationClipSet) {_animationLengths.Clear();_moveToStateMap.Clear();_idleStatesNames.Clear();
_animatorOverrideController = new AnimatorOverrideController(_animator.runtimeAnimatorController);_animator.runtimeAnimatorController = _animatorOverrideController;_clipOverrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(_animatorOverrideController.overridesCount);_animatorOverrideController.GetOverrides(_clipOverrides);
_animatorOverrideController = new AnimatorOverrideController(_animator.runtimeAnimatorController);_animator.runtimeAnimatorController = _animatorOverrideController;_clipOverrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(_animatorOverrideController.overridesCount);_animatorOverrideController.GetOverrides(_clipOverrides);
for (var i = 0; i < _clipOverrides.Count; ++i) {var clipOverride = _clipOverrides[i];var overrideClip = clipOverride.Value;// Assuming State name and Clip Key Name are the samevar stateName = clipOverride.Key.name;if (stateName.Contains("Idle")) {if (_idleStatesNames.Count < animationClipSet.Idle.Count) {_idleStatesNames.Add(stateName);overrideClip = animationClipSet.Idle[_idleStatesNames.Count - 1];
for (var i = 0; i < _clipOverrides.Count; ++i) {var clipOverride = _clipOverrides[i];var overrideClip = clipOverride.Value;// Assuming State name and Clip Key Name are the samevar stateName = clipOverride.Key.name;if (stateName.Contains("Idle")) {if (_idleStatesNames.Count < animationClipSet.Idle.Count) {_idleStatesNames.Add(stateName);overrideClip = animationClipSet.Idle[_idleStatesNames.Count - 1];}
}else if (stateName.Contains("Run")) {_runStateName = stateName;overrideClip = animationClipSet.Run;}else if (stateName.Contains("Attack")) {var attackCount = _moveToStateMap.Count;if (attackCount < animationClipSet.Attacks.Count) {var moveName = animationClipSet.Attacks[attackCount].CombatMove.Value.MoveName;overrideClip = animationClipSet.Attacks[attackCount].AttackAnimation;_moveToStateMap[moveName] = stateName;_animationLengths[moveName] = overrideClip.length;
else if (stateName.Contains("Run")) {_runStateName = stateName;overrideClip = animationClipSet.Run;}else if (stateName.Contains("Attack")) {var attackCount = _moveToStateMap.Count;if (attackCount < animationClipSet.Attacks.Count) {var moveName = animationClipSet.Attacks[attackCount].CombatMove.Value.MoveName;overrideClip = animationClipSet.Attacks[attackCount].AttackAnimation;_moveToStateMap[moveName] = stateName;_animationLengths[moveName] = overrideClip.length;}
_animatorOverrideController.ApplyOverrides(_clipOverrides);}
void SetActionState(IActionState nextActionState) {_nextActionState = nextActionState.IsAdvanced ? nextActionState : default(IdleState);}
void SetActionState(IActionState nextActionState) {_nextActionState = nextActionState.IsAdvanced ? nextActionState : default(IdleState);}
void ResetNextState() {_nextActionState = default(IdleState);}
void ResetNextState() {_nextActionState = default(IdleState);}void HandleIdleState() {switch (_nextActionState) {case IdleState:if (_animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 0.99) {var newIdle = GetNewIdleState();if (_idleStateName != newIdle) {_idleStateName = newIdle;_animator.Play(_idleStateName, _layer, 0f);
void HandleIdleState() {switch (_nextActionState) {case IdleState:if (_animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 0.99) {var newIdle = GetNewIdleState();if (_idleStateName != newIdle) {_idleStateName = newIdle;_animator.Play(_idleStateName, _layer, 0f);}
}break;case MoveToAction.State:_animator.Play(_runStateName, _layer, 0f);break;case WeaveAction.State weave:StartWeave(weave);break;
break;case MoveToAction.State:_animator.Play(_runStateName, _layer, 0f);break;case WeaveAction.State weave:StartWeave(weave);break;}
}void HandleMoveToState() {switch (_nextActionState) {case IdleState:_animator.Update(-Mathf.Floor(_animator.GetCurrentAnimatorStateInfo(_layer).normalizedTime));_animator.CrossFade(_idleStateName, 0.25f, _layer);break;case MoveToAction.State:break;case WeaveAction.State weave:StartWeave(weave);break;
void HandleMoveToState() {switch (_nextActionState) {case IdleState:_animator.Update(-Mathf.Floor(_animator.GetCurrentAnimatorStateInfo(_layer).normalizedTime));_animator.CrossFade(_idleStateName, 0.25f, _layer);break;case MoveToAction.State:break;case WeaveAction.State weave:StartWeave(weave);break;
void HandleWeaveState(WeaveAction.State currentWeave) {switch (_nextActionState) {case IdleState:_animator.Play(_idleStateName, _layer, 0f);break;case MoveToAction.State:_animator.Update(-Mathf.Floor(_animator.GetCurrentAnimatorStateInfo(_layer).normalizedTime));_animator.CrossFade(_runStateName, 0.25f, _layer);break;case WeaveAction.State weave:if (weave.CompletionStatus < 1) {TransitionWeave(currentWeave, weave);}break;
void HandleWeaveState(WeaveAction.State currentWeave) {switch (_nextActionState) {case IdleState:_animator.Play(_idleStateName, _layer, 0f);break;case MoveToAction.State:_animator.Update(-Mathf.Floor(_animator.GetCurrentAnimatorStateInfo(_layer).normalizedTime));_animator.CrossFade(_runStateName, 0.25f, _layer);break;case WeaveAction.State weave:if (weave.CompletionStatus < 1) {TransitionWeave(currentWeave, weave);}break;}
void ApplyActionState() {switch (_currentActionState) {case IdleState:HandleIdleState();break;case MoveToAction.State:HandleMoveToState();break;case WeaveAction.State currentWeave:HandleWeaveState(currentWeave);break;
void ApplyActionState() {switch (_currentActionState) {case IdleState:HandleIdleState();break;case MoveToAction.State:HandleMoveToState();break;case WeaveAction.State currentWeave:HandleWeaveState(currentWeave);break;}_currentActionState = _nextActionState;
void StartWeave(WeaveAction.State nextWeave) {var moveName = nextWeave.Move.MoveName;var moveStateName = _moveToStateMap[moveName];_animator.Update(-Mathf.Floor(_animator.GetCurrentAnimatorStateInfo(_layer).normalizedTime));if (_animator.GetCurrentAnimatorStateInfo(_layer).normalizedTime > 0.9f) {_animator.Play(moveStateName);
void StartWeave(WeaveAction.State nextWeave) {var moveName = nextWeave.Move.MoveName;var moveStateName = _moveToStateMap[moveName];_animator.Update(-Mathf.Floor(_animator.GetCurrentAnimatorStateInfo(_layer).normalizedTime));if (_animator.GetCurrentAnimatorStateInfo(_layer).normalizedTime > 0.9f) {_animator.Play(moveStateName);}else {_animator.CrossFade(moveStateName, 0.1f, _layer);}var animationLength = _animationLengths[moveName];if (nextWeave.Move.Speed > 0) {var desiredSpeed = animationLength / nextWeave.Move.Speed;_animator.SetFloat($"Speed", desiredSpeed);}
var animationLength = _animationLengths[moveName];if (nextWeave.Move.Speed > 0) {var desiredSpeed = animationLength / nextWeave.Move.Speed;_animator.SetFloat($"Speed", desiredSpeed);}}void TransitionWeave(WeaveAction.State currentWeave, WeaveAction.State nextWeave) {if (currentWeave.Move != nextWeave.Move) {StartWeave(nextWeave);
string GetNewIdleState() {var idleAnimationIndex = Random.Range(0, _idleStatesNames.Count);return _idleStatesNames[idleAnimationIndex];
string GetNewIdleState() {var idleAnimationIndex = Random.Range(0, _idleStatesNames.Count);return _idleStatesNames[idleAnimationIndex];}internal readonly struct IdleState : IActionState{public bool IsAdvanced { get; }public float CompletionStatus { get; }public bool IsMoving { get; }
internal readonly struct IdleState : IActionState{public bool IsAdvanced { get; }public float CompletionStatus { get; }public bool IsMoving { get; }
public IdleState(bool isAdvanced, float completionStatus) {IsAdvanced = isAdvanced;CompletionStatus = completionStatus;IsMoving = false;
public IdleState(bool isAdvanced, float completionStatus) {IsAdvanced = isAdvanced;CompletionStatus = completionStatus;IsMoving = false;}
[FormerlySerializedAs("animationClipSets")]public List<AnimationClipSetContainer> AnimationClipSets;}
[CreateAssetMenu(fileName = "AnimationClipSetBank", menuName = "RPG/Animation/AnimationClipSetBank")]public class AnimationClipSetBank : ScriptableObject{[FormerlySerializedAs("animationClipSets")]public List<AnimationClipSetContainer> AnimationClipSets;}
FollowAction _followAction;Transform _target;Weaver _weaver;RuneWeavingContainer _runeWeaving;float _range;bool _startedWeaving = false;static State s_resetState = new(true, 1f, false, default);
public class WeaveAction : IAction{FollowAction _followAction;Transform _target;Weaver _weaver;RuneWeavingContainer _runeWeaving;Resources.Range _range;bool _startedWeaving = false;static State s_resetState = new(true, 1f, false, default);bool _disposed = false;int _lastRange;
public WeaveAction(Weaver unit, RuneWeavingContainer runeWeaving, Transform target, Resources.Range range) {if (range is null) {throw new ArgumentNullException("range");}_target = target;_range = range;_weaver = unit;_runeWeaving = runeWeaving;var currentRange = _range.GetCurrent();_lastRange = currentRange.AsPrimitive();_followAction = new(_weaver, _target, currentRange.ToMeter());_range.ResourceChanged += OnResourceChanged;
if (IsInAttackRange()) {if (_startedWeaving == false) {Debug.Log("Target got in range, weaving");
void OnResourceChanged(object sender, ResourceChangeArgs e) {if (_lastRange != e.Current) {_followAction.Dispose();_followAction = new(_weaver, _target, _range.GetCurrent().ToMeter());_lastRange = e.Current;
else {if (_startedWeaving) {Debug.Log("Target escaped");stateToReturn = new State(false, CompletionStatus(), stateToReturn.IsMoving, _runeWeaving.RuneWeaving.GetCurrentMove());
public IActionState Advance() {var stateToReturn = _followAction.Advance();if (IsInAttackRange()) {if (_startedWeaving == false) {Debug.Log("Target got in range, weaving");}_startedWeaving = true;var isAdvanced = _runeWeaving.RuneWeaving.Advance(Time.deltaTime);stateToReturn = new State(isAdvanced, CompletionStatus(), false, _runeWeaving.RuneWeaving.GetCurrentMove());}else {if (_startedWeaving) {Debug.Log("Target escaped");stateToReturn = new State(false, CompletionStatus(), stateToReturn.IsMoving, _runeWeaving.RuneWeaving.GetCurrentMove());}
public override string ToString() {return $"{_runeWeaving.WeaveName} -> {_target.name}";}bool IsInAttackRange() {// Incorrect in case there are hills. should calc range from feet.Vector3 source = new(_weaver.transform.position.x, 0, _weaver.transform.position.z);Vector3 target = new(_target.position.x, 0, _target.position.z);return Vector3.Distance(source, target) <= _range;}public readonly struct State : IActionState{public bool IsAdvanced { get; }public float CompletionStatus { get; }public bool IsMoving { get; }
public override string ToString() {return $"{_runeWeaving.WeaveName} -> {_target.name}";}bool IsInAttackRange() {// Incorrect in case there are hills. should calc range from feet.Vector3 source = new(_weaver.transform.position.x, 0, _weaver.transform.position.z);Vector3 target = new(_target.position.x, 0, _target.position.z);return Vector3.Distance(source, target) <= _range.GetCurrent().ToMeter();}
public CombatMove Move { get; }
public void Dispose() {Dispose(true);GC.SuppressFinalize(this);}protected virtual void Dispose(bool disposing) {if (!_disposed) {if (disposing) {Cancel();_followAction.Dispose();_followAction = null;_range.ResourceChanged -= OnResourceChanged;_range = null;_runeWeaving = null;_target = null;_weaver = null;}_disposed = true;}}
public State(bool isAdvanced, float completionStatus, bool isMoving, CombatMove move) {IsAdvanced = isAdvanced;CompletionStatus = completionStatus;IsMoving = isMoving;Move = move;
public readonly struct State : IActionState{public bool IsAdvanced { get; }public float CompletionStatus { get; }public bool IsMoving { get; }public CombatMove Move { get; }public State(bool isAdvanced, float completionStatus, bool isMoving, CombatMove move) {IsAdvanced = isAdvanced;CompletionStatus = completionStatus;IsMoving = isMoving;Move = move;}
Vector3 _lastTargetPosition;NavMeshAgent _agent;float _originalStoppingDistance;float _desiredStoppingDistance;bool _isFirstAdvance = true;static State s_resetState = new(false, 0f, false);
public class MoveToAction : IAction{Vector3 _lastTargetPosition;NavMeshAgent _agent;float _originalStoppingDistance;float _desiredStoppingDistance;bool _isFirstAdvance = true;static State s_resetState = new(false, 0f, false);bool _disposed = false;
_lastTargetPosition = target;_desiredStoppingDistance = _agent.stoppingDistance;}public MoveToAction(Weaver unit, Vector3 target, float stoppingDistance) {if (unit == null) {throw new ArgumentNullException("unit");
_lastTargetPosition = target;_desiredStoppingDistance = _agent.stoppingDistance;
if (unit.TryGetComponent(out _agent) == false) {throw new ArgumentException("Missing NavMeshAgent", "unit");
if (unit.TryGetComponent(out _agent) == false) {throw new ArgumentException("Missing NavMeshAgent", "unit");}_lastTargetPosition = target;_desiredStoppingDistance = stoppingDistance;}public bool SetDestination(Vector3 target) {_lastTargetPosition = target;return _agent.SetDestination(target);
_lastTargetPosition = target;_desiredStoppingDistance = stoppingDistance;}public bool SetDestination(Vector3 target) {_lastTargetPosition = target;return _agent.SetDestination(target);}public IActionState Advance() {if (_isFirstAdvance) {_originalStoppingDistance = _agent.stoppingDistance;
public void SetStoppingDistance(float stoppingDistance) {if (stoppingDistance < 0) {throw new ArgumentException("Cannot be < 0", "stoppingDistance");}_desiredStoppingDistance = stoppingDistance;
var isAdvanced = _agent.pathPending || _agent.remainingDistance > _agent.stoppingDistance;return new State(isAdvanced, CompletionStatus(), isAdvanced);}
public IActionState Advance() {if (_isFirstAdvance) {_originalStoppingDistance = _agent.stoppingDistance;_agent.stoppingDistance = _desiredStoppingDistance;_agent.isStopped = false;_agent.SetDestination(_lastTargetPosition);_isFirstAdvance = false;}
public IActionState Cancel() {_agent.isStopped = true;_agent.stoppingDistance = _originalStoppingDistance;_agent.ResetPath();_isFirstAdvance = true;
var isAdvanced = _agent.pathPending || _agent.remainingDistance > _agent.stoppingDistance;return new State(isAdvanced, CompletionStatus(), isAdvanced);}
return s_resetState;}
IActionState Cancel() {_agent.isStopped = true;_agent.stoppingDistance = _originalStoppingDistance;_agent.ResetPath();_isFirstAdvance = true;
public readonly struct State : IActionState{public bool IsAdvanced { get; }public float CompletionStatus { get; }public bool IsMoving { get; }
public float CompletionStatus() {return 0;}public override string ToString() {return $"Move -> {_lastTargetPosition}";}public void Dispose() {Dispose(true);GC.SuppressFinalize(this);}protected virtual void Dispose(bool disposing) {if (!_disposed) {if (disposing) {Cancel();_agent = null;}_disposed = true;}}public readonly struct State : IActionState{public bool IsAdvanced { get; }public float CompletionStatus { get; }public bool IsMoving { get; }
public State(bool isAdvanced, float completionStatus, bool isMoving) {IsAdvanced = isAdvanced;CompletionStatus = completionStatus;IsMoving = isMoving;
public State(bool isAdvanced, float completionStatus, bool isMoving) {IsAdvanced = isAdvanced;CompletionStatus = completionStatus;IsMoving = isMoving;}
public interface IAction{public IActionState Advance();public IActionState Cancel();public float CompletionStatus();}
using System;
public bool IsAdvanced { get; }public float CompletionStatus { get; }public bool IsMoving { get; }
public interface IAction : IDisposable{public IActionState Advance();public float CompletionStatus();}public interface IActionState{public bool IsAdvanced { get; }public float CompletionStatus { get; }public bool IsMoving { get; }}
MoveToAction _moveAction;Transform _target;Vector3 _lastTargetPosition;
public class FollowAction : IAction{MoveToAction _moveAction;Transform _target;Vector3 _lastTargetPosition;bool _disposed = false;
public FollowAction(Weaver unit, Transform target, float stoppingDistance) {_target = target ?? throw new ArgumentNullException("targetToFollow");_lastTargetPosition = target.position;_moveAction = new(unit, _lastTargetPosition, stoppingDistance);}public IActionState Advance() {if (_lastTargetPosition != _target.position) {_lastTargetPosition = _target.position;_moveAction.SetDestination(_lastTargetPosition);
public FollowAction(Weaver unit, Transform target) {_target = target ?? throw new ArgumentNullException("targetToFollow");_lastTargetPosition = target.position;_moveAction = new(unit, _lastTargetPosition);
return _moveAction.Advance();}
public FollowAction(Weaver unit, Transform target, float stoppingDistance) {_target = target ?? throw new ArgumentNullException("targetToFollow");_lastTargetPosition = target.position;_moveAction = new(unit, _lastTargetPosition, stoppingDistance);}
public IActionState Cancel() {return _moveAction.Cancel();}
public void SetStoppingDistance(float stoppingDistance) {_moveAction.SetStoppingDistance(stoppingDistance);}public IActionState Advance() {if (_lastTargetPosition != _target.position) {_lastTargetPosition = _target.position;_moveAction.SetDestination(_lastTargetPosition);}
public float CompletionStatus() {return 0;}public override string ToString() {return $"Follow {_target.name}";
return _moveAction.Advance();}public float CompletionStatus() {return 0;}public void Dispose() {Dispose(true);GC.SuppressFinalize(this);}protected virtual void Dispose(bool disposing) {if (!_disposed) {if (disposing) {_moveAction.Dispose();_moveAction = null;_target = null;}_disposed = true;}}public override string ToString() {return $"Follow {_target.name}";}
[SerializeField] Transform _selectionUI;// [SerializeField] float scale = 1.25f;Transform _selected;[SerializeField] EventAggregator _eventAggregator;
public class TargetIndicator : MonoBehaviour{[SerializeField] Transform _selectionUI;// [SerializeField] float scale = 1.25f;Transform _selected;[SerializeField] EventAggregator _eventAggregator;
protected void Awake() {_selectionUI.gameObject.SetActive(false);}protected void OnDestroy() {_eventAggregator.TargetSelected -= OnTargetSelected;}protected void Update() {SetUnitVisual(_selected);}protected void Start() {_eventAggregator.TargetSelected += OnTargetSelected;}
protected void Awake() {_selectionUI.gameObject.SetActive(false);}protected void OnDestroy() {_eventAggregator.TargetSelected -= OnTargetSelected;}protected void Update() {SetUnitVisual(_selected);}protected void Start() {_eventAggregator.TargetSelected += OnTargetSelected;}
void OnTargetSelected(object sender, UnitActionEventArgs e) {SetSelectedTransform(e.UnitTransform);}
void OnTargetSelected(object sender, UnitActionEventArgs e) {SetSelectedTransform(e.UnitTransform);}
void SetSelectedTransform(Transform selected) {_selected = selected;_selectionUI.gameObject.SetActive(true);SetUnitVisual(_selected);}
void SetSelectedTransform(Transform selected) {_selected = selected;_selectionUI.gameObject.SetActive(true);SetUnitVisual(_selected);}
void SetUnitVisual(Transform selected) {if (selected) {var bounds = selected.GetComponent<Renderer>().bounds;transform.position = new Vector3(bounds.center.x, 0, bounds.center.z);//this.transform.localScale = new Vector3(bounds.size.x, bounds.size.y, bounds.size.z) * scale;
void SetUnitVisual(Transform selected) {if (selected) {var bounds = selected.GetComponent<Renderer>().bounds;transform.position = new Vector3(bounds.center.x, 0, bounds.center.z);//this.transform.localScale = new Vector3(bounds.size.x, bounds.size.y, bounds.size.z) * scale;}
[SerializeField] Transform _selectionUI;[SerializeField] EventAggregator _eventAggregator;
public class SelectionIndicator : MonoBehaviour{[SerializeField] Transform _selectionUI;[SerializeField] EventAggregator _eventAggregator;
// [SerializeField] float scale = 1.25f;Transform _selected;protected void Awake() {_selectionUI.gameObject.SetActive(false);}
// [SerializeField] float scale = 1.25f;Transform _selected;protected void Awake() {_selectionUI.gameObject.SetActive(false);}
protected void OnDestroy() {_eventAggregator.UnitSelected -= OnUnitSelected;_eventAggregator.PartyMemberSelected -= OnPartyMemberSelected;}protected void Update() {SetUnitVisual(_selected);}protected void Start() {_eventAggregator.UnitSelected += OnUnitSelected;_eventAggregator.PartyMemberSelected += OnPartyMemberSelected;}
protected void OnDestroy() {_eventAggregator.UnitSelected -= OnUnitSelected;_eventAggregator.PartyMemberSelected -= OnPartyMemberSelected;}protected void Update() {SetUnitVisual(_selected);}protected void Start() {_eventAggregator.UnitSelected += OnUnitSelected;_eventAggregator.PartyMemberSelected += OnPartyMemberSelected;}
void OnPartyMemberSelected(object sender, EventAggregator.PartyMemberSelectedEventArgs e) {SetSelectedTransform(e.PartyMember.transform);}
void OnPartyMemberSelected(object sender, EventAggregator.PartyMemberSelectedEventArgs e) {SetSelectedTransform(e.PartyMember.transform);}
void OnUnitSelected(object sender, UnitActionEventArgs e) {SetSelectedTransform(e.UnitTransform);}
void OnUnitSelected(object sender, UnitActionEventArgs e) {SetSelectedTransform(e.UnitTransform);}
void SetSelectedTransform(Transform selected) {_selected = selected;_selectionUI.gameObject.SetActive(true);SetUnitVisual(_selected);}
void SetSelectedTransform(Transform selected) {_selected = selected;_selectionUI.gameObject.SetActive(true);SetUnitVisual(_selected);}
void SetUnitVisual(Transform selected) {if (selected) {var bounds = selected.GetComponent<Renderer>().bounds;transform.position = new Vector3(bounds.center.x, 0, bounds.center.z);//this.transform.localScale = new Vector3(bounds.size.x, bounds.size.y, bounds.size.z) * scale;
void SetUnitVisual(Transform selected) {if (selected) {var bounds = selected.GetComponent<Renderer>().bounds;transform.position = new Vector3(bounds.center.x, 0, bounds.center.z);//this.transform.localScale = new Vector3(bounds.size.x, bounds.size.y, bounds.size.z) * scale;}
public Transform UnitTransform { get; }public UnitActionEventArgs(Transform unitTransform) {UnitTransform = unitTransform;
public class UnitActionEventArgs : EventArgs{public Transform UnitTransform { get; }public UnitActionEventArgs(Transform unitTransform) {UnitTransform = unitTransform;}
public class UnitMoveEventArgs : EventArgs{public Vector3 Point { get; }public UnitMoveEventArgs(Vector3 point) {Point = point;
public class UnitMoveEventArgs : EventArgs{public Vector3 Point { get; }public UnitMoveEventArgs(Vector3 point) {Point = point;}
public class PlayerKeyActions : MonoBehaviour{[SerializeField] CameraController _cameraController;[SerializeField] LayerMask _unitSelectionLayerMask;[SerializeField] LayerMask _unitMovementLayerMask;[SerializeField] EventAggregator _eventAggregator;
public class PlayerKeyActions : MonoBehaviour{[SerializeField] CameraController _cameraController;[SerializeField] LayerMask _unitSelectionLayerMask;[SerializeField] LayerMask _unitMovementLayerMask;[SerializeField] EventAggregator _eventAggregator;
protected void Update() {if (_anyGameWorldHidden == false) {HandleTimeDilation();HandleCameraMovement();HandleCameraRotation();HandleUnitActions();
protected void Update() {if (_anyGameWorldHidden == false) {HandleTimeDilation();HandleCameraMovement();HandleCameraRotation();HandleUnitActions();}HandleAdditionalKeyboadClicks();HandleMouseClick();
void HandleAdditionalKeyboadClicks() {if (Input.GetKeyDown(KeyCode.R)) {if (Input.GetKey(KeyCode.LeftControl)) {_eventAggregator.OnWeaveBuilderScreenToggleSelected(this, EventArgs.Empty);_anyGameWorldHidden = !_anyGameWorldHidden;
void HandleAdditionalKeyboadClicks() {if (Input.GetKeyDown(KeyCode.R)) {if (Input.GetKey(KeyCode.LeftControl)) {_eventAggregator.OnWeaveBuilderScreenToggleSelected(this, EventArgs.Empty);_anyGameWorldHidden = !_anyGameWorldHidden;}
void HandleMouseClick() {if (!EventSystem.current.IsPointerOverGameObject()) {if (Input.GetKeyDown(KeyCode.Mouse0)) {var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
void HandleMouseClick() {if (!EventSystem.current.IsPointerOverGameObject()) {if (Input.GetKeyDown(KeyCode.Mouse0)) {var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit)) {var objectHit = hit.transform;if (_unitSelectionLayerMask.IsLayerInMask(objectHit.gameObject.layer)) {_eventAggregator.OnUnitSelected(this, new(objectHit));
if (Physics.Raycast(ray, out var hit)) {var objectHit = hit.transform;if (_unitSelectionLayerMask.IsLayerInMask(objectHit.gameObject.layer)) {_eventAggregator.OnUnitSelected(this, new(objectHit));}
}else if (Input.GetKeyDown(KeyCode.Mouse1)) {var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
else if (Input.GetKeyDown(KeyCode.Mouse1)) {var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit)) {var objectHit = hit.transform;if (_unitSelectionLayerMask.IsLayerInMask(objectHit.gameObject.layer)) {_eventAggregator.OnTargetSelected(this, new(objectHit));}else if (_unitMovementLayerMask.IsLayerInMask(objectHit.gameObject.layer)) {if (Input.GetKey(KeyCode.LeftControl)) {_eventAggregator.OnUnitMove(this, new(hit.point));
if (Physics.Raycast(ray, out var hit)) {var objectHit = hit.transform;if (_unitSelectionLayerMask.IsLayerInMask(objectHit.gameObject.layer)) {_eventAggregator.OnTargetSelected(this, new(objectHit));
else {_eventAggregator.OnPlannedActionsClearSelected(this, EventArgs.Empty);_eventAggregator.OnUnitMove(this, new(hit.point));
else if (_unitMovementLayerMask.IsLayerInMask(objectHit.gameObject.layer)) {if (Input.GetKey(KeyCode.LeftControl)) {_eventAggregator.OnUnitMove(this, new(hit.point));}else {_eventAggregator.OnPlannedActionsClearSelected(this, EventArgs.Empty);_eventAggregator.OnUnitMove(this, new(hit.point));}
void HandleTimeDilation() {if (Input.GetKeyDown(KeyCode.Period)) {_eventAggregator.OnTimeDilationSpeedUp(this, EventArgs.Empty);}if (Input.GetKeyDown(KeyCode.Comma)) {_eventAggregator.OnTimeDilationSpeedDown(this, EventArgs.Empty);}if (Input.GetKeyDown(KeyCode.Slash)) {_eventAggregator.OnTimeDilationSpeedReset(this, EventArgs.Empty);
void HandleTimeDilation() {if (Input.GetKeyDown(KeyCode.Period)) {_eventAggregator.OnTimeDilationSpeedUp(this, EventArgs.Empty);}if (Input.GetKeyDown(KeyCode.Comma)) {_eventAggregator.OnTimeDilationSpeedDown(this, EventArgs.Empty);}if (Input.GetKeyDown(KeyCode.Slash)) {_eventAggregator.OnTimeDilationSpeedReset(this, EventArgs.Empty);}
}
void HandleCameraMovement() {if (Input.GetKey(KeyCode.W)) {_cameraController.MoveForward();}if (Input.GetKey(KeyCode.A)) {_cameraController.MoveLeft();}if (Input.GetKey(KeyCode.S)) {_cameraController.MoveBack();}if (Input.GetKey(KeyCode.D)) {_cameraController.MoveRight();}
if (Input.GetKey(KeyCode.A)) {_cameraController.MoveLeft();
void HandleCameraRotation() {if (Input.GetKey(KeyCode.Q)) {_cameraController.RotateLeft();}if (Input.GetKey(KeyCode.E)) {_cameraController.RotateRight();}
if (Input.GetKey(KeyCode.S)) {_cameraController.MoveBack();}if (Input.GetKey(KeyCode.D)) {_cameraController.MoveRight();}
}
}void HandleCameraRotation() {if (Input.GetKey(KeyCode.Q)) {_cameraController.RotateLeft();}if (Input.GetKey(KeyCode.E)) {_cameraController.RotateRight();
public static class LayerMaskExtensions{public static bool IsLayerInMask(this LayerMask layerMask, int layer) {return layerMask == (layerMask | (1 << layer));
}public static class LayerMaskExtensions{public static bool IsLayerInMask(this LayerMask layerMask, int layer) {return layerMask == (layerMask | (1 << layer));}
fileFormatVersion: 2guid: 3637ce6e45f295d47863202e7233aedfMonoImporter:externalObjects: {}serializedVersion: 2defaultReferences: []executionOrder: 0icon: {instanceID: 0}userData:assetBundleName:assetBundleVariant:
using System;namespace TagFighter.Resources{[Serializable]public sealed class Range : Resource<Centimeter> { }public static class CentimeterExtensions{public static float ToMeter(this Unit<Centimeter> source) {return source.AsPrimitive() * 0.01f;}}}
public event EventHandler<UnitActionEventArgs> UnitSelected;public event EventHandler<UnitMoveEventArgs> UnitMove;public event EventHandler<TryRemovePlannedActionEventArgs> RemovePlannedActionSelected;public event EventHandler<UnitActionEventArgs> TargetSelected;
[CreateAssetMenu(fileName = "NewEventAggregator", menuName = "Combat/EventAggregator")]public class EventAggregator : ScriptableObject{public event EventHandler<PartyMemberSelectedEventArgs> PartyMemberSelected;
public event EventHandler<WeaponSelectedEventArgs> WeaponSelected;public event EventHandler<CombatFormSelectedEventArgs> CombatFormSelected;
public event EventHandler<UnitActionEventArgs> UnitSelected;public event EventHandler<UnitMoveEventArgs> UnitMove;public event EventHandler<TryRemovePlannedActionEventArgs> RemovePlannedActionSelected;public event EventHandler<UnitActionEventArgs> TargetSelected;
public event EventHandler TimeDilationSpeedUp;public event EventHandler TimeDilationSpeedDown;public event EventHandler TimeDilationSpeedReset;public event EventHandler TimeDilationSpeedPause;
public event EventHandler<WeaponSelectedEventArgs> WeaponSelected;public event EventHandler<CombatFormSelectedEventArgs> CombatFormSelected;
public event EventHandler WeaveBuilderScreenToggleSelected;
public event EventHandler TimeDilationSpeedUp;public event EventHandler TimeDilationSpeedDown;public event EventHandler TimeDilationSpeedReset;public event EventHandler TimeDilationSpeedPause;
public void OnPartyMemberSelected(object sender, PartyMemberSelectedEventArgs e) {PartyMemberSelected?.Invoke(sender, e);}public void OnUnitSelected(object sender, UnitActionEventArgs e) {UnitSelected?.Invoke(sender, e);}public void OnUnitMove(object sender, UnitMoveEventArgs e) {UnitMove?.Invoke(sender, e);}public void OnWeaponSelected(object sender, WeaponSelectedEventArgs e) {WeaponSelected?.Invoke(sender, e);}public void InvokeOnCombatFormSelected(object sender, CombatFormSelectedEventArgs e) {CombatFormSelected?.Invoke(sender, e);}public void OnRemovePlannedActionSelected(object sender, TryRemovePlannedActionEventArgs e) {RemovePlannedActionSelected?.Invoke(sender, e);}public void OnTargetSelected(object sender, UnitActionEventArgs e) {TargetSelected?.Invoke(sender, e);}public void OnTimeDilationSpeedUp(object sender, EventArgs e) {TimeDilationSpeedUp?.Invoke(sender, e);}public void OnTimeDilationSpeedDown(object sender, EventArgs e) {TimeDilationSpeedDown?.Invoke(sender, e);}public void OnTimeDilationSpeedReset(object sender, EventArgs e) {TimeDilationSpeedReset?.Invoke(sender, e);}public void OnTimeDilationSpeedPause(object sender, EventArgs e) {TimeDilationSpeedPause?.Invoke(sender, e);}public void OnWeaveBuilderScreenToggleSelected(object sender, EventArgs e) {WeaveBuilderScreenToggleSelected?.Invoke(sender, e);}public void OnRuneWeavingBankChanged(object sender, RuneWeavingBankChangedEventArgs e) {RuneWeavingBankChanged?.Invoke(sender, e);}
public void OnRuneWeavingCastSelected(object sender, WeaveCastEventArgs e) {RuneWeavingCastSelected?.Invoke(sender, e);}public void OnPlannedActionsClearSelected(object sender, EventArgs e) {PlannedActionsClearSelected?.Invoke(sender, e);}
public void OnPartyMemberSelected(object sender, PartyMemberSelectedEventArgs e) {PartyMemberSelected?.Invoke(sender, e);}public void OnUnitSelected(object sender, UnitActionEventArgs e) {UnitSelected?.Invoke(sender, e);}public void OnUnitMove(object sender, UnitMoveEventArgs e) {UnitMove?.Invoke(sender, e);}public void OnWeaponSelected(object sender, WeaponSelectedEventArgs e) {WeaponSelected?.Invoke(sender, e);}public void InvokeOnCombatFormSelected(object sender, CombatFormSelectedEventArgs e) {CombatFormSelected?.Invoke(sender, e);}public void OnRemovePlannedActionSelected(object sender, TryRemovePlannedActionEventArgs e) {RemovePlannedActionSelected?.Invoke(sender, e);}public void OnTargetSelected(object sender, UnitActionEventArgs e) {TargetSelected?.Invoke(sender, e);}public void OnTimeDilationSpeedUp(object sender, EventArgs e) {TimeDilationSpeedUp?.Invoke(sender, e);}public void OnTimeDilationSpeedDown(object sender, EventArgs e) {TimeDilationSpeedDown?.Invoke(sender, e);}public void OnTimeDilationSpeedReset(object sender, EventArgs e) {TimeDilationSpeedReset?.Invoke(sender, e);}public void OnTimeDilationSpeedPause(object sender, EventArgs e) {TimeDilationSpeedPause?.Invoke(sender, e);}public void OnWeaveBuilderScreenToggleSelected(object sender, EventArgs e) {WeaveBuilderScreenToggleSelected?.Invoke(sender, e);}public void OnRuneWeavingBankChanged(object sender, RuneWeavingBankChangedEventArgs e) {RuneWeavingBankChanged?.Invoke(sender, e);}
#region eventspublic class TryRemovePlannedActionEventArgs : EventArgs{public int Index { get; }public TryRemovePlannedActionEventArgs(int index) {if (index < 0) {throw new IndexOutOfRangeException("index");
public void OnRuneWeavingCastSelected(object sender, WeaveCastEventArgs e) {RuneWeavingCastSelected?.Invoke(sender, e);}public void OnPlannedActionsClearSelected(object sender, EventArgs e) {PlannedActionsClearSelected?.Invoke(sender, e);}#region eventspublic class TryRemovePlannedActionEventArgs : EventArgs{public int Index { get; }public TryRemovePlannedActionEventArgs(int index) {if (index < 0) {throw new IndexOutOfRangeException("index");}Index = index;
}public class WeaveCastEventArgs : EventArgs{public RuneWeavingContainer Weave { get; }public WeaveCastEventArgs(RuneWeavingContainer weave) {Weave = weave;
public class WeaveCastEventArgs : EventArgs{public RuneWeavingContainer Weave { get; }public WeaveCastEventArgs(RuneWeavingContainer weave) {Weave = weave;}
}public class RuneWeavingBankChangedEventArgs : EventArgs{public RuneWeavingBank Bank { get; }public RuneWeavingBankChangedEventArgs(RuneWeavingBank bank) {Bank = bank;
public class RuneWeavingBankChangedEventArgs : EventArgs{public RuneWeavingBank Bank { get; }public RuneWeavingBankChangedEventArgs(RuneWeavingBank bank) {Bank = bank;}
}public class PartyMemberSelectedEventArgs : EventArgs{public PartyMember PartyMember { get; }public PartyMemberSelectedEventArgs(PartyMember partyMember) {PartyMember = partyMember;
public class PartyMemberSelectedEventArgs : EventArgs{public PartyMember PartyMember { get; }public PartyMemberSelectedEventArgs(PartyMember partyMember) {PartyMember = partyMember;}
}public class WeaponSelectedEventArgs : EventArgs{public Weapon Weapon { get; }public WeaponSelectedEventArgs(Weapon weapon) {Weapon = weapon;
public class WeaponSelectedEventArgs : EventArgs{public Weapon Weapon { get; }public WeaponSelectedEventArgs(Weapon weapon) {Weapon = weapon;}
}public class CombatFormSelectedEventArgs : EventArgs{public CombatForm CombatForm { get; }public CombatFormSelectedEventArgs(CombatForm combatForm) {CombatForm = combatForm;
public class CombatFormSelectedEventArgs : EventArgs{public CombatForm CombatForm { get; }public CombatFormSelectedEventArgs(CombatForm combatForm) {CombatForm = combatForm;}
[SerializeField] EventAggregator _eventAggregator;Transform _targetUnit;Transform TargetUnit {get {return _targetUnit;}set {if (_targetUnit != null) {TryUnregisterRuneWeavingCast();
public class UnitController : MonoBehaviour{[SerializeField] EventAggregator _eventAggregator;Transform _targetUnit;Transform TargetUnit {get {return _targetUnit;
}Weaver _selectedWeaver;Weaver SelectedWeaver {get {return _selectedWeaver;}set {if (_selectedWeaver != null) {_eventAggregator.PlannedActionsClearSelected -= OnPlannedActionsClearSelected;_eventAggregator.RemovePlannedActionSelected -= OnRemovePlannedActionSelected;_eventAggregator.CombatFormSelected -= OnCombatFormSelected;_eventAggregator.UnitMove -= OnUnitMove;_eventAggregator.WeaponSelected -= OnWeaponSelected;TryUnregisterRuneWeavingCast();
Weaver _selectedWeaver;Weaver SelectedWeaver {get {return _selectedWeaver;
_selectedWeaver = value;
set {if (_selectedWeaver != null) {_eventAggregator.PlannedActionsClearSelected -= OnPlannedActionsClearSelected;_eventAggregator.RemovePlannedActionSelected -= OnRemovePlannedActionSelected;_eventAggregator.CombatFormSelected -= OnCombatFormSelected;_eventAggregator.UnitMove -= OnUnitMove;_eventAggregator.WeaponSelected -= OnWeaponSelected;TryUnregisterRuneWeavingCast();}_selectedWeaver = value;
if (_selectedWeaver != null) {_eventAggregator.PlannedActionsClearSelected += OnPlannedActionsClearSelected;_eventAggregator.RemovePlannedActionSelected += OnRemovePlannedActionSelected;_eventAggregator.CombatFormSelected += OnCombatFormSelected;_eventAggregator.UnitMove += OnUnitMove;_eventAggregator.WeaponSelected += OnWeaponSelected;TryRegisterRuneWeavingCast();
if (_selectedWeaver != null) {_eventAggregator.PlannedActionsClearSelected += OnPlannedActionsClearSelected;_eventAggregator.RemovePlannedActionSelected += OnRemovePlannedActionSelected;_eventAggregator.CombatFormSelected += OnCombatFormSelected;_eventAggregator.UnitMove += OnUnitMove;_eventAggregator.WeaponSelected += OnWeaponSelected;TryRegisterRuneWeavingCast();}
protected void Start() {_eventAggregator.UnitSelected += OnUnitSelected;_eventAggregator.PartyMemberSelected += OnPartyMemberSelected;
protected void Start() {_eventAggregator.UnitSelected += OnUnitSelected;_eventAggregator.PartyMemberSelected += OnPartyMemberSelected;
protected void OnDestroy() {_eventAggregator.UnitSelected -= OnUnitSelected;_eventAggregator.PartyMemberSelected -= OnPartyMemberSelected;
protected void OnDestroy() {_eventAggregator.UnitSelected -= OnUnitSelected;_eventAggregator.PartyMemberSelected -= OnPartyMemberSelected;
bool TryUnregisterRuneWeavingCast() {var unregistered = false;if (SelectedWeaver && TargetUnit) {_eventAggregator.RuneWeavingCastSelected -= OnRuneWeavingCastSelected;unregistered = true;
bool TryUnregisterRuneWeavingCast() {var unregistered = false;if (SelectedWeaver && TargetUnit) {_eventAggregator.RuneWeavingCastSelected -= OnRuneWeavingCastSelected;unregistered = true;}return unregistered;
return unregistered;}bool TryRegisterRuneWeavingCast() {var registered = false;if (SelectedWeaver && TargetUnit) {_eventAggregator.RuneWeavingCastSelected += OnRuneWeavingCastSelected;registered = true;
bool TryRegisterRuneWeavingCast() {var registered = false;if (SelectedWeaver && TargetUnit) {_eventAggregator.RuneWeavingCastSelected += OnRuneWeavingCastSelected;registered = true;}return registered;
void OnPlannedActionsClearSelected(object sender, EventArgs e) {SelectedWeaver.ClearActionPlan();}
void OnPlannedActionsClearSelected(object sender, EventArgs e) {SelectedWeaver.ClearActionPlan();}
void OnRemovePlannedActionSelected(object sender, EventAggregator.TryRemovePlannedActionEventArgs e) {SelectedWeaver.TryRemoveActionFromPlan(e.Index);}
void OnRemovePlannedActionSelected(object sender, EventAggregator.TryRemovePlannedActionEventArgs e) {SelectedWeaver.TryRemoveActionFromPlan(e.Index);}
void OnRuneWeavingCastSelected(object sender, EventAggregator.WeaveCastEventArgs e) {SelectedWeaver.TryQueueWeave(new(e.Weave, SelectedWeaver.transform, TargetUnit), TargetUnit);}
void OnRuneWeavingCastSelected(object sender, EventAggregator.WeaveCastEventArgs e) {SelectedWeaver.TryQueueWeave(new(e.Weave, SelectedWeaver.transform, TargetUnit), TargetUnit);}
void OnCombatFormSelected(object sender, EventAggregator.CombatFormSelectedEventArgs e) {SelectedWeaver.TryEquipCombatForm(e.CombatForm.Name);}
void OnCombatFormSelected(object sender, EventAggregator.CombatFormSelectedEventArgs e) {SelectedWeaver.TryEquipCombatForm(e.CombatForm.Name);}
void OnWeaponSelected(object sender, EventAggregator.WeaponSelectedEventArgs e) {SelectedWeaver.TryDrawWeapon(e.Weapon.Name);}
void OnWeaponSelected(object sender, EventAggregator.WeaponSelectedEventArgs e) {SelectedWeaver.TryDrawWeapon(e.Weapon.Name);}
void OnUnitMove(object sender, UnitMoveEventArgs e) {SelectedWeaver.TryQueueMove(e.Point);}void OnTargetSelected(object sender, UnitActionEventArgs e) {TargetUnit = e.UnitTransform;}void OnPartyMemberSelected(object sender, EventAggregator.PartyMemberSelectedEventArgs e) {if (e.PartyMember.TryGetComponent<Weaver>(out var weaver)) {SelectedWeaver = weaver;
void OnUnitMove(object sender, UnitMoveEventArgs e) {SelectedWeaver.TryQueueMove(e.Point);}void OnTargetSelected(object sender, UnitActionEventArgs e) {TargetUnit = e.UnitTransform;}void OnPartyMemberSelected(object sender, EventAggregator.PartyMemberSelectedEventArgs e) {if (e.PartyMember.TryGetComponent<Weaver>(out var weaver)) {SelectedWeaver = weaver;}
}void OnUnitSelected(object sender, UnitActionEventArgs e) {if (e.UnitTransform.TryGetComponent<Weaver>(out var weaver)) {SelectedWeaver = weaver;
void OnUnitSelected(object sender, UnitActionEventArgs e) {if (e.UnitTransform.TryGetComponent<Weaver>(out var weaver)) {SelectedWeaver = weaver;}
[SerializeField] float _dilationStep = 0.25f;public const float MaxTimeDilation = 4f;const float MinTimeDilation = 0f;const int TimeDilationPercision = 2;float _baseTimeScale;[SerializeField] EventAggregator _eventAggregator;
public class TimeDilationController : MonoBehaviour{[SerializeField] float _dilationStep = 0.25f;public const float MaxTimeDilation = 4f;const float MinTimeDilation = 0f;const int TimeDilationPercision = 2;float _baseTimeScale;[SerializeField] EventAggregator _eventAggregator;
protected void Start() {_eventAggregator.TimeDilationSpeedUp += OnTimeDilationSpeedUp;_eventAggregator.TimeDilationSpeedDown += OnTimeDilationSpeedDown;_eventAggregator.TimeDilationSpeedReset += OnTimeDilationSpeedReset;_eventAggregator.TimeDilationSpeedPause += OnTimeDilationSpeedPause;_baseTimeScale = Time.timeScale;}
protected void Start() {_eventAggregator.TimeDilationSpeedUp += OnTimeDilationSpeedUp;_eventAggregator.TimeDilationSpeedDown += OnTimeDilationSpeedDown;_eventAggregator.TimeDilationSpeedReset += OnTimeDilationSpeedReset;_eventAggregator.TimeDilationSpeedPause += OnTimeDilationSpeedPause;_baseTimeScale = Time.timeScale;}
protected void OnDestroy() {_eventAggregator.TimeDilationSpeedUp -= OnTimeDilationSpeedUp;_eventAggregator.TimeDilationSpeedDown -= OnTimeDilationSpeedDown;_eventAggregator.TimeDilationSpeedReset -= OnTimeDilationSpeedReset;_eventAggregator.TimeDilationSpeedPause -= OnTimeDilationSpeedPause;}
protected void OnDestroy() {_eventAggregator.TimeDilationSpeedUp -= OnTimeDilationSpeedUp;_eventAggregator.TimeDilationSpeedDown -= OnTimeDilationSpeedDown;_eventAggregator.TimeDilationSpeedReset -= OnTimeDilationSpeedReset;_eventAggregator.TimeDilationSpeedPause -= OnTimeDilationSpeedPause;}void OnTimeDilationSpeedPause(object sender, EventArgs e) {Time.timeScale = 0;}void OnTimeDilationSpeedReset(object sender, EventArgs e) {Time.timeScale = _baseTimeScale;}
void OnTimeDilationSpeedPause(object sender, EventArgs e) {Time.timeScale = 0;}void OnTimeDilationSpeedReset(object sender, EventArgs e) {Time.timeScale = _baseTimeScale;}
void OnTimeDilationSpeedDown(object sender, EventArgs e) {Time.timeScale = MathF.Max(MinTimeDilation, MathF.Round(Time.timeScale - _dilationStep, TimeDilationPercision));}
void OnTimeDilationSpeedDown(object sender, EventArgs e) {Time.timeScale = MathF.Max(MinTimeDilation, MathF.Round(Time.timeScale - _dilationStep, TimeDilationPercision));}
void OnTimeDilationSpeedUp(object sender, EventArgs e) {Time.timeScale = MathF.Min(MaxTimeDilation, MathF.Round(Time.timeScale + _dilationStep, TimeDilationPercision));}
public void AddWeave(RuneWeaving runeWeaving, ValidWeaveName weaveName) {_runeWeavings.Add(new RuneWeavingContainer(weaveName, runeWeaving));_eventAggregator.OnRuneWeavingBankChanged(this, new EventAggregator.RuneWeavingBankChangedEventArgs(this));}
[CreateAssetMenu(fileName = "RuneWeavingBank", menuName = "Combat/RuneWeavingBank")]public class RuneWeavingBank : ScriptableObject{[SerializeField] EventAggregator _eventAggregator;[SerializeField] List<RuneWeavingContainer> _runeWeavings = new();
public bool TryDeleteWeaveByName(ValidWeaveName weaveName) {var found = false;var weaveIndex = _runeWeavings.FindIndex(weave => weave.WeaveName == weaveName);found = weaveIndex != -1;if (found == true) {_runeWeavings.RemoveAt(weaveIndex);_eventAggregator.OnRuneWeavingBankChanged(this, new(this));
public void AddWeave(RuneWeaving runeWeaving, ValidWeaveName weaveName) {_runeWeavings.Add(new RuneWeavingContainer(weaveName, runeWeaving));_eventAggregator.OnRuneWeavingBankChanged(this, new EventAggregator.RuneWeavingBankChangedEventArgs(this));
public bool TryGetWeaveByName(ValidWeaveName weaveName, out RuneWeavingContainer runeWeavingContainer) {var found = false;var weaveIndex = _runeWeavings.FindIndex(weave => weave.WeaveName == weaveName);found = weaveIndex != -1;if (found == true) {runeWeavingContainer = _runeWeavings[weaveIndex];}else {runeWeavingContainer = null;
public bool TryDeleteWeaveByName(ValidWeaveName weaveName) {var found = false;var weaveIndex = _runeWeavings.FindIndex(weave => weave.WeaveName == weaveName);found = weaveIndex != -1;if (found == true) {_runeWeavings.RemoveAt(weaveIndex);_eventAggregator.OnRuneWeavingBankChanged(this, new(this));}return found;
public IEnumerable<RuneWeavingContainer> GetWeaves() => _runeWeavings;}
public bool TryGetWeaveByName(ValidWeaveName weaveName, out RuneWeavingContainer runeWeavingContainer) {var found = false;var weaveIndex = _runeWeavings.FindIndex(weave => weave.WeaveName == weaveName);found = weaveIndex != -1;if (found == true) {runeWeavingContainer = _runeWeavings[weaveIndex];}else {runeWeavingContainer = null;}return found;}
[Serializable]public class RuneWeavingContainer{public RuneWeaving RuneWeaving;public ValidWeaveName WeaveName;public RuneWeavingContainer(ValidWeaveName weaveName, RuneWeaving runeWeaving) {WeaveName = weaveName;RuneWeaving = runeWeaving;}public RuneWeavingContainer(RuneWeavingContainer toCopy, Transform caster, Transform target) {RuneWeaving = new RuneWeaving(toCopy.RuneWeaving.MartialSequence.GetSequence(), toCopy.RuneWeaving.RuneBindingSequence.GetSequence(), caster, target);WeaveName = toCopy.WeaveName;
public IEnumerable<RuneWeavingContainer> GetWeaves() => _runeWeavings;
[Serializable]public record ValidWeaveName{[SerializeField] string _weaveName;ValidWeaveName(string weaveName) {_weaveName = weaveName;
[Serializable]public class RuneWeavingContainer{public RuneWeaving RuneWeaving;public ValidWeaveName WeaveName;public RuneWeavingContainer(ValidWeaveName weaveName, RuneWeaving runeWeaving) {WeaveName = weaveName;RuneWeaving = runeWeaving;}public RuneWeavingContainer(RuneWeavingContainer toCopy, Transform caster, Transform target) {RuneWeaving = new RuneWeaving(toCopy.RuneWeaving.MartialSequence.GetSequence(), toCopy.RuneWeaving.RuneBindingSequence.GetSequence(), caster, target);WeaveName = toCopy.WeaveName;}
public bool TrySetName(string weaveName) {var validName = IsWeaveNameValid(weaveName);if (validName) {
[Serializable]public record ValidWeaveName{[SerializeField] string _weaveName;ValidWeaveName(string weaveName) {
public static bool TryParse(string weaveName, out ValidWeaveName validWeaveName) {var validName = IsWeaveNameValid(weaveName);if (validName) {validWeaveName = new ValidWeaveName(weaveName);
public static bool TryParse(string weaveName, out ValidWeaveName validWeaveName) {var validName = IsWeaveNameValid(weaveName);if (validName) {validWeaveName = new ValidWeaveName(weaveName);}else {validWeaveName = null;}return validName;
public static bool IsWeaveNameValid(string weaveName) {return weaveName.Length > 0;}public static implicit operator string(ValidWeaveName validWeaveName) => validWeaveName._weaveName;
ApplyTrigger.TriggerConditionMet -= ApplyTrigger_OnTriggerConditionMet;ApplyTrigger.UnRegister();EndTrigger.TriggerConditionMet -= EndTrigger_OnTriggerConditionMet;EndTrigger.UnRegister();
if (ApplyTrigger != null) {ApplyTrigger.Unregister();ApplyTrigger.TriggerConditionMet -= ApplyTrigger_OnTriggerConditionMet;}if (EndTrigger != null) {EndTrigger.Unregister();EndTrigger.TriggerConditionMet -= EndTrigger_OnTriggerConditionMet;}
}}[Serializable]public class OnApply : ITrigger{public event EventHandler<ConditionTriggerArgs> TriggerConditionMet;public void Register(PawnCondition condition) {OnTriggerConditionMet(new());}public ITrigger ShallowCopy() {return (ITrigger)MemberwiseClone();}public void Unregister() {}protected void OnTriggerConditionMet(ConditionTriggerArgs e) {TriggerConditionMet?.Invoke(this, e);
}
[Serializable]public class OnEquip : ITrigger{public WeaponRef WatchedWeapon;public event EventHandler<ConditionTriggerArgs> TriggerConditionMet;Weaver _watchedWeaver;public void Register(PawnCondition condition) {_watchedWeaver = condition.GetComponent<Weaver>();if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped += OnWeaponEquipped;}}void OnWeaponEquipped(object sender, Weaver.WeaponEquippedEventArgs e) {if (WatchedWeapon.Value == e.CurrentWeapon) {OnTriggerConditionMet(new());}}public ITrigger ShallowCopy() {return (ITrigger)MemberwiseClone();}public void Unregister() {if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped -= OnWeaponEquipped;_watchedWeaver = null;WatchedWeapon = null;}}protected void OnTriggerConditionMet(ConditionTriggerArgs e) {TriggerConditionMet?.Invoke(this, e);}}[Serializable]public class OnUnequip : ITrigger{public WeaponRef WatchedWeapon;public event EventHandler<ConditionTriggerArgs> TriggerConditionMet;Weaver _watchedWeaver;public void Register(PawnCondition condition) {_watchedWeaver = condition.GetComponent<Weaver>();if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped += OnWeaponEquipped;}}void OnWeaponEquipped(object sender, Weaver.WeaponEquippedEventArgs e) {if (WatchedWeapon.Value == e.PreviousWeapon) {OnTriggerConditionMet(new());}}public ITrigger ShallowCopy() {return (ITrigger)MemberwiseClone();}public void Unregister() {if (_watchedWeaver != null) {_watchedWeaver.WeaponEquipped -= OnWeaponEquipped;_watchedWeaver = null;WatchedWeapon = null;}}protected void OnTriggerConditionMet(ConditionTriggerArgs e) {TriggerConditionMet?.Invoke(this, e);}}}
[SerializeField] Weapon _weapon;public static implicit operator Weapon(WeaponRef weaponRef) => weaponRef.Value;
[CreateAssetMenu(fileName = "Weapon", menuName = "Combat/Weapon")][Serializable]public class WeaponRef : ScriptableObject{[SerializeField] Weapon _weapon;public static implicit operator Weapon(WeaponRef weaponRef) => weaponRef.Value;
public string Name;[SerializeField] float _range;[SerializeField] CombatMoveSetRef _weaponMoveSet;[SerializeField] List<CombatFormRef> _compatibleCombatForms;
public interface IItem{public IEnumerable<EffectTypePair> MainHandEffects();}
public IEnumerable<CombatFormRef> GetCompatibleFormRefs() {return _compatibleCombatForms;
[Flags]public enum ItemSlot{None = 0,Head = 1 << 0,Shoulder = 1 << 1,Body = 1 << 2,Arms = 1 << 3,MainHand = 1 << 4,OffHand = 1 << 5,Leg = 1 << 6,Foot = 1 << 7
public CombatMoveSetRef GetCombatMoveSetRef() => _weaponMoveSet;public float GetRange() => _range;
[Serializable]public class Weapon : IItem{public string Name;[SerializeField] CombatMoveSetRef _weaponMoveSet;[SerializeField] List<CombatFormRef> _compatibleCombatForms;[SerializeField] List<ItemEffectSlot> _effects;public IEnumerable<CombatFormRef> GetCompatibleFormRefs() {return _compatibleCombatForms;}public CombatMoveSetRef GetCombatMoveSetRef() => _weaponMoveSet;public IEnumerable<EffectTypePair> MainHandEffects() {return GetEffects(ItemSlot.MainHand);}protected virtual IEnumerable<EffectTypePair> GetEffects(ItemSlot slots) {return _effects.Where(effectSlot => effectSlot.Slot.HasFlag(slots)).Select(itemEffectSlot => itemEffectSlot.Effect);}}
_effects:- Slot: 16Effect:Mode:rid: 6090675012705714188Effect:rid: 6090675012705714189- Slot: -1Effect:Mode:rid: 6090675012705714193Effect:rid: 6090675012705714197references:version: 2RefIds:- rid: -2type: {class: , ns: , asm: }- rid: 6090675012705714188type: {class: DelayedEffect, ns: TagFighter.Effects, asm: Assembly-CSharp}- rid: 6090675012705714189type: {class: UnaryResourceEffect, ns: TagFighter.Effects, asm: Assembly-CSharp}data:From:Resource:rid: -2Location:rid: -2Multiplier: 1Addend: 0To:Resource:rid: 6090675012705714190Location:rid: 6090675012705714191Multiplier: 1Addend: 150- rid: 6090675012705714190type: {class: Range, ns: TagFighter.Effects.ResourceTypeAccessors, asm: Assembly-CSharp}- rid: 6090675012705714191type: {class: Pawn, ns: TagFighter.Effects.ResourceLocationAccessors.Set, asm: Assembly-CSharp}data:Property:rid: 6090675012705714192- rid: 6090675012705714192type: {class: Current, ns: TagFighter.Effects.ResourceLocationAccessors.PawnProperties,asm: Assembly-CSharp}- rid: 6090675012705714193type: {class: PeriodicWeave, ns: TagFighter.Effects, asm: Assembly-CSharp}data:AreaOfEffect:rid: 6090675012705714194ApplyTrigger:rid: 6090675012705714195EndTrigger:rid: 6090675012705714196IsPermanent: 0- rid: 6090675012705714194type: {class: Single, ns: TagFighter.Effects.AoeShapes, asm: Assembly-CSharp}- rid: 6090675012705714195type: {class: OnEquip, ns: TagFighter.Effects.Triggers, asm: Assembly-CSharp}data:WatchedWeapon: {fileID: 11400000}- rid: 6090675012705714196type: {class: OnUnequip, ns: TagFighter.Effects.Triggers, asm: Assembly-CSharp}data:WatchedWeapon: {fileID: 11400000}- rid: 6090675012705714197type: {class: AoeEffect, ns: TagFighter.Effects, asm: Assembly-CSharp}data:Shape:rid: 6090675012705714198- rid: 6090675012705714198type: {class: Single, ns: TagFighter.Effects.AoeShapes, asm: Assembly-CSharp}
_effects:- Slot: 16Effect:Mode:rid: 6090675012705714176Effect:rid: 6090675012705714177- Slot: -1Effect:Mode:rid: 6090675012705714181Effect:rid: 6090675012705714184references:version: 2RefIds:- rid: -2type: {class: , ns: , asm: }- rid: 6090675012705714176type: {class: DelayedEffect, ns: TagFighter.Effects, asm: Assembly-CSharp}- rid: 6090675012705714177type: {class: UnaryResourceEffect, ns: TagFighter.Effects, asm: Assembly-CSharp}data:From:Resource:rid: -2Location:rid: -2Multiplier: 1Addend: 0To:Resource:rid: 6090675012705714178Location:rid: 6090675012705714179Multiplier: 1Addend: 200- rid: 6090675012705714178type: {class: Range, ns: TagFighter.Effects.ResourceTypeAccessors, asm: Assembly-CSharp}- rid: 6090675012705714179type: {class: Pawn, ns: TagFighter.Effects.ResourceLocationAccessors.Set, asm: Assembly-CSharp}data:Property:rid: 6090675012705714180- rid: 6090675012705714180type: {class: Current, ns: TagFighter.Effects.ResourceLocationAccessors.PawnProperties,asm: Assembly-CSharp}- rid: 6090675012705714181type: {class: PeriodicWeave, ns: TagFighter.Effects, asm: Assembly-CSharp}data:AreaOfEffect:rid: 6090675012705714182ApplyTrigger:rid: 6090675012705714187EndTrigger:rid: 6090675012705714186IsPermanent: 0- rid: 6090675012705714182type: {class: Single, ns: TagFighter.Effects.AoeShapes, asm: Assembly-CSharp}- rid: 6090675012705714184type: {class: AoeEffect, ns: TagFighter.Effects, asm: Assembly-CSharp}data:Shape:rid: 6090675012705714185- rid: 6090675012705714185type: {class: Single, ns: TagFighter.Effects.AoeShapes, asm: Assembly-CSharp}- rid: 6090675012705714186type: {class: OnUnequip, ns: TagFighter.Effects.Triggers, asm: Assembly-CSharp}data:WatchedWeapon: {fileID: 11400000}- rid: 6090675012705714187type: {class: OnEquip, ns: TagFighter.Effects.Triggers, asm: Assembly-CSharp}data:WatchedWeapon: {fileID: 11400000}
--- !u!114 &1095075979MonoBehaviour:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 1095075963}m_Enabled: 1m_EditorHideFlags: 0m_Script: {fileID: 11500000, guid: 3637ce6e45f295d47863202e7233aedf, type: 3}m_Name:m_EditorClassIdentifier:_current:_base:_value: 50_capacity:_base:_value: 1000
--- !u!114 &1460840159MonoBehaviour:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 1460840143}m_Enabled: 1m_EditorHideFlags: 0m_Script: {fileID: 11500000, guid: 3637ce6e45f295d47863202e7233aedf, type: 3}m_Name:m_EditorClassIdentifier:_current:_base:_value: 50_capacity:_base:_value: 1000
- component: {fileID: 2775200704764093959}- component: {fileID: 2775200704764093958}- component: {fileID: 2775200704764093957}- component: {fileID: 2775200704764094072}
- component: {fileID: 5381362345172573048}
--- !u!33 &2775200704764093959MeshFilter:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 2775200704764093955}m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}--- !u!23 &2775200704764093958MeshRenderer:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 2775200704764093955}m_Enabled: 1m_CastShadows: 1m_ReceiveShadows: 1m_DynamicOccludee: 1m_StaticShadowCaster: 0m_MotionVectors: 1m_LightProbeUsage: 1m_ReflectionProbeUsage: 1m_RayTracingMode: 2m_RayTraceProcedural: 0m_RenderingLayerMask: 1m_RendererPriority: 0m_Materials:- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}m_StaticBatchInfo:firstSubMesh: 0subMeshCount: 0m_StaticBatchRoot: {fileID: 0}m_ProbeAnchor: {fileID: 0}m_LightProbeVolumeOverride: {fileID: 0}m_ScaleInLightmap: 1m_ReceiveGI: 1m_PreserveUVs: 0m_IgnoreNormalsForChartDetection: 0m_ImportantGI: 0m_StitchLightmapSeams: 1m_SelectedEditorRenderState: 3m_MinimumChartSize: 4m_AutoUVMaxDistance: 0.5m_AutoUVMaxAngle: 89m_LightmapParameters: {fileID: 0}m_SortingLayerID: 0m_SortingLayer: 0m_SortingOrder: 0m_AdditionalVertexStreams: {fileID: 0}--- !u!136 &2775200704764093957CapsuleCollider:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 2775200704764093955}m_Material: {fileID: 0}m_IsTrigger: 0m_Enabled: 1m_Radius: 0.5m_Height: 2m_Direction: 1m_Center: {x: 0, y: 0, z: 0}--- !u!195 &2775200704764094072NavMeshAgent:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 2775200704764093955}m_Enabled: 1m_AgentTypeID: 0m_Radius: 0.5m_Speed: 10m_Acceleration: 1000avoidancePriority: 50m_AngularSpeed: 120m_StoppingDistance: 0.1m_AutoTraverseOffMeshLink: 1m_AutoBraking: 1m_AutoRepath: 1m_Height: 2m_BaseOffset: 1m_WalkableMask: 4294967295m_ObstacleAvoidanceType: 4
--- !u!33 &2775200704764093959MeshFilter:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 2775200704764093955}m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}--- !u!23 &2775200704764093958MeshRenderer:
--- !u!114 &5381362345172573048MonoBehaviour:
m_CastShadows: 1m_ReceiveShadows: 1m_DynamicOccludee: 1m_StaticShadowCaster: 0m_MotionVectors: 1m_LightProbeUsage: 1m_ReflectionProbeUsage: 1m_RayTracingMode: 2m_RayTraceProcedural: 0m_RenderingLayerMask: 1m_RendererPriority: 0m_Materials:- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}m_StaticBatchInfo:firstSubMesh: 0subMeshCount: 0m_StaticBatchRoot: {fileID: 0}m_ProbeAnchor: {fileID: 0}m_LightProbeVolumeOverride: {fileID: 0}m_ScaleInLightmap: 1m_ReceiveGI: 1m_PreserveUVs: 0m_IgnoreNormalsForChartDetection: 0m_ImportantGI: 0m_StitchLightmapSeams: 1m_SelectedEditorRenderState: 3m_MinimumChartSize: 4m_AutoUVMaxDistance: 0.5m_AutoUVMaxAngle: 89m_LightmapParameters: {fileID: 0}m_SortingLayerID: 0m_SortingLayer: 0m_SortingOrder: 0m_AdditionalVertexStreams: {fileID: 0}--- !u!136 &2775200704764093957CapsuleCollider:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 2775200704764093955}m_Material: {fileID: 0}m_IsTrigger: 0m_Enabled: 1m_Radius: 0.5m_Height: 2m_Direction: 1m_Center: {x: 0, y: 0, z: 0}--- !u!195 &2775200704764094072NavMeshAgent:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 2775200704764093955}m_Enabled: 1m_AgentTypeID: 0m_Radius: 0.5m_Speed: 10m_Acceleration: 1000avoidancePriority: 50m_AngularSpeed: 120m_StoppingDistance: 0.1m_AutoTraverseOffMeshLink: 1m_AutoBraking: 1m_AutoRepath: 1m_Height: 2m_BaseOffset: 1m_WalkableMask: 4294967295m_ObstacleAvoidanceType: 4
m_EditorHideFlags: 0m_Script: {fileID: 11500000, guid: 3637ce6e45f295d47863202e7233aedf, type: 3}m_Name:m_EditorClassIdentifier:_current:_base:_value: 200_capacity:_base:_value: 1000