NetworkMatchComponent.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0 OR MIT
  5. *
  6. */
  7. #pragma once
  8. #include <PlayerIdentityBus.h>
  9. #include <PlayerMatchLifecycleBus.h>
  10. #include <AzCore/EBus/ScheduledEvent.h>
  11. #include <AzCore/Math/Random.h>
  12. #include <Source/AutoGen/NetworkMatchComponent.AutoComponent.h>
  13. namespace MultiplayerSample
  14. {
  15. AZ_ENUM_CLASS(AllowedPlayerActions,
  16. None,
  17. RotationOnly,
  18. All
  19. );
  20. class INetworkMatch
  21. {
  22. public:
  23. AZ_RTTI(INetworkMatch, "{2EBAF2B1-76E9-4FC8-82DF-BD63FFC372BF}");
  24. INetworkMatch() = default;
  25. virtual ~INetworkMatch() = default;
  26. //! Returns which player actions (if any) the current game state allows.
  27. //! For example, in between rounds the player shouldn't be able to move around, but they can still rotate.
  28. //! @result The type of player actions that are allowed
  29. virtual AllowedPlayerActions PlayerActionsAllowed() const = 0;
  30. //! Returns the time in seconds until the current round ends.
  31. //! @result the time in seconds until the current round ends
  32. virtual float GetRoundTimeRemainingSec() const = 0;
  33. //! Returns the total time in seconds until a round ends.
  34. //! @result the total time in seconds until a round ends
  35. virtual float GetTotalRoundTimeSec() const = 0;
  36. //! Returns current the round number.
  37. //! @result current the round number
  38. virtual int32_t GetCurrentRoundNumber() const = 0;
  39. //! Returns the total number of rounds before a game ends.
  40. //! @result the total number of rounds before a game ends
  41. virtual int32_t GetTotalRoundCount() const = 0;
  42. //! Returns the current count of active players.
  43. //! @result the current count of active players
  44. virtual int32_t GetTotalPlayerCount() const = 0;
  45. //! Returns the time the first match begins
  46. //! Host Time is the time in milliseconds since the host server application has started.
  47. //! @result the time the first match begins
  48. virtual AZ::TimeMs GetMatchStartHostTime() const = 0;
  49. //! Adds an event handler to the round number AZ::Event
  50. //! @param handler the handler to add the the requested component event
  51. virtual void AddRoundNumberEventHandler(AZ::Event<uint16_t>::Handler& handler) = 0;
  52. //! Adds an event handler to the round time remaining AZ::Event
  53. //! @param handler the handler to add the the requested component event
  54. virtual void AddRoundTimeRemainingEventHandler(AZ::Event<RoundTimeSec>::Handler& handler) = 0;
  55. //! Adds an event handler to the round number rest remaining AZ::Event
  56. //! @param handler the handler to add the the requested component event
  57. virtual void AddRoundRestTimeRemainingEventHandler(AZ::Event<RoundTimeSec>::Handler& handler) = 0;
  58. //! Adds an event handler to capture the time the first match is set to begin.
  59. //! @param handler the handler to add the the requested component event
  60. virtual void AddFirstMatchStartHostTime(AZ::Event<AZ::TimeMs>::Handler& handler) = 0;
  61. };
  62. //! Script-bind for the INetworkMatch interface
  63. class NetworkMatchComponentRequests
  64. : public AZ::EBusTraits
  65. {
  66. public:
  67. static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
  68. static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
  69. };
  70. using NetworkMatchComponentRequestBus = AZ::EBus<INetworkMatch, NetworkMatchComponentRequests>;
  71. class NetworkMatchComponent
  72. : public NetworkMatchComponentBase
  73. , public NetworkMatchComponentRequestBus::Handler
  74. , public PlayerIdentityNotificationBus::Handler
  75. {
  76. public:
  77. AZ_MULTIPLAYER_COMPONENT(MultiplayerSample::NetworkMatchComponent, s_networkMatchComponentConcreteUuid, MultiplayerSample::NetworkMatchComponentBase);
  78. static void Reflect(AZ::ReflectContext* context);
  79. void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
  80. void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
  81. //! INetworkMatch interface
  82. //! @{
  83. AllowedPlayerActions PlayerActionsAllowed() const override;
  84. float GetRoundTimeRemainingSec() const override;
  85. float GetTotalRoundTimeSec() const override;
  86. int32_t GetCurrentRoundNumber() const override;
  87. int32_t GetTotalRoundCount() const override;
  88. int32_t GetTotalPlayerCount() const override;
  89. AZ::TimeMs GetMatchStartHostTime() const override;
  90. void AddRoundNumberEventHandler(AZ::Event<uint16_t>::Handler& handler) override;
  91. void AddRoundTimeRemainingEventHandler(AZ::Event<RoundTimeSec>::Handler& handler) override;
  92. void AddRoundRestTimeRemainingEventHandler(AZ::Event<RoundTimeSec>::Handler& handler) override;
  93. void AddFirstMatchStartHostTime(AZ::Event<AZ::TimeMs>::Handler& handler) override;
  94. //! @}
  95. #if AZ_TRAIT_SERVER
  96. //! PlayerIdentityNotificationBus
  97. //! @{
  98. void OnPlayerActivated(Multiplayer::NetEntityId playerEntity) override;
  99. void OnPlayerDeactivated(Multiplayer::NetEntityId playerEntity) override;
  100. //! }@
  101. #endif
  102. #if AZ_TRAIT_CLIENT
  103. void HandleRPC_EndMatch(
  104. AzNetworking::IConnection* invokingConnection, const MatchResultsSummary& results) override;
  105. #endif
  106. };
  107. class NetworkMatchComponentController
  108. : public NetworkMatchComponentControllerBase
  109. , public PlayerMatchLifecycleBus::Handler
  110. {
  111. public:
  112. // Possible pre/post names for automatically assigned player gamer name. Upon joining, a player will be given a name e.g. RoboRiot.
  113. const AZStd::vector<PlayerNameString> AutoAssignedPlayerNamePrefix{ "Robo", "Circuit", "Sparky", "Bolt", "Mech", "Metal", "Junkyard", "Wire", "Steel", "Cog", "Electric", "Circuit", "Rusty", "Byte", "Cyber", "Gizmo", "Sprocket", "Electro", "Plasma", "Automated", "Cybernetic", "Bionic" };
  114. const AZStd::vector<PlayerNameString> AutoAssignedPlayerNamePostfix{ "Riot", "Crusher", "Sparks", "Bot", "Marauder", "Warrior", "Samurai", "Commando", "Enigma", "Champion", "Renegade", "Brawler", "Crusader", "Gladiator", "Battler", "Heavy", "Miner", "Simulant", "Mecha", "Automata", "Cyborg", "Clunker", "Automat"};
  115. explicit NetworkMatchComponentController(NetworkMatchComponent& parent);
  116. void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
  117. void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
  118. //! PlayerMatchLifecycleBus overrides
  119. //! @{
  120. void OnPlayerArmorZero(Multiplayer::NetEntityId playerEntity) override;
  121. //! )@
  122. #if AZ_TRAIT_SERVER
  123. void StartMatch();
  124. void EndMatch();
  125. void StartRound();
  126. void EndRound();
  127. void HandleRPC_PlayerActivated(AzNetworking::IConnection* invokingConnection, const Multiplayer::NetEntityId& playerEntity) override;
  128. void HandleRPC_PlayerDeactivated(AzNetworking::IConnection* invokingConnection, const Multiplayer::NetEntityId& playerEntity) override;
  129. #endif
  130. private:
  131. #if AZ_TRAIT_SERVER
  132. void RoundTickOnceASecond();
  133. AZ::ScheduledEvent m_roundTickEvent{[this]()
  134. {
  135. RoundTickOnceASecond();
  136. }, AZ::Name("NetworkMatchComponentController")};
  137. void RestTickOnceASecond();
  138. AZ::ScheduledEvent m_restTickEvent{ [this]()
  139. {
  140. RestTickOnceASecond();
  141. }, AZ::Name("NetworkMatchRestClock") };
  142. #endif
  143. //! List of active players in the match.
  144. AZStd::vector<Multiplayer::NetEntityId> m_players;
  145. #if AZ_TRAIT_SERVER
  146. //! A temporary way to assign player identities, such as player names.
  147. void AssignPlayerIdentity(Multiplayer::NetEntityId playerEntity);
  148. PlayerNameString GeneratePlayerName();
  149. int m_nextPlayerId = 1;
  150. int m_playerNameRandomStartingIndexPrefix = 0;
  151. int m_playerNameRandomStartingIndexPostfix = 0;
  152. void RespawnPlayer(Multiplayer::NetEntityId playerEntity, PlayerResetOptions resets);
  153. #endif
  154. void FindWinner(MatchResultsSummary& results, const AZStd::vector<PlayerState>& potentialWinners);
  155. };
  156. }
  157. namespace AZ
  158. {
  159. AZ_TYPE_INFO_SPECIALIZE(MultiplayerSample::AllowedPlayerActions, "{D8EB0533-D50C-4C04-B462-BA0BD1607FA8}");
  160. } // namespace AZ