diff --git a/Assets/QuantumUser/Simulation/Battle/Qtn/Player/BattlePlayerInput.qtn b/Assets/QuantumUser/Simulation/Battle/Qtn/Player/BattlePlayerInput.qtn index 2eb70bf17..dbe0da8e9 100644 --- a/Assets/QuantumUser/Simulation/Battle/Qtn/Player/BattlePlayerInput.qtn +++ b/Assets/QuantumUser/Simulation/Battle/Qtn/Player/BattlePlayerInput.qtn @@ -4,14 +4,10 @@ input int DebugNumber; BattleMovementInputType MovementInput; bool MovementDirectionIsNormalized; - BattleGridPosition MovementPositionTarget; - FPVector2 MovementPositionMove; - FPVector2 MovementDirection; + BattleGridPosition MovementGridPosition; + FPVector2 MovementVector; bool RotationInput; FP RotationValue; - bool AbilityActivate; - int PlayerCharacterNumber; - bool GiveUpInput; BattleSpecialInput Special; } diff --git a/Assets/QuantumUser/Simulation/Battle/Scripts/BattleDebugUtils.cs b/Assets/QuantumUser/Simulation/Battle/Scripts/BattleDebugUtils.cs index b08b042e2..a2282b4ee 100644 --- a/Assets/QuantumUser/Simulation/Battle/Scripts/BattleDebugUtils.cs +++ b/Assets/QuantumUser/Simulation/Battle/Scripts/BattleDebugUtils.cs @@ -67,24 +67,6 @@ public static InputDebugInfo GenerateDebugInfo(Input* input) inputDebugSummary += "Rotate"; inputNotEmpty = true; } - if (input->AbilityActivate != false) - { - if (inputDebugSummary != "") inputDebugSummary += ", "; - inputDebugSummary += "Ability Activate"; - inputNotEmpty = true; - } - if (input->PlayerCharacterNumber > -1) - { - if (inputDebugSummary != "") inputDebugSummary += ", "; - inputDebugSummary += "Character Swap"; - inputNotEmpty = true; - } - if (input->GiveUpInput != false) - { - if (inputDebugSummary != "") inputDebugSummary += ", "; - inputDebugSummary += "Give Up"; - inputNotEmpty = true; - } if (inputNotEmpty) { @@ -95,24 +77,16 @@ public static InputDebugInfo GenerateDebugInfo(Input* input) " MovementInput: {0},\n" + " MovementDirectionIsNormalized: {1},\n" + " MovementPositionTarget: {2},\n" + - " MovementPositionMove: {3},\n" + - " MovementDirection: {4},\n" + - " RotationInput: {5},\n" + - " RotationValue: {6},\n" + - " AbilityActivate: {7},\n" + - " PlayerCharacterNumber: {8},\n" + - " GiveUpInput: {9}\n" + + " MovementVector: {3},\n" + + " RotationInput: {4},\n" + + " RotationValue: {5},\n" + "}}", input->MovementInput, input->MovementDirectionIsNormalized, - input->MovementPositionTarget.ConvertToString(), - input->MovementPositionMove, - input->MovementDirection, + input->MovementGridPosition.ConvertToString(), + input->MovementVector, input->RotationInput, - input->RotationValue, - input->AbilityActivate, - input->PlayerCharacterNumber, - input->GiveUpInput + input->RotationValue ) ); } diff --git a/Assets/QuantumUser/Simulation/Battle/Scripts/Game/BattleCommands.cs b/Assets/QuantumUser/Simulation/Battle/Scripts/Game/BattleCommands.cs new file mode 100644 index 000000000..e15667b6b --- /dev/null +++ b/Assets/QuantumUser/Simulation/Battle/Scripts/Game/BattleCommands.cs @@ -0,0 +1,119 @@ +/// @file BattleCommands.cs +/// +/// Contains @cref{Battle.QSimulation.Game,BattleCommand} class and all battle commands +/// +/// See [{Custom Quantum Commands}](#page-concepts-commands) for more info. +/// + +// System usings +using System.Runtime.CompilerServices; + +// Quantum usings +using Quantum; +using Photon.Deterministic; + +namespace Battle.QSimulation.Game +{ + /// + /// Abstract base class for all deterministic battle commands.
+ /// All new commands must be added to the enum. + ///
+ /// + /// See [{BattleCommand (base class)}](#page-concepts-commands-battle-qcommand) for more info. + public abstract class BattleCommand : DeterministicCommand + { + /// + /// Type of the command. None if no command. + /// + public enum Type + { + /// No command + None, + /// + GiveUp, + /// + ActivateAbility, + /// + SwapCharacter + } + + public override void Serialize(BitStream stream) { } + + public abstract Type BattleCommandType { get; } + + /// + /// Fetches a command for a and returns its . The out parameter contains the command itself. + /// + /// + /// The current simulation frame. + /// Reference to the player whose command is fetched. + /// Contains the command, or null if there isn't one. (out param) + /// + /// + /// The of the command, or if no command was found. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Type GetCommand(Frame f, PlayerRef playerRef, out BattleCommand commandData) + { + commandData = (BattleCommand)f.GetPlayerCommand(playerRef); + if (commandData == null) return Type.None; + return commandData.BattleCommandType; + } + } + + /// + /// A deterministic command that triggers the ability activation for a specific player. + /// + /// + /// See [{Custom Quantum Commands}](#page-concepts-commands) for more info. + public class BattleCharacterAbilityQCommand : BattleCommand + { + /// + /// Gets the command Type associated with this command.
+ /// Always returns Type.ActivateAbility. + ///
+ public override Type BattleCommandType => Type.ActivateAbility; + } + + /// + /// A deterministic command that triggers the character swapping logic for a specific player. + /// + /// + /// See [{Custom Quantum Commands}](#page-concepts-commands) for more info. + public class BattleCharacterSwapQCommand : BattleCommand + { + /// + /// Gets the command Type associated with this command.
+ /// Always returns Type.SwapCharacter. + ///
+ public override Type BattleCommandType => Type.SwapCharacter; + + /// + /// The number of the character the player is attempting to swap to. + /// + public int CharacterNumber; + + /// + /// Serializes the character number into the bitstream for network transmission. + /// + /// The bitstream to write to + public override void Serialize(BitStream stream) + { + stream.Serialize(ref CharacterNumber); + } + } + + /// + /// A deterministic command that triggers the give up logic for a specific player. + /// + /// + /// See [{Custom Quantum Commands}](#page-concepts-commands) for more info. + public class BattleGiveUpQCommand : BattleCommand + { + /// + /// Gets the command Type associated with this command.
+ /// Always returns Type.GiveUp. + ///
+ public override Type BattleCommandType => Type.GiveUp; + } +} diff --git a/Assets/QuantumUser/Simulation/Battle/Scripts/Game/BattleCommands.cs.meta b/Assets/QuantumUser/Simulation/Battle/Scripts/Game/BattleCommands.cs.meta new file mode 100644 index 000000000..9cb8edac0 --- /dev/null +++ b/Assets/QuantumUser/Simulation/Battle/Scripts/Game/BattleCommands.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e2a770b1a1492384dba77cd0746538a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerBotController.cs b/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerBotController.cs index 76038fda9..067934558 100644 --- a/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerBotController.cs +++ b/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerBotController.cs @@ -167,14 +167,10 @@ public static void GetBotInput(Frame f, bool isInPlay, BattlePlayerDataQComponen IsValid = true, MovementInput = movementInput, MovementDirectionIsNormalized = false, - MovementPositionTarget = predictedGridPosition, - MovementPositionMove = FPVector2.Zero, - MovementDirection = FPVector2.Zero, + MovementGridPosition = predictedGridPosition, + MovementVector = FPVector2.Zero, RotationInput = false, - RotationValue = FP._0, - PlayerCharacterNumber = -1, - GiveUpInput = false, - AbilityActivate = false + RotationValue = FP._0 }; } } diff --git a/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerMovementController.cs b/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerMovementController.cs index bc3454885..c86a68064 100644 --- a/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerMovementController.cs +++ b/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerMovementController.cs @@ -93,13 +93,13 @@ public static void UpdateMovement(Frame f, BattlePlayerDataQComponent* playerDat break; case BattleMovementInputType.PositionTarget: - ClampGridPosition(playerData, input->MovementPositionTarget, out playerData->TargetPosition); + ClampGridPosition(playerData, input->MovementGridPosition, out playerData->TargetPosition); playerData->HasTargetPosition = true; playerData->ViewPosition = playerData->TargetPosition; break; case BattleMovementInputType.PositionMove: - positionNext = FPVector2.MoveTowards(transform->Position, input->MovementPositionMove, playerData->Stats.Speed * f.DeltaTime); + positionNext = FPVector2.MoveTowards(transform->Position, input->MovementVector, playerData->Stats.Speed * f.DeltaTime); if (ClampAndSnapWorldPosition(playerData, positionNext, out FPVector2 clampedNext)) { positionNext = clampedNext; @@ -108,7 +108,7 @@ public static void UpdateMovement(Frame f, BattlePlayerDataQComponent* playerDat break; case BattleMovementInputType.Direction: - FPVector2 movementDirection = input->MovementDirection * (input->MovementDirectionIsNormalized ? playerData->Stats.Speed : FP._1); + FPVector2 movementDirection = input->MovementVector * (input->MovementDirectionIsNormalized ? playerData->Stats.Speed : FP._1); positionNext = transform->Position + FPVector2.ClampMagnitude(movementDirection, playerData->Stats.Speed) * f.DeltaTime; if (ClampAndSnapWorldPosition(playerData, positionNext, out FPVector2 clampedPosition)) { diff --git a/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerQSystem.cs b/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerQSystem.cs index 2ddac4284..612cc519b 100644 --- a/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerQSystem.cs +++ b/Assets/QuantumUser/Simulation/Battle/Scripts/Player/BattlePlayerQSystem.cs @@ -92,7 +92,9 @@ public static void OnProjectileHitPlayerCharacter(Frame f, BattleCollisionQSyste BattleEmotionState.Joy => SoundEffectTypeCommon.HitCharacterJoy, BattleEmotionState.Love => SoundEffectTypeCommon.HitCharacterLove, BattleEmotionState.Playful => SoundEffectTypeCommon.HitCharacterPlayful, - BattleEmotionState.Sadness => SoundEffectTypeCommon.HitCharacterSadness + BattleEmotionState.Sadness => SoundEffectTypeCommon.HitCharacterSadness, + + _ => throw new System.NotImplementedException() }; HandleSFXCommon(f, damagedPlayerData->Slot, soundEffectType, SoundEffectTarget.All); } @@ -194,7 +196,7 @@ public static void OnProjectileHitPlayerShield(Frame f, BattleCollisionQSystem.P /// /// Update method has been split into subprocesses.
/// see @cref{BattlePlayerQSystem,GetInput}
- /// see @cref{BattlePlayerQSystem,HandleGiveUpInput}
+ /// see @cref{BattlePlayerQSystem,HandleGiveUp}
/// see @cref{BattlePlayerQSystem,HandleCharacterSwapping}
/// see @cref{BattlePlayerQSystem,HandleOutOfPlay}
/// see @cref{BattlePlayerQSystem,HandleInPlay} @@ -224,10 +226,27 @@ public override void Update(Frame f) playerTransform = playerEntity.GetTransform(f); } + switch (BattleCommand.GetCommand(f, playerData->PlayerRef, out BattleCommand commandData)) + { + case BattleCommand.Type.None: + break; + + case BattleCommand.Type.GiveUp: + if (HandleGiveUp(f, playerHandle)) continue; + break; + + case BattleCommand.Type.ActivateAbility: + playerData->AbilityActivateBufferSec = FrameTimer.FromSeconds(f, FP._0_50); + break; + + case BattleCommand.Type.SwapCharacter: + BattleCharacterSwapQCommand swapCharacterData = (BattleCharacterSwapQCommand)commandData; + if (HandleCharacterSwapping(f, playerHandle, swapCharacterData.CharacterNumber)) continue; + break; + } + input = GetInput(f, playerHandle, playerData, &stackInputStorage); - if (HandleGiveUpInput(f, input, playerHandle)) continue; - if (HandleCharacterSwapping(f, input, playerHandle)) continue; if (HandleOutOfPlay(f, playerHandle)) continue; HandleInPlay(f, input, playerHandle, playerData, playerEntity, playerTransform); @@ -327,16 +346,13 @@ private enum SoundEffectTarget input = stackInputStorage; *stackInputStorage = new Input { + IsValid = true, MovementInput = BattleMovementInputType.None, MovementDirectionIsNormalized = false, - MovementPositionTarget = new BattleGridPosition { Col = 0, Row = 0 }, - MovementPositionMove = FPVector2.Zero, - MovementDirection = FPVector2.Zero, + MovementGridPosition = new BattleGridPosition { Col = 0, Row = 0 }, + MovementVector = FPVector2.Zero, RotationInput = false, RotationValue = FP._0, - PlayerCharacterNumber = -1, - GiveUpInput = false, - AbilityActivate = false }; } @@ -344,13 +360,15 @@ private enum SoundEffectTarget } /// - /// Private helper method for handling when a player gives up or abandons the match. + /// Private helper method for handling when a player wants to give up or has abandoned the match. /// /// /// Used by HandleGiveUpInput and HandlePlayerAbandoned. /// /// Current simulation frame. /// Handle of the player. + /// + /// True if all players on a team have given up. private static bool HandleGiveUpLogic(Frame f, BattlePlayerManager.PlayerHandle playerHandle) { BattlePlayerSlot slot = playerHandle.Slot; @@ -455,21 +473,18 @@ private static void HandleSFXCharacter(Frame f, BattlePlayerSlot slot, SoundEffe } /// - /// Private helper method for handling player input for giving up during the game play.
- /// Subprocess of the Update method. + /// Private helper method for handling player give up command.
+ /// Subprocess of Update method. ///
/// /// Updates give up state and calls HandleGiveUpLogic method which handles the rest of the logic. /// /// Current simulation frame. - /// Pointer to the player's input data. /// Handle of the player. /// - /// True if the give up input was processed. - private bool HandleGiveUpInput(Frame f, Input* input, BattlePlayerManager.PlayerHandle playerHandle) + /// True if all players on a team have given up. + private bool HandleGiveUp(Frame f, BattlePlayerManager.PlayerHandle playerHandle) { - if (!input->GiveUpInput) return false; - playerHandle.GiveUpState = !playerHandle.GiveUpState; s_debugLogger.LogFormat(f, "({0}) Give up input received, new state: {1}", playerHandle.Slot, playerHandle.GiveUpState); @@ -479,17 +494,16 @@ private bool HandleGiveUpInput(Frame f, Input* input, BattlePlayerManager.Player /// /// Private helper method for handling character swapping.
- /// Subprocess of the Update method. + /// Subprocess of Update method. ///
/// /// Current simulation frame. - /// Pointer to the player's input data. /// Handle of the player. /// - /// True if character swapped. - private bool HandleCharacterSwapping(Frame f, Input* input, BattlePlayerManager.PlayerHandle playerHandle) + /// True if character was swapped. + private bool HandleCharacterSwapping(Frame f, BattlePlayerManager.PlayerHandle playerHandle, int playerCharacterNumber) { - if (input->PlayerCharacterNumber < 0) return false; + if (playerCharacterNumber == playerHandle.SelectedCharacterNumber) return false; s_debugLogger.LogFormat(f, "({0}) Character swap input received", playerHandle.Slot); @@ -499,10 +513,9 @@ private bool HandleCharacterSwapping(Frame f, Input* input, BattlePlayerManager. return false; } - s_debugLogger.LogFormat(f, "({0}) Swapping to character number: {1}", playerHandle.Slot, input->PlayerCharacterNumber); - - BattlePlayerManager.SpawnPlayer(f, playerHandle.Slot, input->PlayerCharacterNumber); + s_debugLogger.LogFormat(f, "({0}) Swapping to character number: {1}", playerHandle.Slot, playerCharacterNumber); + BattlePlayerManager.SpawnPlayer(f, playerHandle.Slot, playerCharacterNumber); return true; } @@ -567,11 +580,6 @@ private void HandleInPlay(Frame f, Input* input, BattlePlayerManager.PlayerHandl bool updateMovement = true; - if (input->AbilityActivate) - { - playerData->AbilityActivateBufferSec = FrameTimer.FromSeconds(f, FP._0_50); - } - if (!playerData->AbilityCooldownSec.IsRunning(f) && playerData->AbilityActivateBufferSec.IsRunning(f)) { AbilityActivate(f, playerData, playerTransform); diff --git a/Assets/QuantumUser/Simulation/CommandSetup.User.cs b/Assets/QuantumUser/Simulation/CommandSetup.User.cs index cdd0c1f05..6088f323e 100644 --- a/Assets/QuantumUser/Simulation/CommandSetup.User.cs +++ b/Assets/QuantumUser/Simulation/CommandSetup.User.cs @@ -1,14 +1,39 @@ -namespace Quantum -{ - using System.Collections.Generic; - using Photon.Deterministic; +/// @file CommandSetup.User.cs +/// +/// Contains @cref{Quantum,DeterministicCommandSetup} class contains all project-specific commands. +/// + +// System usings +using System.Collections.Generic; + +// Quantum usings +using Photon.Deterministic; +// Battle QSimulation usings +using Battle.QSimulation.Game; + +namespace Quantum +{ + /// + /// Contains all project-specific commands. + /// public static partial class DeterministicCommandSetup { + /// + /// Registers the game's custom instances with + /// the %Quantum command system. Called once during the simulation initialization. + /// @warning + /// This method should only be called by Quantum. + /// + /// + /// The command factory collection to register commands into + /// The runtime game configuration for the current session + /// The simulation configuration for the current session static partial void AddCommandFactoriesUser(ICollection factories, RuntimeConfig gameConfig, SimulationConfig simulationConfig) { - // Add or remove commands to the collection. - // factories.Add(new NavMeshAgentTestSystem.RunTest()); + factories.Add(new BattleGiveUpQCommand()); + factories.Add(new BattleCharacterSwapQCommand()); + factories.Add(new BattleCharacterAbilityQCommand()); } } -} \ No newline at end of file +} diff --git a/Assets/QuantumUser/Simulation/Generated/Quantum.CodeGen.Core.cs b/Assets/QuantumUser/Simulation/Generated/Quantum.CodeGen.Core.cs index d7dca043a..64449761e 100644 --- a/Assets/QuantumUser/Simulation/Generated/Quantum.CodeGen.Core.cs +++ b/Assets/QuantumUser/Simulation/Generated/Quantum.CodeGen.Core.cs @@ -1144,33 +1144,25 @@ public static void Serialize(void* ptr, FrameSerializer serializer) { } [StructLayout(LayoutKind.Explicit)] public unsafe partial struct Input { - public const Int32 SIZE = 104; + public const Int32 SIZE = 80; public const Int32 ALIGNMENT = 8; - [FieldOffset(20)] + [FieldOffset(8)] public QBoolean IsValid; [FieldOffset(4)] public Int32 DebugNumber; [FieldOffset(0)] public BattleMovementInputType MovementInput; - [FieldOffset(24)] + [FieldOffset(12)] public QBoolean MovementDirectionIsNormalized; - [FieldOffset(32)] - public BattleGridPosition MovementPositionTarget; - [FieldOffset(64)] - public FPVector2 MovementPositionMove; - [FieldOffset(48)] - public FPVector2 MovementDirection; - [FieldOffset(28)] - public QBoolean RotationInput; + [FieldOffset(20)] + public BattleGridPosition MovementGridPosition; [FieldOffset(40)] - public FP RotationValue; - [FieldOffset(12)] - public QBoolean AbilityActivate; - [FieldOffset(8)] - public Int32 PlayerCharacterNumber; + public FPVector2 MovementVector; [FieldOffset(16)] - public QBoolean GiveUpInput; - [FieldOffset(80)] + public QBoolean RotationInput; + [FieldOffset(32)] + public FP RotationValue; + [FieldOffset(56)] public BattleSpecialInput Special; public override Int32 GetHashCode() { unchecked { @@ -1179,14 +1171,10 @@ public override Int32 GetHashCode() { hash = hash * 31 + DebugNumber.GetHashCode(); hash = hash * 31 + (Int32)MovementInput; hash = hash * 31 + MovementDirectionIsNormalized.GetHashCode(); - hash = hash * 31 + MovementPositionTarget.GetHashCode(); - hash = hash * 31 + MovementPositionMove.GetHashCode(); - hash = hash * 31 + MovementDirection.GetHashCode(); + hash = hash * 31 + MovementGridPosition.GetHashCode(); + hash = hash * 31 + MovementVector.GetHashCode(); hash = hash * 31 + RotationInput.GetHashCode(); hash = hash * 31 + RotationValue.GetHashCode(); - hash = hash * 31 + AbilityActivate.GetHashCode(); - hash = hash * 31 + PlayerCharacterNumber.GetHashCode(); - hash = hash * 31 + GiveUpInput.GetHashCode(); hash = hash * 31 + Special.GetHashCode(); return hash; } @@ -1208,22 +1196,18 @@ static partial void SerializeCodeGen(void* ptr, FrameSerializer serializer) { var p = (Input*)ptr; serializer.Stream.Serialize((Int32*)&p->MovementInput); serializer.Stream.Serialize(&p->DebugNumber); - serializer.Stream.Serialize(&p->PlayerCharacterNumber); - QBoolean.Serialize(&p->AbilityActivate, serializer); - QBoolean.Serialize(&p->GiveUpInput, serializer); QBoolean.Serialize(&p->IsValid, serializer); QBoolean.Serialize(&p->MovementDirectionIsNormalized, serializer); QBoolean.Serialize(&p->RotationInput, serializer); - Quantum.BattleGridPosition.Serialize(&p->MovementPositionTarget, serializer); + Quantum.BattleGridPosition.Serialize(&p->MovementGridPosition, serializer); FP.Serialize(&p->RotationValue, serializer); - FPVector2.Serialize(&p->MovementDirection, serializer); - FPVector2.Serialize(&p->MovementPositionMove, serializer); + FPVector2.Serialize(&p->MovementVector, serializer); Quantum.BattleSpecialInput.Serialize(&p->Special, serializer); } } [StructLayout(LayoutKind.Explicit)] public unsafe partial struct _globals_ { - public const Int32 SIZE = 1192; + public const Int32 SIZE = 1048; public const Int32 ALIGNMENT = 8; [FieldOffset(0)] public AssetRef Map; @@ -1247,12 +1231,12 @@ public unsafe partial struct _globals_ { public Int32 PlayerConnectedCount; [FieldOffset(560)] [FramePrinter.FixedArrayAttribute(typeof(Input), 6)] - private fixed Byte _input_[624]; - [FieldOffset(1184)] + private fixed Byte _input_[480]; + [FieldOffset(1040)] public BitSet6 PlayerLastConnectionState; public FixedArray input { get { - fixed (byte* p = _input_) { return new FixedArray(p, 104, 6); } + fixed (byte* p = _input_) { return new FixedArray(p, 80, 6); } } } public override Int32 GetHashCode() { @@ -2339,14 +2323,10 @@ partial void SetPlayerInputCodeGen(PlayerRef player, Input input) { i->DebugNumber = input.DebugNumber; i->MovementInput = input.MovementInput; i->MovementDirectionIsNormalized = input.MovementDirectionIsNormalized; - i->MovementPositionTarget = input.MovementPositionTarget; - i->MovementPositionMove = input.MovementPositionMove; - i->MovementDirection = input.MovementDirection; + i->MovementGridPosition = input.MovementGridPosition; + i->MovementVector = input.MovementVector; i->RotationInput = input.RotationInput; i->RotationValue = input.RotationValue; - i->AbilityActivate = input.AbilityActivate; - i->PlayerCharacterNumber = input.PlayerCharacterNumber; - i->GiveUpInput = input.GiveUpInput; i->Special = input.Special; } public Input* GetPlayerInput(PlayerRef player) { diff --git a/Assets/QuantumUser/Simulation/Generated/Quantum.CodeGen.Prototypes.cs b/Assets/QuantumUser/Simulation/Generated/Quantum.CodeGen.Prototypes.cs index f7a220c15..76358346b 100644 --- a/Assets/QuantumUser/Simulation/Generated/Quantum.CodeGen.Prototypes.cs +++ b/Assets/QuantumUser/Simulation/Generated/Quantum.CodeGen.Prototypes.cs @@ -776,14 +776,10 @@ public unsafe partial class InputPrototype : StructPrototype { public Int32 DebugNumber; public Quantum.QEnum32 MovementInput; public QBoolean MovementDirectionIsNormalized; - public Quantum.Prototypes.BattleGridPositionPrototype MovementPositionTarget; - public FPVector2 MovementPositionMove; - public FPVector2 MovementDirection; + public Quantum.Prototypes.BattleGridPositionPrototype MovementGridPosition; + public FPVector2 MovementVector; public QBoolean RotationInput; public FP RotationValue; - public QBoolean AbilityActivate; - public Int32 PlayerCharacterNumber; - public QBoolean GiveUpInput; public Quantum.Prototypes.BattleSpecialInputPrototype Special; partial void MaterializeUser(Frame frame, ref Quantum.Input result, in PrototypeMaterializationContext context); public void Materialize(Frame frame, ref Quantum.Input result, in PrototypeMaterializationContext context = default) { @@ -791,14 +787,10 @@ public void Materialize(Frame frame, ref Quantum.Input result, in PrototypeMater result.DebugNumber = this.DebugNumber; result.MovementInput = this.MovementInput; result.MovementDirectionIsNormalized = this.MovementDirectionIsNormalized; - this.MovementPositionTarget.Materialize(frame, ref result.MovementPositionTarget, in context); - result.MovementPositionMove = this.MovementPositionMove; - result.MovementDirection = this.MovementDirection; + this.MovementGridPosition.Materialize(frame, ref result.MovementGridPosition, in context); + result.MovementVector = this.MovementVector; result.RotationInput = this.RotationInput; result.RotationValue = this.RotationValue; - result.AbilityActivate = this.AbilityActivate; - result.PlayerCharacterNumber = this.PlayerCharacterNumber; - result.GiveUpInput = this.GiveUpInput; this.Special.Materialize(frame, ref result.Special, in context); MaterializeUser(frame, ref result, in context); } diff --git a/Assets/QuantumUser/View/Battle/Scripts/Game/BattleGameViewController.cs b/Assets/QuantumUser/View/Battle/Scripts/Game/BattleGameViewController.cs index 0a2307cf0..aedd4fce8 100644 --- a/Assets/QuantumUser/View/Battle/Scripts/Game/BattleGameViewController.cs +++ b/Assets/QuantumUser/View/Battle/Scripts/Game/BattleGameViewController.cs @@ -48,12 +48,11 @@ namespace Battle.View.Game /// Accesses all of the @ref UIHandlerReferences through the BattleUiController reference variable _uiController.
public class BattleGameViewController : QuantumCallbacks { - #region SerializeFields - /// @anchor BattleGameViewController-SerializeFields /// @name SerializeField variables /// SerializeFields@u-exlink are serialized variables exposed to the Unity editor. /// @{ + #region SerializeFields /// [SerializeField] Reference to BattleGridViewController which handles visual functionality for the %Battle arena's grid. /// @ref BattleGameViewController-SerializeFields @@ -85,14 +84,16 @@ public class BattleGameViewController : QuantumCallbacks [Tooltip("Reference to BattlePlayerInput which polls player input for %Quantum")] [SerializeField] private BattlePlayerInput _playerInput; - /// @} - #endregion SerializeFields + /// @} #region Public #region Public - Static Properties + /// The Quantum game + public static QuantumGame QGame { get; private set; } + /// The local player's BattlePlayerSlot. public static BattlePlayerSlot LocalPlayerSlot { get; private set; } @@ -123,19 +124,18 @@ public static void AssignProjectileReference(GameObject projectileReference) #region Public - Methods - #region Public - Methods - UiInput - /// @name UiInput methods /// UiInput methods are called when the player gives an %UI input, such as presses a button. These methods shouldn't be called any other way. /// @{ + #region Public - Methods - UiInput /// /// Public method that gets called when the local player pressed the give up button. /// public void UiInputOnLocalPlayerGiveUp() { - _debugLogger.Log("Give up button pressed"); - _playerInput.OnGiveUp(); + _playerInput.CommandSendGiveUp(); + _debugLogger.Log("Give up button pressed, command sent"); } /// @@ -147,14 +147,13 @@ public void UiInputOnLocalPlayerGiveUp() /// The character number which the local player selected. public void UiInputOnCharacterSelected(int characterNumber) { - _playerInput.OnCharacterSelected(characterNumber); - + _playerInput.CommandSendSwapCharacter(characterNumber); _debugLogger.LogFormat("Character number {0} button pressed!", characterNumber); } /// /// Public method that gets called when local player gives movement joystick input. - /// Calls OnJoystickMovement method + /// Calls QueueJoystickMovement method /// in _playerInput. /// /// @@ -162,13 +161,12 @@ public void UiInputOnCharacterSelected(int characterNumber) /// The movement direction Vector2. public void UiInputOnJoystickMovement(BattleJoystickState state, Vector2 value) { - _playerInput.OnJoystickMovement(state, value); - //Debug.Log($"Move joystick input {input}"); + _playerInput.QueueJoystickMovement(state, value); } /// /// Public method that gets called when local player gives rotation joystick input. - /// Calls OnJoystickRotation method + /// Calls QueueJoystickRotation method /// in _playerInput. /// /// @@ -176,8 +174,7 @@ public void UiInputOnJoystickMovement(BattleJoystickState state, Vector2 value) /// The rotation input as float. public void UiInputOnJoystickRotation(BattleJoystickState state, float value) { - _playerInput.OnJoystickRotation(state, value); - //Debug.Log($"Rotate joystick input {input}"); + _playerInput.QueueJoystickRotation(state, value); } /// @@ -191,7 +188,7 @@ public void UiInputOnExitGamePressed() /// /// Public method that gets called when local player gives special joystick input. - /// calls OnJoystickSpecial method + /// calls QueueJoystickSpecial method /// in _playerInput /// /// @@ -199,12 +196,11 @@ public void UiInputOnExitGamePressed() /// The special input as Vector2 public void UiInputOnJoystickSpecial(BattleJoystickState state, Vector2 value) { - _playerInput.OnJoystickSpecial(state, value); + _playerInput.QueueJoystickSpecial(state, value); } - /// @} - #endregion Public - Methods - UiInput + /// @} #endregion Public - Methods @@ -297,11 +293,10 @@ private void Awake() QuantumEvent.Subscribe(this, QEventDebugOnScreenMessage); } - #region QuantumEvent handlers - /// @name QuantumEvent handlers /// QuantumEvent handler methods are called by QuantumEvents. These methods shouldn't be called any other way. /// @{ + #region QuantumEvent handlers /// /// Private handler method for EventBattleViewWaitForPlayers QuantumEvent.
@@ -362,13 +357,14 @@ private void QEventOnViewAllPlayersConnected(EventBattleViewAllPlayersConnected /// The event data. private void QEventOnViewInit(EventBattleViewInit e) { - PlayerRef playerRef = default; + QGame = QuantumRunner.Default.Game; + PlayerRef localPlayerRef = default; // Getting LocalPlayerSlot and LocalPlayerTeam if (Utils.TryGetQuantumFrame(out Frame f)) { - playerRef = QuantumRunner.Default.Game.GetLocalPlayers()[0]; - LocalPlayerSlot = BattlePlayerManager.PlayerHandle.GetSlot(f, playerRef); + localPlayerRef = QGame.GetLocalPlayers()[0]; + LocalPlayerSlot = BattlePlayerManager.PlayerHandle.GetSlot(f, localPlayerRef); LocalPlayerTeam = BattlePlayerManager.PlayerHandle.GetTeamNumber(LocalPlayerSlot); } @@ -403,7 +399,7 @@ private void QEventOnViewInit(EventBattleViewInit e) BattleUiMovableElementData dataGiveUpButton = SettingsCarrier.Instance.GetBattleUiMovableElementData(BattleUiElementType.GiveUpButton); if (dataGiveUpButton != null) _uiController.GiveUpButtonHandler.MovableUiElement.SetData(dataGiveUpButton); - RuntimePlayer localPlayerData = f.GetPlayerData(playerRef); + RuntimePlayer localPlayerData = f.GetPlayerData(localPlayerRef); RuntimePlayer localTeammateData = f.GetPlayerData(BattlePlayerManager.PlayerHandle.GetTeammateHandle(f, LocalPlayerSlot).PlayerRef); // Setting local player info @@ -749,9 +745,10 @@ private void QEventDebugOnScreenMessage(EventBattleDebugOnScreenMessage e) _uiController.AnnouncementHandler.SetDebugtext(e.Message); } + #endregion /// @} -#endregion + /// /// Private Update@u-exlink method. Handles %UI updates based on the game's state and countdown. @@ -762,7 +759,7 @@ private void Update() if (Utils.TryGetQuantumFrame(out Frame frame)) { // Try to retrieve the singleton entity reference for the GameSession - if (frame.TryGetSingletonEntityRef(out var entity) == false) + if (frame.TryGetSingletonEntityRef(out EntityRef _) == false) { // If the GameSession singleton is not found, display an error message _debugLogger.Error(frame, "GameSession singleton not found"); diff --git a/Assets/QuantumUser/View/Battle/Scripts/Player/BattlePlayerInput.cs b/Assets/QuantumUser/View/Battle/Scripts/Player/BattlePlayerInput.cs index c756a6947..bc4ab4e01 100644 --- a/Assets/QuantumUser/View/Battle/Scripts/Player/BattlePlayerInput.cs +++ b/Assets/QuantumUser/View/Battle/Scripts/Player/BattlePlayerInput.cs @@ -42,60 +42,79 @@ namespace Battle.View.Player /// [{Player Overview}](#page-concepts-player-overview) public class BattlePlayerInput : MonoBehaviour { - /// @name Input methods - /// Input methods are called by BattleGameViewController when the player gives a %UI input. These methods shouldn't be called any other way. + /// @name Command input methods + /// Command input methods are called by @cref{BattleGameViewController} when the player gives a %UI input. These methods shouldn't be called any other way.
+ /// These inputs are sent to %Quantum as commands. /// @{ /// - /// Called when the player interacts with the movement joystick. + /// Called when the player presses give up button /// - /// - /// of the joystick. (unused) - /// The input value of the movement joystick as Vector2. - public void OnJoystickMovement(BattleJoystickState state, Vector2 value) + public void CommandSendGiveUp() { - _joystickMovementVector = value; + BattleGameViewController.QGame.SendCommand(new BattleGiveUpQCommand()); } /// - /// Called when the player interacts with the rotation joystick. + /// Called when the player presses character swap button /// /// - /// of the joystick. (unused) - /// The input value of the rotation joystick as float. - public void OnJoystickRotation(BattleJoystickState state, float value) + /// The character number of the character to swap to + public void CommandSendSwapCharacter(int characterNumber) { - _joystickRotationValue = value; + BattleGameViewController.QGame.SendCommand(new BattleCharacterSwapQCommand + { + CharacterNumber = characterNumber + }); } /// - /// Called when player interacts with the special joystick + /// Called when the player activates ability + /// + public void CommandSendActivateAbility() + { + BattleGameViewController.QGame.SendCommand(new BattleCharacterAbilityQCommand()); + } + + /// @} + + /// @name Queued input methods + /// Queued input methods are called by @cref{BattleGameViewController} when the player gives a %UI input. These methods shouldn't be called any other way.
+ /// These inputs are queued for next time that %Quantum polls input. + /// @{ + + /// + /// Called when the player interacts with the movement joystick. /// /// - /// of the joystick. - /// Value of the joystick input as Vector2. - public void OnJoystickSpecial(BattleJoystickState state, Vector2 value) + /// of the joystick. (unused) + /// Value of the joystick as Vector2. + public void QueueJoystickMovement(BattleJoystickState state, Vector2 value) { - _joystickSpecialState = state; - _joystickSpecialValue = value; + _queued.JoystickMovementVector = value; } /// - /// Called when the player presses one of the character selection buttons. + /// Called when the player interacts with the rotation joystick. /// /// - /// The number of the character that was selected. - public void OnCharacterSelected(int characterNumber) + /// of the joystick. (unused) + /// Value of the joystick as float. + public void QueueJoystickRotation(BattleJoystickState state, float value) { - _characterNumber = characterNumber; + _queued.JoystickRotationValue = value; } /// - /// Called when the player presses the give up button. + /// Called when player interacts with the special joystick /// - public void OnGiveUp() + /// + /// of the joystick. + /// Value of the joystick as Vector2. + public void QueueJoystickSpecial(BattleJoystickState state, Vector2 value) { - _onGiveUp = true; + _queued.JoystickSpecialState = state; + _queued.JoystickSpecialValue = value; } /// @} @@ -107,17 +126,15 @@ private struct MovementInputInfo { public BattleMovementInputType MovementInput; public bool MovementDirectionIsNormalized; - public BattleGridPosition MovementPositionTarget; - public FPVector2 MovementPositionMove; - public FPVector2 MovementDirection; + public BattleGridPosition MovementGridPosition; + public FPVector2 MovementVector; - public MovementInputInfo(BattleMovementInputType movementInput, bool movementDirectionIsNormalized, BattleGridPosition movementPositionTarget, FPVector2 movementPositionMove, FPVector2 movementDirection) + public MovementInputInfo(BattleMovementInputType movementInput, bool movementDirectionIsNormalized, BattleGridPosition movementPositionTarget, FPVector2 movementVector) { MovementInput = movementInput; MovementDirectionIsNormalized = movementDirectionIsNormalized; - MovementPositionTarget = movementPositionTarget; - MovementPositionMove = movementPositionMove; - MovementDirection = movementDirection; + MovementGridPosition = movementPositionTarget; + MovementVector = movementVector; } } @@ -136,10 +153,28 @@ public RotationInputInfo(bool rotationInput, FP rotationValue) } } + /// + /// Struct containing data related to queued inputs. + /// The vector received from the movement joystick.
+ public Vector2 JoystickMovementVector; + /// The float value received from the rotation joystick. + public float JoystickRotationValue; + /// The of the special joystick + public BattleJoystickState JoystickSpecialState; + /// The vector received from the special joystick. + public Vector2 JoystickSpecialValue; + } + /// @name State variables /// Variables related to current input states. /// @{ + /// Struct containing data related to queued inputs. + private Queued _queued; + /// Saved time from previous frame. private float _previousTime; @@ -155,30 +190,12 @@ public RotationInputInfo(bool rotationInput, FP rotationValue) /// Initial saved vector when movement input is first detected. private Vector3 _movementStartVector; - /// The vector received from the movement joystick. - private Vector2 _joystickMovementVector; - - /// The vector received from the special joystick. - private Vector2 _joystickSpecialValue; - - /// The float value received from the rotation joystick. - private float _joystickRotationValue; - /// Saved world position of the previous tap position used for double tap input validating. private Vector3 _lastTapPosition; - /// The of the special joystick - private BattleJoystickState _joystickSpecialState; - /// Saved time stamp of the previous tap. private float _lastTapTime; - /// Saved character number from character swapping input. - private int _characterNumber = -1; - - /// Give up button state - private bool _onGiveUp = false; - /// Bool to block screen input private bool _blockScreenInput = false; @@ -281,12 +298,9 @@ private void PollInput(CallbackPollInput callback) const float DoubleTapDistance = 1.0f; // set default input info - MovementInputInfo movementInputInfo = new(BattleMovementInputType.None, false, new BattleGridPosition() { Row = -1, Col = -1 }, FPVector2.Zero, FPVector2.Zero); + MovementInputInfo movementInputInfo = new(BattleMovementInputType.None, false, new BattleGridPosition() { Row = -1, Col = -1 }, FPVector2.Zero); RotationInputInfo rotationInputInfo = new(false, FP._0); - // check button input - if (_characterNumber > -1 || _onGiveUp) _blockScreenInput = true; - Vector2 clickPosition = Vector2.zero; Vector3 unityPosition = Vector3.zero; @@ -307,12 +321,19 @@ private void PollInput(CallbackPollInput callback) _blockScreenInput = false; } + bool abilityActivate = Time.time - _lastTapTime < DoubleTapInterval && mouseClick && Vector3.Distance(_lastTapPosition, unityPosition) < DoubleTapDistance; + + if (abilityActivate) + { + CommandSendActivateAbility(); + } + //{ create and set input BattleSpecialInput specialInput = new() { - JoystickValue = new FPVector2(FP.FromFloat_UNSAFE(_joystickSpecialValue.x), FP.FromFloat_UNSAFE(_joystickSpecialValue.y)), - JoystickState = _joystickSpecialState + JoystickValue = new FPVector2(FP.FromFloat_UNSAFE(_queued.JoystickSpecialValue.x), FP.FromFloat_UNSAFE(_queued.JoystickSpecialValue.y)), + JoystickState = _queued.JoystickSpecialState }; Input input = new() @@ -321,14 +342,10 @@ private void PollInput(CallbackPollInput callback) DebugNumber = _inputDebugNumber, MovementInput = movementInputInfo.MovementInput, MovementDirectionIsNormalized = movementInputInfo.MovementDirectionIsNormalized, - MovementPositionTarget = movementInputInfo.MovementPositionTarget, - MovementPositionMove = movementInputInfo.MovementPositionMove, - MovementDirection = movementInputInfo.MovementDirection, + MovementGridPosition = movementInputInfo.MovementGridPosition, + MovementVector = movementInputInfo.MovementVector, RotationInput = rotationInputInfo.RotationInput, RotationValue = rotationInputInfo.RotationValue, - AbilityActivate = Time.time - _lastTapTime < DoubleTapInterval && mouseClick && Vector3.Distance(_lastTapPosition, unityPosition) < DoubleTapDistance, - PlayerCharacterNumber = _characterNumber, - GiveUpInput = _onGiveUp, Special = specialInput }; @@ -365,10 +382,6 @@ private void PollInput(CallbackPollInput callback) _previousTime = Time.time; _inputDebugNumber++; - - // reset - _onGiveUp = false; - _characterNumber = -1; } /// @name Input reading methods @@ -385,7 +398,7 @@ private void PollInput(CallbackPollInput callback) /// Time since previous frame private MovementInputInfo GetMovementInput(bool mouseDown, bool mouseClick, Vector3 unityPosition, FP deltaTime) { - MovementInputInfo movementInputInfo = new(BattleMovementInputType.None, false, new BattleGridPosition() { Row = -1, Col = -1 }, FPVector2.Zero, FPVector2.Zero); + MovementInputInfo movementInputInfo = new(BattleMovementInputType.None, false, new BattleGridPosition() { Row = -1, Col = -1 }, FPVector2.Zero); switch (_movementInputType) { @@ -393,7 +406,7 @@ private MovementInputInfo GetMovementInput(bool mouseDown, bool mouseClick, Vect if (mouseClick) { movementInputInfo.MovementInput = BattleMovementInputType.PositionTarget; - movementInputInfo.MovementPositionTarget = new() + movementInputInfo.MovementGridPosition = new() { Row = BattleGridManager.WorldYPositionToGridRow(FP.FromFloat_UNSAFE(unityPosition.z)), Col = BattleGridManager.WorldXPositionToGridCol(FP.FromFloat_UNSAFE(unityPosition.x)) @@ -405,7 +418,7 @@ private MovementInputInfo GetMovementInput(bool mouseDown, bool mouseClick, Vect if (mouseDown) { movementInputInfo.MovementInput = BattleMovementInputType.PositionMove; - movementInputInfo.MovementPositionMove = new FPVector2 + movementInputInfo.MovementVector = new FPVector2 ( FP.FromFloat_UNSAFE(unityPosition.x), FP.FromFloat_UNSAFE(unityPosition.z) @@ -414,7 +427,7 @@ private MovementInputInfo GetMovementInput(bool mouseDown, bool mouseClick, Vect else { movementInputInfo.MovementInput = BattleMovementInputType.None; - movementInputInfo.MovementPositionMove = FPVector2.Zero; + movementInputInfo.MovementVector = FPVector2.Zero; } break; @@ -442,8 +455,8 @@ private MovementInputInfo GetMovementInput(bool mouseDown, bool mouseClick, Vect if (_swipePerformed) { Vector3 direction = unityPosition - _movementStartVector; - movementInputInfo.MovementDirection = new FPVector2(FP.FromFloat_UNSAFE(direction.x), FP.FromFloat_UNSAFE(direction.z)) / deltaTime; - movementInputInfo.MovementDirection *= FP.FromFloat_UNSAFE(_swipeSensitivity); + movementInputInfo.MovementVector = new FPVector2(FP.FromFloat_UNSAFE(direction.x), FP.FromFloat_UNSAFE(direction.z)) / deltaTime; + movementInputInfo.MovementVector *= FP.FromFloat_UNSAFE(_swipeSensitivity); } _movementStartVector = unityPosition; @@ -451,13 +464,13 @@ private MovementInputInfo GetMovementInput(bool mouseDown, bool mouseClick, Vect break; case MovementInputType.Joystick: - if (_joystickMovementVector != Vector2.zero) + if (_queued.JoystickMovementVector != Vector2.zero) { movementInputInfo.MovementInput = BattleMovementInputType.Direction; movementInputInfo.MovementDirectionIsNormalized = true; - movementInputInfo.MovementDirection = new FPVector2(FP.FromFloat_UNSAFE(_joystickMovementVector.x), FP.FromFloat_UNSAFE(_joystickMovementVector.y)); + movementInputInfo.MovementVector = new FPVector2(FP.FromFloat_UNSAFE(_queued.JoystickMovementVector.x), FP.FromFloat_UNSAFE(_queued.JoystickMovementVector.y)); - if (BattleGameViewController.LocalPlayerTeam == BattleTeamNumber.TeamBeta) movementInputInfo.MovementDirection *= -1; + if (BattleGameViewController.LocalPlayerTeam == BattleTeamNumber.TeamBeta) movementInputInfo.MovementVector *= -1; } break; } @@ -511,10 +524,10 @@ private RotationInputInfo GetRotationInput(bool mouseDown, bool twoFingers, Vect break; case RotationInputType.Joystick: - if (_joystickRotationValue != 0) + if (_queued.JoystickRotationValue != 0) { rotationInputInfo.RotationInput = true; - rotationInputInfo.RotationValue = FP.FromFloat_UNSAFE(_joystickRotationValue); + rotationInputInfo.RotationValue = FP.FromFloat_UNSAFE(_queued.JoystickRotationValue); rotationInputInfo.RotationValue *= -1; } break; diff --git a/Assets/QuantumUser/View/Battle/Scripts/UI/Handler/BattleUiGiveUpButtonHandler.cs b/Assets/QuantumUser/View/Battle/Scripts/UI/Handler/BattleUiGiveUpButtonHandler.cs index 40143fbf8..3930aeec2 100644 --- a/Assets/QuantumUser/View/Battle/Scripts/UI/Handler/BattleUiGiveUpButtonHandler.cs +++ b/Assets/QuantumUser/View/Battle/Scripts/UI/Handler/BattleUiGiveUpButtonHandler.cs @@ -167,7 +167,7 @@ private void UpdateInfoText() break; case ButtonInfoState.LocalGiveUp: - _giveUpButtonInfoText.text = "You want to give up"; + _giveUpButtonInfoText.text = "You want to give up\nClick to cancel"; break; case ButtonInfoState.TeammateGiveUp: diff --git a/Doc/Doxygen/Battle/additional-documentation/pages/1-concepts-.md b/Doc/Doxygen/Battle/additional-documentation/pages/1-concepts-.md index ac902dce4..2fb6437e7 100644 --- a/Doc/Doxygen/Battle/additional-documentation/pages/1-concepts-.md +++ b/Doc/Doxygen/Battle/additional-documentation/pages/1-concepts-.md @@ -4,8 +4,10 @@ @bigtext{@subpage page-concepts-entity-management} +@bigtext{@subpage page-concepts-commands} + @bigtext{@subpage page-concepts-player} @bigtext{@subpage page-concepts-view-registry} -@bigtext{@subpage page-concepts-battle-sprite-sheet} \ No newline at end of file +@bigtext{@subpage page-concepts-battle-sprite-sheet} diff --git a/Doc/Doxygen/Battle/additional-documentation/pages/1-concepts-commands.md b/Doc/Doxygen/Battle/additional-documentation/pages/1-concepts-commands.md new file mode 100644 index 000000000..793a5576e --- /dev/null +++ b/Doc/Doxygen/Battle/additional-documentation/pages/1-concepts-commands.md @@ -0,0 +1,40 @@ +# Custom %Quantum Commands {#page-concepts-commands} + +In %Battle we have a custom implementation of [Quantum Commands🡵](https://doc.photonengine.com/quantum/current/manual/commands) +All [{BattleQCommands}](#page-concepts-commands-battle-qcommand) extend the [{BattleCommand}](#page-concepts-commands-battle-command-base) base class. +@ref BattleCommands.cs contains all %Quantum commands in %Battle. + +
+ +## BattleCommand (base class) {#page-concepts-commands-battle-command-base} + +@cref{Battle.QSimulation.Game,BattleCommand} contains @cref{Battle.QSimulation.Game.BattleCommand,Type} enum which contains all %Battle commands. +[{BattleQCommands}](#page-concepts-commands-battle-qcommand) can be **Fetched** using @ref Battle.QSimulation.Game.BattleCommand.GetCommand "GetCommand" for handling the **command**. + +
+ +## BattleQCommand {#page-concepts-commands-battle-qcommand} + +To make a new command, add a new class in @ref BattleCommands.cs file, which: +- Inherits from @cref{Battle.QSimulation.Game,BattleCommand} class +- Should be named **%Battle(commandname)QCommand** +- Has a a public override Type @ref %BattleCommandType => Type.(commandname) property +- Can have a **public override void Serialize(Bitstream stream)** method which is required if the command carries data + +The command does not necessarily have to do anything itself, since it can be done in the part of the code where receiving the command is polled. + +All new commands must be added to @ref CommandSetup.User.cs, and @ref Battle.QSimulation.Game.BattleCommand.Type "Type" enum in @ref Battle.QSimulation.Game.BattleCommand "BattleCommand" class at the top of the @ref BattleCommands.cs file. + +**C# code example** +```cs +public class BattleExampleQCommand : BattleCommand +{ + public override Type BattleCommandType => Type.Example; + + public override void Serialize(BitStream stream) + { + //... + } + // ... +} +``` \ No newline at end of file