You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
319 lines
11 KiB
C#
319 lines
11 KiB
C#
3 weeks ago
|
using Unity.BossRoom.ConnectionManagement;
|
||
|
using Unity.BossRoom.Gameplay.GameplayObjects;
|
||
|
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
|
||
|
using Unity.BossRoom.Gameplay.Messages;
|
||
|
using Unity.BossRoom.Infrastructure;
|
||
|
using Unity.Multiplayer.Samples.BossRoom;
|
||
|
using Unity.Multiplayer.Samples.Utilities;
|
||
|
using Unity.Netcode;
|
||
|
using UnityEngine;
|
||
|
using VContainer;
|
||
|
|
||
|
namespace Unity.BossRoom.DebugCheats
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Handles debug cheat events, applies them on the server and logs them on all clients. This class is only
|
||
|
/// available in the editor or for development builds
|
||
|
/// </summary>
|
||
|
public class DebugCheatsManager : NetworkBehaviour
|
||
|
{
|
||
|
[SerializeField]
|
||
|
GameObject m_DebugCheatsPanel;
|
||
|
|
||
|
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
||
|
[SerializeField]
|
||
|
[Tooltip("Enemy to spawn. Make sure this is included in the NetworkManager's list of prefabs!")]
|
||
|
NetworkObject m_EnemyPrefab;
|
||
|
|
||
|
[SerializeField]
|
||
|
[Tooltip("Boss to spawn. Make sure this is included in the NetworkManager's list of prefabs!")]
|
||
|
NetworkObject m_BossPrefab;
|
||
|
|
||
|
[SerializeField]
|
||
|
KeyCode m_OpenWindowKeyCode = KeyCode.Slash;
|
||
|
|
||
|
SwitchedDoor m_SwitchedDoor;
|
||
|
|
||
|
SwitchedDoor SwitchedDoor
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
if (m_SwitchedDoor == null)
|
||
|
{
|
||
|
m_SwitchedDoor = FindObjectOfType<SwitchedDoor>();
|
||
|
}
|
||
|
return m_SwitchedDoor;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const int k_NbTouchesToOpenWindow = 4;
|
||
|
|
||
|
bool m_DestroyPortalsOnNextToggle = true;
|
||
|
|
||
|
[Inject]
|
||
|
IPublisher<CheatUsedMessage> m_CheatUsedMessagePublisher;
|
||
|
|
||
|
void Update()
|
||
|
{
|
||
|
if (Input.touchCount == k_NbTouchesToOpenWindow && AnyTouchDown() ||
|
||
|
m_OpenWindowKeyCode != KeyCode.None && Input.GetKeyDown(m_OpenWindowKeyCode))
|
||
|
{
|
||
|
m_DebugCheatsPanel.SetActive(!m_DebugCheatsPanel.activeSelf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static bool AnyTouchDown()
|
||
|
{
|
||
|
foreach (var touch in Input.touches)
|
||
|
{
|
||
|
if (touch.phase == TouchPhase.Began)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public void SpawnEnemy()
|
||
|
{
|
||
|
ServerSpawnEnemyRpc();
|
||
|
}
|
||
|
|
||
|
public void SpawnBoss()
|
||
|
{
|
||
|
ServerSpawnBossRpc();
|
||
|
}
|
||
|
|
||
|
public void KillTarget()
|
||
|
{
|
||
|
ServerKillTargetRpc();
|
||
|
}
|
||
|
|
||
|
public void KillAllEnemies()
|
||
|
{
|
||
|
ServerKillAllEnemiesRpc();
|
||
|
}
|
||
|
|
||
|
public void ToggleGodMode()
|
||
|
{
|
||
|
ServerToggleGodModeRpc();
|
||
|
}
|
||
|
|
||
|
public void HealPlayer()
|
||
|
{
|
||
|
ServerHealPlayerRpc();
|
||
|
}
|
||
|
|
||
|
public void ToggleSuperSpeed()
|
||
|
{
|
||
|
ServerToggleSuperSpeedRpc();
|
||
|
}
|
||
|
|
||
|
public void ToggleTeleportMode()
|
||
|
{
|
||
|
ServerToggleTeleportModeRpc();
|
||
|
}
|
||
|
|
||
|
public void ToggleDoor()
|
||
|
{
|
||
|
ServerToggleDoorRpc();
|
||
|
}
|
||
|
|
||
|
public void TogglePortals()
|
||
|
{
|
||
|
ServerTogglePortalsRpc();
|
||
|
}
|
||
|
|
||
|
public void GoToPostGame()
|
||
|
{
|
||
|
GoToPostGameServerRpc();
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerSpawnEnemyRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
var newEnemy = Instantiate(m_EnemyPrefab);
|
||
|
newEnemy.SpawnWithOwnership(NetworkManager.Singleton.LocalClientId, true);
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "SpawnEnemy");
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerSpawnBossRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
var newEnemy = Instantiate(m_BossPrefab);
|
||
|
newEnemy.SpawnWithOwnership(NetworkManager.Singleton.LocalClientId, true);
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "SpawnBoss");
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerKillTargetRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
ulong clientId = serverRpcParams.Receive.SenderClientId;
|
||
|
var playerServerCharacter = PlayerServerCharacter.GetPlayerServerCharacter(clientId);
|
||
|
if (playerServerCharacter != null)
|
||
|
{
|
||
|
var targetId = playerServerCharacter.TargetId.Value;
|
||
|
if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(targetId, out NetworkObject obj))
|
||
|
{
|
||
|
var damageable = obj.GetComponent<IDamageable>();
|
||
|
if (damageable != null && damageable.IsDamageable())
|
||
|
{
|
||
|
damageable.ReceiveHP(playerServerCharacter, int.MinValue);
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "KillTarget");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UnityEngine.Debug.Log($"Target {targetId} has no IDamageable component or cannot be damaged.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerKillAllEnemiesRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
foreach (var serverCharacter in FindObjectsOfType<ServerCharacter>())
|
||
|
{
|
||
|
if (serverCharacter.IsNpc && serverCharacter.LifeState == LifeState.Alive)
|
||
|
{
|
||
|
if (serverCharacter.gameObject.TryGetComponent(out IDamageable damageable))
|
||
|
{
|
||
|
damageable.ReceiveHP(null, -serverCharacter.HitPoints);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "KillAllEnemies");
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerToggleGodModeRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
var clientId = serverRpcParams.Receive.SenderClientId;
|
||
|
var playerServerCharacter = PlayerServerCharacter.GetPlayerServerCharacter(clientId);
|
||
|
if (playerServerCharacter != null)
|
||
|
{
|
||
|
playerServerCharacter.NetLifeState.IsGodMode.Value = !playerServerCharacter.NetLifeState.IsGodMode.Value;
|
||
|
PublishCheatUsedMessage(clientId, "ToggleGodMode");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerHealPlayerRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
var clientId = serverRpcParams.Receive.SenderClientId;
|
||
|
var playerServerCharacter = PlayerServerCharacter.GetPlayerServerCharacter(clientId);
|
||
|
if (playerServerCharacter != null)
|
||
|
{
|
||
|
var baseHp = playerServerCharacter.CharacterClass.BaseHP.Value;
|
||
|
if (playerServerCharacter.LifeState == LifeState.Fainted)
|
||
|
{
|
||
|
playerServerCharacter.Revive(null, baseHp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (playerServerCharacter.gameObject.TryGetComponent(out IDamageable damageable))
|
||
|
{
|
||
|
damageable.ReceiveHP(null, baseHp);
|
||
|
}
|
||
|
}
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "HealPlayer");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerToggleSuperSpeedRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
var clientId = serverRpcParams.Receive.SenderClientId;
|
||
|
foreach (var playerServerCharacter in PlayerServerCharacter.GetPlayerServerCharacters())
|
||
|
{
|
||
|
if (playerServerCharacter.OwnerClientId == clientId)
|
||
|
{
|
||
|
playerServerCharacter.Movement.SpeedCheatActivated = !playerServerCharacter.Movement.SpeedCheatActivated;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
PublishCheatUsedMessage(clientId, "ToggleSuperSpeed");
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerToggleTeleportModeRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
var clientId = serverRpcParams.Receive.SenderClientId;
|
||
|
foreach (var playerServerCharacter in PlayerServerCharacter.GetPlayerServerCharacters())
|
||
|
{
|
||
|
if (playerServerCharacter.OwnerClientId == clientId)
|
||
|
{
|
||
|
playerServerCharacter.Movement.TeleportModeActivated = !playerServerCharacter.Movement.TeleportModeActivated;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "ToggleTeleportMode");
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerToggleDoorRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
if (SwitchedDoor != null)
|
||
|
{
|
||
|
SwitchedDoor.ForceOpen = !SwitchedDoor.ForceOpen;
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "ToggleDoor");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UnityEngine.Debug.Log("Could not activate ToggleDoor cheat. Door not found.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void ServerTogglePortalsRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
foreach (var portal in FindObjectsOfType<EnemyPortal>())
|
||
|
{
|
||
|
if (m_DestroyPortalsOnNextToggle)
|
||
|
{
|
||
|
// This will only affect portals that are currently active in a scene and are currently loaded.
|
||
|
// Portals that are already destroyed will not be affected by this, and won't have their cooldown
|
||
|
// reinitialized.
|
||
|
portal.ForceDestroy();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
portal.ForceRestart();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_DestroyPortalsOnNextToggle = !m_DestroyPortalsOnNextToggle;
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "TogglePortals");
|
||
|
}
|
||
|
|
||
|
[Rpc(SendTo.Server, RequireOwnership = false)]
|
||
|
void GoToPostGameServerRpc(RpcParams serverRpcParams = default)
|
||
|
{
|
||
|
SceneLoaderWrapper.Instance.LoadScene("PostGame", useNetworkSceneManager: true);
|
||
|
PublishCheatUsedMessage(serverRpcParams.Receive.SenderClientId, "GoToPostGame");
|
||
|
}
|
||
|
|
||
|
void PublishCheatUsedMessage(ulong clientId, string cheatUsed)
|
||
|
{
|
||
|
var playerData = SessionManager<SessionPlayerData>.Instance.GetPlayerData(clientId);
|
||
|
if (playerData.HasValue)
|
||
|
{
|
||
|
m_CheatUsedMessagePublisher.Publish(new CheatUsedMessage(cheatUsed, playerData.Value.PlayerName));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void LogCheatNotImplemented(string cheat)
|
||
|
{
|
||
|
UnityEngine.Debug.Log($"Cheat {cheat} not implemented");
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
void Awake()
|
||
|
{
|
||
|
m_DebugCheatsPanel.SetActive(false);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|