Exemple #1
0
        public ClientManager(NetworkManager networkManager, PlayerManager playerManager,
                             AnimationManager animationManager, MapManager mapManager, Settings.GameSettings gameSettings,
                             PacketManager packetManager)
        {
            _netClient        = networkManager.GetNetClient();
            _playerManager    = playerManager;
            _animationManager = animationManager;
            _mapManager       = mapManager;
            _gameSettings     = gameSettings;

            _entityManager = new EntityManager(_netClient);

            _heartBeatReceiveStopwatch = new Stopwatch();

            // Register packet handlers
            packetManager.RegisterClientPacketHandler <ServerShutdownPacket>(PacketId.ServerShutdown, OnServerShutdown);
            packetManager.RegisterClientPacketHandler <ClientPlayerConnectPacket>(PacketId.PlayerConnect, OnPlayerConnect);
            packetManager.RegisterClientPacketHandler <ClientPlayerDisconnectPacket>(PacketId.PlayerDisconnect, OnPlayerDisconnect);
            packetManager.RegisterClientPacketHandler <ClientAlreadyInScenePacket>(PacketId.AlreadyInScene, OnAlreadyInScene);
            packetManager.RegisterClientPacketHandler <ClientPlayerEnterScenePacket>(PacketId.PlayerEnterScene,
                                                                                     OnPlayerEnterScene);
            packetManager.RegisterClientPacketHandler <ClientPlayerLeaveScenePacket>(PacketId.PlayerLeaveScene,
                                                                                     OnPlayerLeaveScene);
            packetManager.RegisterClientPacketHandler <ClientUpdatePacket>(
                PacketId.PlayerUpdate, OnUpdatePacket);
            packetManager.RegisterClientPacketHandler <ClientPlayerTeamUpdatePacket>(PacketId.PlayerTeamUpdate, OnPlayerTeamUpdate);
            packetManager.RegisterClientPacketHandler <GameSettingsUpdatePacket>(PacketId.GameSettingsUpdated,
                                                                                 OnGameSettingsUpdated);

            // Register the Hero Controller Start, which is when the local player spawns
            On.HeroController.Start += (orig, self) => {
                // Execute the original method
                orig(self);
                // If we are connect to a server, add a username to the player object
                if (networkManager.GetNetClient().IsConnected)
                {
                    _playerManager.AddNameToPlayer(HeroController.instance.gameObject, _username, _playerManager.LocalPlayerTeam);
                }
            };
            networkManager.GetNetClient().RegisterOnConnect(() => {
                // We should only be able to connect during a gameplay scene,
                // which is when the player is spawned already, so we can add the username
                _playerManager.AddNameToPlayer(HeroController.instance.gameObject, _username, _playerManager.LocalPlayerTeam);
            });

            // Register handlers for scene change and player update
            UnityEngine.SceneManagement.SceneManager.activeSceneChanged += OnSceneChange;
            On.HeroController.Update += OnPlayerUpdate;

            // Register client connect handler
            _netClient.RegisterOnConnect(OnClientConnect);

            // Register application quit handler
            ModHooks.Instance.ApplicationQuitHook += OnApplicationQuit;

            // Prevent changing the timescale if the client is connected to ensure synchronisation between clients
            On.GameManager.SetTimeScale_float += (orig, self, scale) => {
                if (!_netClient.IsConnected)
                {
                    orig(self, scale);
                }
                else
                {
                    // Always put the time scale to 1.0, thus never allowing the game to change speed
                    // This is to prevent desyncs in multiplayer
                    orig(self, 1.0f);
                }
            };
            // Register pause callback to make sure the player doesn't keep dashing or moving
            On.HeroController.Pause += (orig, self) => {
                if (!_netClient.IsConnected)
                {
                    orig(self);
                    return;
                }

                // We simply call the private ResetInput method to prevent the knight from continuing movement
                // while the game is paused
                typeof(HeroController).InvokeMember(
                    "ResetInput",
                    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
                    null,
                    HeroController.instance,
                    null
                    );
            };

            // To make sure that if we are paused, and we enter a screen transition,
            // we still go through it. So we unpause first, then execute the original method
            On.TransitionPoint.OnTriggerEnter2D += (orig, self, obj) => {
                // Unpause if paused
                if (UIManager.instance != null)
                {
                    if (UIManager.instance.uiState.Equals(UIState.PAUSED))
                    {
                        UIManager.instance.TogglePauseGame();
                    }
                }

                // Execute original method
                orig(self, obj);
            };
        }