diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 168f4635..df063779 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -218,7 +218,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!224 &101671527 RectTransform: m_ObjectHideFlags: 0 @@ -1445,6 +1445,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 53b82781cf2fb9a4aa3b0d3e0a71f056, type: 3} m_Name: m_EditorClassIdentifier: + undoButton: {fileID: 101671528} turnText: {fileID: 144807538} missedText: {fileID: 1222372628} Player1BackgroundOverlay: {fileID: 1242843364} @@ -1885,7 +1886,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 0.23529412} - m_RaycastTarget: 1 + m_RaycastTarget: 0 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: @@ -2376,7 +2377,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 0.23529412} - m_RaycastTarget: 1 + m_RaycastTarget: 0 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: @@ -2787,6 +2788,7 @@ MonoBehaviour: m_EditorClassIdentifier: resultText: {fileID: 1682630446} homeButton: {fileID: 799045267} + replayButton: {fileID: 988327835} --- !u!1 &2089575972 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Action/ActionService.cs b/Assets/Scripts/Action/ActionService.cs index 957c65c0..a3b546ec 100644 --- a/Assets/Scripts/Action/ActionService.cs +++ b/Assets/Scripts/Action/ActionService.cs @@ -1,27 +1,28 @@ using Command.Input; +using Command.Commands; using System.Collections.Generic; namespace Command.Actions { public class ActionService { - private Dictionary actions; + private Dictionary actions; public ActionService() => CreateActions(); private void CreateActions() { - actions = new Dictionary(); - actions.Add(ActionType.Attack, new AttackAction()); - actions.Add(ActionType.Heal, new HealAction()); - actions.Add(ActionType.AttackStance, new AttackStanceAction()); - actions.Add(ActionType.Cleanse, new CleanseAction()); - actions.Add(ActionType.Meditate, new MeditateAction()); - actions.Add(ActionType.BerserkAttack, new BerserkAttackAction()); - actions.Add(ActionType.ThirdEye, new ThirdEyeAction()); + actions = new Dictionary(); + actions.Add(CommandType.Attack, new AttackAction()); + actions.Add(CommandType.Heal, new HealAction()); + actions.Add(CommandType.AttackStance, new AttackStanceAction()); + actions.Add(CommandType.Cleanse, new CleanseAction()); + actions.Add(CommandType.Meditate, new MeditateAction()); + actions.Add(CommandType.BerserkAttack, new BerserkAttackAction()); + actions.Add(CommandType.ThirdEye, new ThirdEyeAction()); } - public IAction GetActionByType(ActionType type) + public IAction GetActionByType(CommandType type) { if (actions.ContainsKey(type)) return actions[type]; @@ -29,6 +30,6 @@ public IAction GetActionByType(ActionType type) throw new System.Exception($"No Action found for the type {type} in the dictionary"); } - public TargetType GetTargetTypeForAction(ActionType actionType) => actions[actionType].TargetType; + public TargetType GetTargetTypeForAction(CommandType actionType) => actions[actionType].TargetType; } } \ No newline at end of file diff --git a/Assets/Scripts/Action/Actions/AttackAction.cs b/Assets/Scripts/Action/Actions/AttackAction.cs index 75632f04..11ae16e6 100644 --- a/Assets/Scripts/Action/Actions/AttackAction.cs +++ b/Assets/Scripts/Action/Actions/AttackAction.cs @@ -1,3 +1,4 @@ +using Command.Commands; using Command.Input; using Command.Main; using Command.Player; @@ -9,28 +10,28 @@ public class AttackAction : IAction { private UnitController actorUnit; private UnitController targetUnit; + private bool isSuccessful; public TargetType TargetType => TargetType.Enemy; - public void PerformAction(UnitController actorUnit, UnitController targetUnit) + public void PerformAction(UnitController actorUnit, UnitController targetUnit, bool isSuccessful) { this.actorUnit = actorUnit; this.targetUnit = targetUnit; + this.isSuccessful = isSuccessful; - actorUnit.PlayBattleAnimation(ActionType.Attack, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); + actorUnit.PlayBattleAnimation(CommandType.Attack, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); } public void OnActionAnimationCompleted() { PlayAttackSound(); - if (IsSuccessful()) + if (isSuccessful) targetUnit.TakeDamage(actorUnit.CurrentPower); else GameService.Instance.UIService.ActionMissed(); } - public bool IsSuccessful() => true; - public Vector3 CalculateMovePosition(UnitController targetUnit) => targetUnit.GetEnemyPosition(); private void PlayAttackSound() diff --git a/Assets/Scripts/Action/Actions/AttackStanceAction.cs b/Assets/Scripts/Action/Actions/AttackStanceAction.cs index 9fc46d34..bc3f8aa8 100644 --- a/Assets/Scripts/Action/Actions/AttackStanceAction.cs +++ b/Assets/Scripts/Action/Actions/AttackStanceAction.cs @@ -1,6 +1,7 @@ using Command.Player; using Command.Input; using Command.Main; +using Command.Commands; using UnityEngine; namespace Command.Actions @@ -9,28 +10,28 @@ public class AttackStanceAction : IAction { private UnitController actorUnit; private UnitController targetUnit; + private bool isSuccessful; TargetType IAction.TargetType { get => TargetType.Self; } - public void PerformAction(UnitController actorUnit, UnitController targetUnit) + public void PerformAction(UnitController actorUnit, UnitController targetUnit, bool isSuccessful) { this.actorUnit = actorUnit; this.targetUnit = targetUnit; + this.isSuccessful = isSuccessful; - actorUnit.PlayBattleAnimation(ActionType.AttackStance, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); + actorUnit.PlayBattleAnimation(CommandType.AttackStance, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); } public void OnActionAnimationCompleted() { GameService.Instance.SoundService.PlaySoundEffects(Sound.SoundType.ATTACK_STANCE); - if (IsSuccessful()) + if (isSuccessful) targetUnit.CurrentPower += (int)(targetUnit.CurrentPower * 0.2f); else GameService.Instance.UIService.ActionMissed(); } - public bool IsSuccessful() => true; - public Vector3 CalculateMovePosition(UnitController targetUnit) => targetUnit.GetEnemyPosition(); } } \ No newline at end of file diff --git a/Assets/Scripts/Action/Actions/BerserkAttackAction.cs b/Assets/Scripts/Action/Actions/BerserkAttackAction.cs index 42ce5acd..5ed281e9 100644 --- a/Assets/Scripts/Action/Actions/BerserkAttackAction.cs +++ b/Assets/Scripts/Action/Actions/BerserkAttackAction.cs @@ -1,3 +1,4 @@ +using Command.Commands; using Command.Input; using Command.Main; using Command.Player; @@ -7,34 +8,35 @@ namespace Command.Actions { public class BerserkAttackAction : IAction { - private const float hitChance = 0.66f; private UnitController actorUnit; private UnitController targetUnit; + private bool isSuccessful; + public TargetType TargetType => TargetType.Enemy; - public void PerformAction(UnitController actorUnit, UnitController targetUnit) + public void PerformAction(UnitController actorUnit, UnitController targetUnit, bool isSuccessful) { this.actorUnit = actorUnit; this.targetUnit = targetUnit; + this.isSuccessful = isSuccessful; - actorUnit.PlayBattleAnimation(ActionType.BerserkAttack, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); + actorUnit.PlayBattleAnimation(CommandType.BerserkAttack, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); } public void OnActionAnimationCompleted() { GameService.Instance.SoundService.PlaySoundEffects(Sound.SoundType.BERSERK_ATTACK); - if (IsSuccessful()) + if (isSuccessful) targetUnit.TakeDamage(actorUnit.CurrentPower * 2); else { actorUnit.TakeDamage(actorUnit.CurrentPower * 2); + actorUnit.OnActionExecuted(); Debug.Log("actor unit must be hit now."); } } - public bool IsSuccessful() => Random.Range(0f, 1f) < hitChance; - public Vector3 CalculateMovePosition(UnitController targetUnit) => targetUnit.GetEnemyPosition(); } } \ No newline at end of file diff --git a/Assets/Scripts/Action/Actions/CleanseAction.cs b/Assets/Scripts/Action/Actions/CleanseAction.cs index 469071ea..34eea7d6 100644 --- a/Assets/Scripts/Action/Actions/CleanseAction.cs +++ b/Assets/Scripts/Action/Actions/CleanseAction.cs @@ -2,36 +2,37 @@ using Command.Player; using Command.Main; using UnityEngine; +using Command.Commands; namespace Command.Actions { public class CleanseAction : IAction { - private const float hitChance = 0.2f; private UnitController actorUnit; private UnitController targetUnit; + private bool isSuccessful; + public TargetType TargetType => TargetType.Enemy; - public void PerformAction(UnitController actorUnit, UnitController targetUnit) + public void PerformAction(UnitController actorUnit, UnitController targetUnit, bool isSuccessful) { this.actorUnit = actorUnit; this.targetUnit = targetUnit; + this.isSuccessful = isSuccessful; - actorUnit.PlayBattleAnimation(ActionType.Cleanse, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); + actorUnit.PlayBattleAnimation(CommandType.Cleanse, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); } public void OnActionAnimationCompleted() { GameService.Instance.SoundService.PlaySoundEffects(Sound.SoundType.CLEANSE); - if (IsSuccessful()) + if (isSuccessful) targetUnit.ResetStats(); else GameService.Instance.UIService.ActionMissed(); } - public bool IsSuccessful() => Random.Range(0f, 1f) < hitChance; - public Vector3 CalculateMovePosition(UnitController targetUnit) => targetUnit.GetEnemyPosition(); } } diff --git a/Assets/Scripts/Action/Actions/HealAction.cs b/Assets/Scripts/Action/Actions/HealAction.cs index d05b6d47..f98df74c 100644 --- a/Assets/Scripts/Action/Actions/HealAction.cs +++ b/Assets/Scripts/Action/Actions/HealAction.cs @@ -1,3 +1,4 @@ +using Command.Commands; using Command.Input; using Command.Main; using Command.Player; @@ -9,26 +10,26 @@ public class HealAction : IAction { private UnitController actorUnit; private UnitController targetUnit; + private bool isSuccessful; public TargetType TargetType => TargetType.Friendly; - public void PerformAction(UnitController actorUnit, UnitController targetUnit) + public void PerformAction(UnitController actorUnit, UnitController targetUnit, bool isSuccessful) { this.actorUnit = actorUnit; this.targetUnit = targetUnit; + this.isSuccessful = isSuccessful; - actorUnit.PlayBattleAnimation(ActionType.Heal, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); + actorUnit.PlayBattleAnimation(CommandType.Heal, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); } public void OnActionAnimationCompleted() { GameService.Instance.SoundService.PlaySoundEffects(Sound.SoundType.HEAL); - if (IsSuccessful()) + if (isSuccessful) targetUnit.RestoreHealth(actorUnit.CurrentPower); } - public bool IsSuccessful() => true; - public Vector3 CalculateMovePosition(UnitController targetUnit) => targetUnit.GetEnemyPosition(); } } \ No newline at end of file diff --git a/Assets/Scripts/Action/Actions/MeditateAction.cs b/Assets/Scripts/Action/Actions/MeditateAction.cs index 869e159b..26259374 100644 --- a/Assets/Scripts/Action/Actions/MeditateAction.cs +++ b/Assets/Scripts/Action/Actions/MeditateAction.cs @@ -1,3 +1,4 @@ +using Command.Commands; using Command.Input; using Command.Main; using Command.Player; @@ -9,21 +10,24 @@ public class MeditateAction : IAction { private UnitController actorUnit; private UnitController targetUnit; + private bool isSuccessful; + public TargetType TargetType => TargetType.Self; - public void PerformAction(UnitController actorUnit, UnitController targetUnit) + public void PerformAction(UnitController actorUnit, UnitController targetUnit, bool isSuccessful) { this.actorUnit = actorUnit; this.targetUnit = targetUnit; + this.isSuccessful = isSuccessful; - actorUnit.PlayBattleAnimation(ActionType.Meditate, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); + actorUnit.PlayBattleAnimation(CommandType.Meditate, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); } public void OnActionAnimationCompleted() { GameService.Instance.SoundService.PlaySoundEffects(Sound.SoundType.MEDITATE); - if (IsSuccessful()) + if (isSuccessful) { var healthToIncrease = (int)(targetUnit.CurrentMaxHealth * 0.2f); targetUnit.CurrentMaxHealth += healthToIncrease; @@ -33,8 +37,6 @@ public void OnActionAnimationCompleted() GameService.Instance.UIService.ActionMissed(); } - public bool IsSuccessful() => true; - public Vector3 CalculateMovePosition(UnitController targetUnit) => targetUnit.GetEnemyPosition(); } } \ No newline at end of file diff --git a/Assets/Scripts/Action/Actions/ThirdEyeAction.cs b/Assets/Scripts/Action/Actions/ThirdEyeAction.cs index 8a24ba01..7dbd9bfa 100644 --- a/Assets/Scripts/Action/Actions/ThirdEyeAction.cs +++ b/Assets/Scripts/Action/Actions/ThirdEyeAction.cs @@ -1,3 +1,4 @@ +using Command.Commands; using Command.Input; using Command.Main; using Command.Player; @@ -9,19 +10,22 @@ public class ThirdEyeAction : IAction { private UnitController actorUnit; private UnitController targetUnit; + private bool isSuccessful; + public TargetType TargetType => TargetType.Self; - public void PerformAction(UnitController actorUnit, UnitController targetUnit) + public void PerformAction(UnitController actorUnit, UnitController targetUnit, bool isSuccessful) { this.actorUnit = actorUnit; this.targetUnit = targetUnit; + this.isSuccessful = isSuccessful; - actorUnit.PlayBattleAnimation(ActionType.BerserkAttack, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); + actorUnit.PlayBattleAnimation(CommandType.BerserkAttack, CalculateMovePosition(targetUnit), OnActionAnimationCompleted); } public void OnActionAnimationCompleted() { - if (IsSuccessful()) + if (isSuccessful) { int healthToConvert = (int)(targetUnit.CurrentHealth * 0.25f); targetUnit.TakeDamage(healthToConvert); @@ -31,8 +35,6 @@ public void OnActionAnimationCompleted() GameService.Instance.UIService.ActionMissed(); } - public bool IsSuccessful() => true; - public Vector3 CalculateMovePosition(UnitController targetUnit) => targetUnit.GetEnemyPosition(); } } \ No newline at end of file diff --git a/Assets/Scripts/Action/IAction.cs b/Assets/Scripts/Action/IAction.cs index 610560d8..a73327e7 100644 --- a/Assets/Scripts/Action/IAction.cs +++ b/Assets/Scripts/Action/IAction.cs @@ -11,9 +11,7 @@ public interface IAction { public TargetType TargetType { get; } - public void PerformAction(UnitController actorUnit, UnitController targetUnit); - - public bool IsSuccessful(); + public void PerformAction(UnitController actorUnit, UnitController targetUnit, bool isSuccessful); public Vector3 CalculateMovePosition(UnitController targetUnit); } diff --git a/Assets/Scripts/Battle/BattleService.cs b/Assets/Scripts/Battle/BattleService.cs index 0709f35f..3a1ae879 100644 --- a/Assets/Scripts/Battle/BattleService.cs +++ b/Assets/Scripts/Battle/BattleService.cs @@ -16,8 +16,13 @@ public BattleService(List battleScriptableObjects) SubscribeToEvents(); } - private void SubscribeToEvents() => GameService.Instance.EventService.OnBattleSelected.AddListener(LoadBattle); + private void SubscribeToEvents() + { + GameService.Instance.EventService.OnBattleSelected.AddListener(LoadBattle); + GameService.Instance.EventService.OnReplayButtonClicked.AddListener(ReplayBattle); + } + private void ReplayBattle() => LoadBattle(currentBattleId); private void LoadBattle(int battleId) { currentBattleId = battleId; diff --git a/Assets/Scripts/Command.meta b/Assets/Scripts/Command.meta new file mode 100644 index 00000000..1e9e808d --- /dev/null +++ b/Assets/Scripts/Command.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 057c0ab2ac9ca0e4fa171bc5a7b7c2dd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/Abstract Commands.meta b/Assets/Scripts/Command/Abstract Commands.meta new file mode 100644 index 00000000..69cc3bee --- /dev/null +++ b/Assets/Scripts/Command/Abstract Commands.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6bd3bf9b13445164c8eae27ef19b4ca3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/Abstract Commands/ICommand.cs b/Assets/Scripts/Command/Abstract Commands/ICommand.cs new file mode 100644 index 00000000..bc817aa7 --- /dev/null +++ b/Assets/Scripts/Command/Abstract Commands/ICommand.cs @@ -0,0 +1,25 @@ +namespace Command.Commands +{ + public interface ICommand + { + public void Execute(); + + public void Undo(); + } + + public struct CommandData + { + public int ActorUnitID; + public int TargetUnitID; + public int ActorPlayerID; + public int TargetPlayerID; + + public CommandData(int ActorUnitID, int TargetUnitID,int ActorPlayerID, int TargetPlayerID) + { + this.ActorUnitID = ActorUnitID; + this.TargetUnitID = TargetUnitID; + this.ActorPlayerID = ActorPlayerID; + this.TargetPlayerID = TargetPlayerID; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Command/Abstract Commands/ICommand.cs.meta b/Assets/Scripts/Command/Abstract Commands/ICommand.cs.meta new file mode 100644 index 00000000..16fb8f1e --- /dev/null +++ b/Assets/Scripts/Command/Abstract Commands/ICommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1694b2a5c5fb77e4b8c12b63c23898ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/Abstract Commands/UnitCommand.cs b/Assets/Scripts/Command/Abstract Commands/UnitCommand.cs new file mode 100644 index 00000000..944d847b --- /dev/null +++ b/Assets/Scripts/Command/Abstract Commands/UnitCommand.cs @@ -0,0 +1,22 @@ +using Command.Player; + +namespace Command.Commands +{ + public abstract class UnitCommand : ICommand + { + public CommandData commandData; + + protected UnitController actorUnit; + protected UnitController targetUnit; + + public abstract void Execute(); + + public abstract void Undo(); + + public abstract bool WillHitTarget(); + + public void SetActorUnit(UnitController actorUnit) => this.actorUnit = actorUnit; + + public void SetTargetUnit(UnitController targetUnit) => this.targetUnit = targetUnit; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Command/Abstract Commands/UnitCommand.cs.meta b/Assets/Scripts/Command/Abstract Commands/UnitCommand.cs.meta new file mode 100644 index 00000000..c015f0d6 --- /dev/null +++ b/Assets/Scripts/Command/Abstract Commands/UnitCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90e5347a76c8bba418c5b957b9ccc682 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/CommandInvoker.cs b/Assets/Scripts/Command/CommandInvoker.cs new file mode 100644 index 00000000..4f8f19f9 --- /dev/null +++ b/Assets/Scripts/Command/CommandInvoker.cs @@ -0,0 +1,40 @@ +using Command.Main; +using System.Collections.Generic; + +namespace Command.Commands +{ + public class CommandInvoker + { + private Stack commandRegistry = new Stack(); + + public void ProcessCommand(ICommand commandToProcess) + { + ExecuteCommand(commandToProcess); + RegisterCommand(commandToProcess); + } + + public void ExecuteCommand(ICommand commandToExecute) => commandToExecute.Execute(); + + public void RegisterCommand(ICommand commandToRegister) => commandRegistry.Push(commandToRegister); + + public void Undo() + { + if (!RegistryEmpty() && CommandBelongsToActivePlayer()) + commandRegistry.Pop().Undo(); + } + + private bool RegistryEmpty() => commandRegistry.Count == 0; + + private bool CommandBelongsToActivePlayer() => (commandRegistry.Peek() as UnitCommand).commandData.ActorPlayerID == GameService.Instance.PlayerService.ActivePlayerID; + + public CommandInvoker() => SubscribeToEvents(); + + private void SubscribeToEvents() => GameService.Instance.EventService.OnReplayButtonClicked.AddListener(SetReplayStack); + + public void SetReplayStack() + { + GameService.Instance.ReplayService.SetCommandStack(commandRegistry); + commandRegistry.Clear(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Command/CommandInvoker.cs.meta b/Assets/Scripts/Command/CommandInvoker.cs.meta new file mode 100644 index 00000000..afeecb98 --- /dev/null +++ b/Assets/Scripts/Command/CommandInvoker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef2285a6c836f4345b10e73a227cde34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Action/ActionType.cs b/Assets/Scripts/Command/CommandType.cs similarity index 73% rename from Assets/Scripts/Action/ActionType.cs rename to Assets/Scripts/Command/CommandType.cs index f6c14302..0a1e430e 100644 --- a/Assets/Scripts/Action/ActionType.cs +++ b/Assets/Scripts/Command/CommandType.cs @@ -1,6 +1,6 @@ -namespace Command.Actions +namespace Command.Commands { - public enum ActionType + public enum CommandType { None, Attack, diff --git a/Assets/Scripts/Action/ActionType.cs.meta b/Assets/Scripts/Command/CommandType.cs.meta similarity index 100% rename from Assets/Scripts/Action/ActionType.cs.meta rename to Assets/Scripts/Command/CommandType.cs.meta diff --git a/Assets/Scripts/Command/ConcreteCommands.meta b/Assets/Scripts/Command/ConcreteCommands.meta new file mode 100644 index 00000000..23e370f1 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 55cc47bf89042a94291adf77ae1962bc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/ConcreteCommands/AttackCommand.cs b/Assets/Scripts/Command/ConcreteCommands/AttackCommand.cs new file mode 100644 index 00000000..ddb31c17 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/AttackCommand.cs @@ -0,0 +1,31 @@ +using Command.Main; + +namespace Command.Commands +{ + public class AttackCommand : UnitCommand + { + private bool willHitTarget; + + public AttackCommand(CommandData commandData) + { + this.commandData = commandData; + willHitTarget = WillHitTarget(); + } + + public override bool WillHitTarget() => true; + + public override void Execute() => GameService.Instance.ActionService.GetActionByType(CommandType.Attack).PerformAction(actorUnit, targetUnit, willHitTarget); + + public override void Undo() + { + if (willHitTarget) + { + if (!targetUnit.IsAlive()) + targetUnit.Revive(); + + targetUnit.RestoreHealth(actorUnit.CurrentPower); + actorUnit.Owner.ResetCurrentActiveUnit(); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Command/ConcreteCommands/AttackCommand.cs.meta b/Assets/Scripts/Command/ConcreteCommands/AttackCommand.cs.meta new file mode 100644 index 00000000..22275d85 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/AttackCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00ed892a7cb8738439eb141a0e0cddb0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/ConcreteCommands/AttackStanceCommand.cs b/Assets/Scripts/Command/ConcreteCommands/AttackStanceCommand.cs new file mode 100644 index 00000000..126399f1 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/AttackStanceCommand.cs @@ -0,0 +1,28 @@ +using Command.Main; + +namespace Command.Commands +{ + public class AttackStanceCommand : UnitCommand + { + private bool willHitTarget; + + public AttackStanceCommand(CommandData commandData) + { + this.commandData = commandData; + willHitTarget = WillHitTarget(); + } + + public override void Execute() => GameService.Instance.ActionService.GetActionByType(CommandType.AttackStance).PerformAction(actorUnit, targetUnit, willHitTarget); + + public override void Undo() + { + if (willHitTarget) + { + targetUnit.CurrentPower -= (int)(targetUnit.CurrentPower * 0.2f); + actorUnit.Owner.ResetCurrentActiveUnit(); + } + } + + public override bool WillHitTarget() => true; + } +} diff --git a/Assets/Scripts/Command/ConcreteCommands/AttackStanceCommand.cs.meta b/Assets/Scripts/Command/ConcreteCommands/AttackStanceCommand.cs.meta new file mode 100644 index 00000000..19e8d1aa --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/AttackStanceCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d3197fa1f4b55f4dbcaa1635ee3e7e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/ConcreteCommands/BerserkAttackCommand.cs b/Assets/Scripts/Command/ConcreteCommands/BerserkAttackCommand.cs new file mode 100644 index 00000000..ec99f1bd --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/BerserkAttackCommand.cs @@ -0,0 +1,40 @@ +using Command.Main; +using UnityEngine; + +namespace Command.Commands +{ + public class BerserkAttackCommand : UnitCommand + { + private bool willHitTarget; + private const float hitChance = 0.66f; + + public BerserkAttackCommand(CommandData commandData) + { + this.commandData = commandData; + willHitTarget = WillHitTarget(); + } + + public override void Execute() => GameService.Instance.ActionService.GetActionByType(CommandType.BerserkAttack).PerformAction(actorUnit, targetUnit, willHitTarget); + + public override void Undo() + { + if (willHitTarget) + { + if (!targetUnit.IsAlive()) + targetUnit.Revive(); + + targetUnit.RestoreHealth(actorUnit.CurrentPower * 2); + } + else + { + if (!actorUnit.IsAlive()) + actorUnit.Revive(); + + actorUnit.RestoreHealth(actorUnit.CurrentPower * 2); + } + actorUnit.Owner.ResetCurrentActiveUnit(); + } + + public override bool WillHitTarget() => Random.Range(0f, 1f) < hitChance; + } +} diff --git a/Assets/Scripts/Command/ConcreteCommands/BerserkAttackCommand.cs.meta b/Assets/Scripts/Command/ConcreteCommands/BerserkAttackCommand.cs.meta new file mode 100644 index 00000000..31dc3a0e --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/BerserkAttackCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f62618eba9ffa542a5f213d150803ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/ConcreteCommands/CleanseCommand.cs b/Assets/Scripts/Command/ConcreteCommands/CleanseCommand.cs new file mode 100644 index 00000000..6f00986b --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/CleanseCommand.cs @@ -0,0 +1,34 @@ +using Command.Main; +using UnityEngine; + +namespace Command.Commands +{ + public class CleanseCommand : UnitCommand + { + private bool willHitTarget; + private const float hitChance = 0.2f; + private int previousPower; + + public CleanseCommand(CommandData commandData) + { + this.commandData = commandData; + willHitTarget = WillHitTarget(); + } + + public override void Execute() + { + previousPower = targetUnit.CurrentPower; + GameService.Instance.ActionService.GetActionByType(CommandType.Cleanse).PerformAction(actorUnit, targetUnit, willHitTarget); + } + + public override void Undo() + { + if (willHitTarget) + targetUnit.CurrentPower = previousPower; + + actorUnit.Owner.ResetCurrentActiveUnit(); + } + + public override bool WillHitTarget() => Random.Range(0f, 1f) < hitChance; + } +} diff --git a/Assets/Scripts/Command/ConcreteCommands/CleanseCommand.cs.meta b/Assets/Scripts/Command/ConcreteCommands/CleanseCommand.cs.meta new file mode 100644 index 00000000..4f8620f0 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/CleanseCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 309efdff4d5eb594399f96309278aecc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/ConcreteCommands/HealCommand.cs b/Assets/Scripts/Command/ConcreteCommands/HealCommand.cs new file mode 100644 index 00000000..ef90ef33 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/HealCommand.cs @@ -0,0 +1,28 @@ +using Command.Main; + +namespace Command.Commands +{ + public class HealCommand : UnitCommand + { + private bool willHitTarget; + + public HealCommand(CommandData commandData) + { + this.commandData = commandData; + willHitTarget = WillHitTarget(); + } + + public override void Execute() => GameService.Instance.ActionService.GetActionByType(CommandType.Heal).PerformAction(actorUnit, targetUnit, willHitTarget); + + public override void Undo() + { + if (willHitTarget) + { + targetUnit.TakeDamage(actorUnit.CurrentPower); + actorUnit.Owner.ResetCurrentActiveUnit(); + } + } + + public override bool WillHitTarget() => true; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Command/ConcreteCommands/HealCommand.cs.meta b/Assets/Scripts/Command/ConcreteCommands/HealCommand.cs.meta new file mode 100644 index 00000000..f55e3d0f --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/HealCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c01465896d721740947c4d0328cfb17 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/ConcreteCommands/MeditateCommand.cs b/Assets/Scripts/Command/ConcreteCommands/MeditateCommand.cs new file mode 100644 index 00000000..d176f4a0 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/MeditateCommand.cs @@ -0,0 +1,35 @@ +using Command.Main; + +namespace Command.Commands +{ + public class MeditateCommand : UnitCommand + { + private bool willHitTarget; + private int previousMaxHealth; + + public MeditateCommand(CommandData commandData) + { + this.commandData = commandData; + willHitTarget = WillHitTarget(); + } + + public override void Execute() + { + previousMaxHealth = targetUnit.CurrentMaxHealth; + GameService.Instance.ActionService.GetActionByType(CommandType.Meditate).PerformAction(actorUnit, targetUnit, willHitTarget); + } + + public override void Undo() + { + if (willHitTarget) + { + var healthToReduce = targetUnit.CurrentMaxHealth - previousMaxHealth; + targetUnit.CurrentMaxHealth = previousMaxHealth; + targetUnit.TakeDamage(healthToReduce); + } + actorUnit.Owner.ResetCurrentActiveUnit(); + } + + public override bool WillHitTarget() => true; + } +} diff --git a/Assets/Scripts/Command/ConcreteCommands/MeditateCommand.cs.meta b/Assets/Scripts/Command/ConcreteCommands/MeditateCommand.cs.meta new file mode 100644 index 00000000..40eab923 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/MeditateCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7eb8278659a46384982ecbd6a0f52c81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Command/ConcreteCommands/ThirdEyeCommand.cs b/Assets/Scripts/Command/ConcreteCommands/ThirdEyeCommand.cs new file mode 100644 index 00000000..901ad28c --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/ThirdEyeCommand.cs @@ -0,0 +1,35 @@ +using Command.Main; + +namespace Command.Commands +{ + public class ThirdEyeCommand : UnitCommand + { + private bool willHitTarget; + private int previousHealth; + + public ThirdEyeCommand(CommandData commandData) + { + this.commandData = commandData; + willHitTarget = WillHitTarget(); + } + + public override void Execute() + { + previousHealth = targetUnit.CurrentHealth; + GameService.Instance.ActionService.GetActionByType(CommandType.ThirdEye).PerformAction(actorUnit, targetUnit, willHitTarget); + } + + public override void Undo() + { + if(!targetUnit.IsAlive()) + targetUnit.Revive(); + + int healthToRestore = (int)(previousHealth * 0.25f); + targetUnit.RestoreHealth(healthToRestore); + targetUnit.CurrentPower -= healthToRestore; + actorUnit.Owner.ResetCurrentActiveUnit(); + } + + public override bool WillHitTarget() => true; + } +} diff --git a/Assets/Scripts/Command/ConcreteCommands/ThirdEyeCommand.cs.meta b/Assets/Scripts/Command/ConcreteCommands/ThirdEyeCommand.cs.meta new file mode 100644 index 00000000..6fcf2e51 --- /dev/null +++ b/Assets/Scripts/Command/ConcreteCommands/ThirdEyeCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6981291794a59074f9e544d5aacecf35 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Events/EventService.cs b/Assets/Scripts/Events/EventService.cs index 59b664c2..19ee1135 100644 --- a/Assets/Scripts/Events/EventService.cs +++ b/Assets/Scripts/Events/EventService.cs @@ -1,4 +1,4 @@ -using Command.Actions; +using Command.Commands; /** This script demonstrates implementation of the Observer Pattern. * If you're interested in learning about Observer Pattern, @@ -11,12 +11,14 @@ namespace Command.Events public class EventService { public GameEventController OnBattleSelected { get; private set; } - public GameEventController OnActionSelected { get; private set; } + public GameEventController OnActionSelected { get; private set; } + public GameEventController OnReplayButtonClicked { get; internal set; } public EventService() { OnBattleSelected = new GameEventController(); - OnActionSelected = new GameEventController(); + OnActionSelected = new GameEventController(); + OnReplayButtonClicked = new GameEventController(); } } } \ No newline at end of file diff --git a/Assets/Scripts/Input/InputService.cs b/Assets/Scripts/Input/InputService.cs index de088222..eb89498a 100644 --- a/Assets/Scripts/Input/InputService.cs +++ b/Assets/Scripts/Input/InputService.cs @@ -1,6 +1,6 @@ using Command.Main; using Command.Player; -using Command.Actions; +using Command.Commands; namespace Command.Input { @@ -9,7 +9,7 @@ public class InputService private MouseInputHandler mouseInputHandler; private InputState currentState; - private ActionType selectedActionType; + private CommandType selectedCommandType; private TargetType targetType; public InputService() @@ -29,9 +29,9 @@ public void UpdateInputService() mouseInputHandler.HandleTargetSelection(targetType); } - public void OnActionSelected(ActionType selectedActionType) + public void OnActionSelected(CommandType selectedActionType) { - this.selectedActionType = selectedActionType; + this.selectedCommandType = selectedActionType; SetInputState(InputState.SELECTING_TARGET); TargetType targetType = SetTargetType(selectedActionType); ShowTargetSelectionUI(targetType); @@ -43,12 +43,47 @@ private void ShowTargetSelectionUI(TargetType selectedTargetType) GameService.Instance.UIService.ShowTargetOverlay(playerID, selectedTargetType); } - private TargetType SetTargetType(ActionType selectedActionType) => targetType = GameService.Instance.ActionService.GetTargetTypeForAction(selectedActionType); + private TargetType SetTargetType(CommandType selectedCommandType) => targetType = GameService.Instance.ActionService.GetTargetTypeForAction(selectedCommandType); public void OnTargetSelected(UnitController targetUnit) { SetInputState(InputState.EXECUTING_INPUT); - GameService.Instance.PlayerService.PerformAction(selectedActionType, targetUnit); + UnitCommand commandToProcess = CreateUnitCommand(targetUnit); + GameService.Instance.ProcessUnitCommand(commandToProcess); + } + + private UnitCommand CreateUnitCommand(UnitController targetUnit) + { + + CommandData commandData = CreateCommandData(targetUnit); + + switch (selectedCommandType) + { + case CommandType.Attack: + return new AttackCommand(commandData); + case CommandType.Heal: + return new HealCommand(commandData); + case CommandType.AttackStance: + return new AttackStanceCommand(commandData); + case CommandType.Cleanse: + return new CleanseCommand(commandData); + case CommandType.BerserkAttack: + return new BerserkAttackCommand(commandData); + case CommandType.Meditate: + return new MeditateCommand(commandData); + case CommandType.ThirdEye: + return new ThirdEyeCommand(commandData); + default: + throw new System.Exception($"No Command found of type: {selectedCommandType}"); + } + } + + private CommandData CreateCommandData(UnitController targetUnit) + { + return new CommandData(GameService.Instance.PlayerService.ActiveUnitID, + targetUnit.UnitID, + GameService.Instance.PlayerService.ActivePlayerID, + targetUnit.Owner.PlayerID); } } } \ No newline at end of file diff --git a/Assets/Scripts/Main/GameService.cs b/Assets/Scripts/Main/GameService.cs index e8a709be..2d498979 100644 --- a/Assets/Scripts/Main/GameService.cs +++ b/Assets/Scripts/Main/GameService.cs @@ -9,6 +9,9 @@ using Command.Battle; using Command.Actions; using UnityEngine.UI; +using Command.Commands; +using System; +using Command.Replay; namespace Command.Main { @@ -28,10 +31,18 @@ public class GameService : GenericMonoSingleton public InputService InputService { get; private set; } public BattleService BattleService { get; private set; } public PlayerService PlayerService { get; private set; } + public CommandInvoker CommandInvoker { get; private set; } + + public ReplayService ReplayService { get; private set; } [SerializeField] private UIService uiService; public UIService UIService => uiService; + internal void ProcessUnitCommand(System.Windows.Input.ICommand command) + { + throw new NotImplementedException(); + } + // Scriptable Objects: [SerializeField] private SoundScriptableObject soundScriptableObject; [SerializeField] private List battleScriptableObjects; @@ -49,8 +60,12 @@ private void Start() BattleService = new BattleService(battleScriptableObjects); PlayerService = new PlayerService(); uiService.Init(battleScriptableObjects.Count); + CommandInvoker = new CommandInvoker(); + ReplayService = new ReplayService(); } private void Update() => InputService.UpdateInputService(); + + public void ProcessUnitCommand(ICommand commandToProcess) => PlayerService.ProcessUnitCommand(commandToProcess as UnitCommand); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Assets/Scripts/Player/PlayerController.cs b/Assets/Scripts/Player/PlayerController.cs index 3860582a..faff057c 100644 --- a/Assets/Scripts/Player/PlayerController.cs +++ b/Assets/Scripts/Player/PlayerController.cs @@ -1,3 +1,4 @@ +using Command.Commands; using System.Collections.Generic; using UnityEngine; @@ -82,12 +83,24 @@ public void DestroyAllUnits() units.Clear(); } - // TODO: What is this?? - public void ResetCurrentActivePlayer() + public void ProcessUnitCommand(UnitCommand commandToProcess) => GetUnitByID(commandToProcess.commandData.ActorUnitID).ProcessUnitCommand(commandToProcess); + + public void ResetCurrentActiveUnit() { units[activeUnitIndex].ResetUnitIndicator(); + activeUnitIndex--; - units[activeUnitIndex].StartUnitTurn(); + + while(activeUnitIndex >= 0) + { + if (!units[activeUnitIndex].IsAlive()) + activeUnitIndex--; + else + { + units[activeUnitIndex].StartUnitTurn(); + break; + } + } } } } \ No newline at end of file diff --git a/Assets/Scripts/Player/PlayerService.cs b/Assets/Scripts/Player/PlayerService.cs index ec1f8bb4..935f687b 100644 --- a/Assets/Scripts/Player/PlayerService.cs +++ b/Assets/Scripts/Player/PlayerService.cs @@ -1,4 +1,4 @@ -using Command.Actions; +using Command.Commands; using Command.Main; namespace Command.Player @@ -65,8 +65,6 @@ private void SetActivePlayer() public void OnPlayerTurnCompleted() => StartNextTurn(); - public void PerformAction(ActionType actionSelected, UnitController targetUnit) => GameService.Instance.ActionService.GetActionByType(actionSelected).PerformAction(activePlayer.GetUnitByID(ActiveUnitID), targetUnit); - public void PlayerDied(PlayerController deadPlayer) { int winnerId; @@ -79,6 +77,20 @@ public void PlayerDied(PlayerController deadPlayer) GameService.Instance.UIService.ShowBattleEndUI(winnerId); } + public void ProcessUnitCommand(UnitCommand commandToProcess) + { + SetUnitReferences(commandToProcess); + GetPlayerById(commandToProcess.commandData.ActorPlayerID).ProcessUnitCommand(commandToProcess); + } + + private void SetUnitReferences(UnitCommand commandToProcess) + { + var actorUnit = GetPlayerById(commandToProcess.commandData.ActorPlayerID).GetUnitByID(commandToProcess.commandData.ActorUnitID); + var targetUnit = GetPlayerById(commandToProcess.commandData.TargetPlayerID).GetUnitByID(commandToProcess.commandData.TargetUnitID); + commandToProcess.SetActorUnit(actorUnit); + commandToProcess.SetTargetUnit(targetUnit); + } + private PlayerController GetPlayerById(int playerId) { if (player1.PlayerID == playerId) diff --git a/Assets/Scripts/Player/Unit/UnitController.cs b/Assets/Scripts/Player/Unit/UnitController.cs index 863dc14f..e8a4c7a9 100644 --- a/Assets/Scripts/Player/Unit/UnitController.cs +++ b/Assets/Scripts/Player/Unit/UnitController.cs @@ -1,6 +1,6 @@ using UnityEngine; using Command.Main; -using Command.Actions; +using Command.Commands; using System.Collections; using System; using Object = UnityEngine.Object; @@ -91,19 +91,19 @@ private void UnitDied() unitView.PlayAnimation(UnitAnimations.DEATH); } - public void PlayBattleAnimation(ActionType actionType, Vector3 battlePosition, Action callback) + public void PlayBattleAnimation(CommandType commandType, Vector3 battlePosition, Action callback) { GameService.Instance.UIService.ResetBattleBackgroundOverlay(); - MoveToBattlePosition(battlePosition, callback, true, actionType); + MoveToBattlePosition(battlePosition, callback, true, commandType); } - private void MoveToBattlePosition(Vector3 battlePosition, Action callback = null, bool shouldPlayActionAnimation = true, ActionType actionTypeToExecute = ActionType.None) + private void MoveToBattlePosition(Vector3 battlePosition, Action callback = null, bool shouldPlayActionAnimation = true, CommandType commandTypeToExecute = CommandType.None) { float moveTime = Vector3.Distance(unitView.transform.position, battlePosition) / unitScriptableObject.MovementSpeed; - unitView.StartCoroutine(MoveToPositionOverTime(battlePosition, moveTime, callback, shouldPlayActionAnimation, actionTypeToExecute)); + unitView.StartCoroutine(MoveToPositionOverTime(battlePosition, moveTime, callback, shouldPlayActionAnimation, commandTypeToExecute)); } - private IEnumerator MoveToPositionOverTime(Vector3 targetPosition, float time, Action callback, bool shouldPlayActionAnimation, ActionType actionTypeToExecute) + private IEnumerator MoveToPositionOverTime(Vector3 targetPosition, float time, Action callback, bool shouldPlayActionAnimation, CommandType actionTypeToExecute) { float elapsedTime = 0; Vector3 startingPosition = unitView.transform.position; @@ -124,9 +124,9 @@ private IEnumerator MoveToPositionOverTime(Vector3 targetPosition, float time, A callback.Invoke(); } - private void PlayActionAnimation(ActionType actionType) + private void PlayActionAnimation(CommandType actionType) { - if (actionType == ActionType.None) + if (actionType == CommandType.None) return; if (actionType == unitScriptableObject.executableCommands[0]) @@ -147,12 +147,18 @@ public void OnActionExecuted() public void ResetStats() => CurrentPower = unitScriptableObject.Power; - public void Revive() => SetAliveState(UnitAliveState.ALIVE); + public void Revive() + { + SetAliveState(UnitAliveState.ALIVE); + unitView.PlayAnimation(UnitAnimations.IDLE); + } public void Destroy() => UnityEngine.Object.Destroy(unitView.gameObject); public void ResetUnitIndicator() => unitView.SetUnitIndicator(false); + public void ProcessUnitCommand(UnitCommand commandToProcess) => GameService.Instance.CommandInvoker.ProcessCommand(commandToProcess); + public Vector3 GetEnemyPosition() { if (Owner.PlayerID == 1) diff --git a/Assets/Scripts/Player/Unit/UnitScriptableObject.cs b/Assets/Scripts/Player/Unit/UnitScriptableObject.cs index 3c0b6305..4bb5aeab 100644 --- a/Assets/Scripts/Player/Unit/UnitScriptableObject.cs +++ b/Assets/Scripts/Player/Unit/UnitScriptableObject.cs @@ -1,4 +1,4 @@ -using Command.Actions; +using Command.Commands; using System.Collections.Generic; using UnityEngine; @@ -12,7 +12,7 @@ public class UnitScriptableObject : ScriptableObject public UnitView UnitPrefab; public int MaxHealth; public int Power; - public List executableCommands; + public List executableCommands; public Vector3 EnemyBattlePositionOffset; public float MovementSpeed; } diff --git a/Assets/Scripts/Replay.meta b/Assets/Scripts/Replay.meta new file mode 100644 index 00000000..8af47348 --- /dev/null +++ b/Assets/Scripts/Replay.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: da275a0515bf930419f4c6a9bfcc0814 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Replay/ReplayService.cs b/Assets/Scripts/Replay/ReplayService.cs new file mode 100644 index 00000000..94189dd3 --- /dev/null +++ b/Assets/Scripts/Replay/ReplayService.cs @@ -0,0 +1,47 @@ +using Command.Main; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Windows.Input; +using UnityEngine; + +namespace Command.Replay +{ + // A class responsible for managing and controlling the replay of recorded commands. + public class ReplayService + { + // A stack to store recorded commands for replay. + private Stack replayCommandStack; + + // Property to get or set the current replay state. + public ReplayState ReplayState { get; private set; } + + // Constructor for the ReplayService. Initializes the replay state as "DEACTIVE." + public ReplayService() => SetReplayState(ReplayState.DEACTIVE); + + /// Set the replay state to the specified state. + public void SetReplayState(ReplayState stateToSet) => ReplayState = stateToSet; + + // Set the command stack for replay, providing a collection of commands to replay. + public void SetCommandStack(Stack commandsToSet) => replayCommandStack = new Stack(commandsToSet); + + // Execute the next recorded command in the stack if there are commands left to replay. + public void ExecuteNext() + { + if (replayCommandStack.Count > 0) + GameService.Instance.ProcessUnitCommand(replayCommandStack.Pop()); + } + + internal void SetCommandStack(Stack commandRegistry) + { + throw new NotImplementedException(); + } + } + + public enum ReplayState + { + ACTIVE, + DEACTIVE + } + +} \ No newline at end of file diff --git a/Assets/Scripts/Replay/ReplayService.cs.meta b/Assets/Scripts/Replay/ReplayService.cs.meta new file mode 100644 index 00000000..1568e43f --- /dev/null +++ b/Assets/Scripts/Replay/ReplayService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef5f22befab898b48a95b3426504cb61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/ActionSelectionUI/ActionButtonView.cs b/Assets/Scripts/UI/ActionSelectionUI/ActionButtonView.cs index f3016d06..69863dff 100644 --- a/Assets/Scripts/UI/ActionSelectionUI/ActionButtonView.cs +++ b/Assets/Scripts/UI/ActionSelectionUI/ActionButtonView.cs @@ -1,4 +1,4 @@ -using Command.Actions; +using Command.Commands; using TMPro; using UnityEngine; using UnityEngine.UI; @@ -9,7 +9,7 @@ public class ActionButtonView : MonoBehaviour { [SerializeField] private TextMeshProUGUI buttonText; private ActionSelectionUIController owner; - private ActionType actionType; + private CommandType actionType; private void Start() => GetComponent