public MatchPlayerController(IMatchEngine engine, int playerIndex, Dictionary <int, VoxelAbilities>[] allAbilities)
        {
            m_playerIndex  = playerIndex;
            m_engine       = engine;
            m_allAbilities = allAbilities;

            m_engine.Map.Root.ForEach(cell =>
            {
                cell.ForEach(voxelData =>
                {
                    int owner = voxelData.Owner;
                    if (owner == m_playerIndex)
                    {
                        if (VoxelData.IsUnit(voxelData.Type))
                        {
                            Coordinate coordinate = new Coordinate(cell, voxelData);
                            CreateUnitController(voxelData, coordinate);
                        }
                        else
                        {
                            if (!voxelData.IsNeutral)
                            {
                                CreateAsset(voxelData, cell);
                            }
                        }
                    }
                });
            });

            m_units         = m_idToUnit.Values.ToArray();
            m_commandBuffer = new CommandsArray(new Cmd[m_idToUnit.Count]);
        }
 public CommandsArray(CommandsArray arr)
 {
     if (arr.Commands != null)
     {
         Commands = arr.Commands.ToArray();
     }
 }
        public bool Tick(long tick, out CommandsBundle commands)
        {
            for (int i = 0; i < m_players.Length; ++i)
            {
                m_pathFinders[i].Tick();
                m_taskRunners[i].Tick();
            }

            List <IMatchPlayerController> defeatedPlayers = null;

            for (int i = 0; i < m_players.Length; ++i)
            {
                IMatchPlayerController playerController = m_players[i];

                bool wasInRoom = playerController.IsPlayerInRoom;

                CommandsArray playerCommands;

                if (playerController.Tick(tick, out playerCommands))
                {
                    m_hasNewCommands = true;
                }

                if (wasInRoom && !playerController.IsPlayerInRoom)
                {
                    playerCommands = new CommandsArray(playerCommands);

                    Array.Resize(ref playerCommands.Commands, playerCommands.Commands.Length + 1);

                    playerCommands.Commands[playerCommands.Commands.Length - 1] = new Cmd(CmdCode.LeaveRoom, -1);

                    if (defeatedPlayers == null)
                    {
                        defeatedPlayers = new List <IMatchPlayerController>();
                    }

                    defeatedPlayers.Add(playerController);
                }
                else if (!playerController.HasControllableUnits)
                {
                    if (defeatedPlayers == null)
                    {
                        defeatedPlayers = new List <IMatchPlayerController>();
                    }

                    defeatedPlayers.Add(playerController);
                }

                m_serverCommands.Commands[i] = playerCommands;
            }

            if (defeatedPlayers != null)
            {
                for (int i = 0; i < defeatedPlayers.Count; ++i)
                {
                    IMatchPlayerController defeatedPlayer = defeatedPlayers[i];
                    defeatedPlayer.DestroyAllUnitsAndAssets();
                }
            }

            bool wasGameCompleted = m_serverCommands.IsGameCompleted;

            m_serverCommands.IsGameCompleted = IsCompleted();

            if (wasGameCompleted != m_serverCommands.IsGameCompleted)
            {
                m_hasNewCommands = true;
            }

            if (m_hasNewCommands)
            {
                commands = m_serializer.DeepClone(m_serverCommands);
                if (m_serverCommands.TasksStateInfo.Count > 0)
                {
                    m_serverCommands.TasksStateInfo.Clear();
                }
                if (m_serverCommands.ClientRequests.Count > 0)
                {
                    m_serverCommands.ClientRequests.Clear();
                }
                m_hasNewCommands = false;
                for (int i = 0; i < m_taskEngines.Length; ++i)
                {
                    m_taskEngines[i].Tick();
                }

                return(true);
            }

            commands = null;
            for (int i = 0; i < m_taskEngines.Length; ++i)
            {
                m_taskEngines[i].Tick();
            }
            return(false);
        }
Beispiel #4
0
        private void OnEngineCommands(Error error, long clientTick, CommandsBundle commandBundle)
        {
            if (m_engine.HasError(error))
            {
                if (error.Code != StatusCode.Outdated)
                {
                    m_notification.ShowError(error);
                    return;
                }
            }

            long serverTick = commandBundle.Tick;

            CommandsArray[] playersCommands = commandBundle.Commands;
            //List<TaskStateInfo> taskStateInfo = commandBundle.TasksStateInfo;
            bool isGameCompleted = commandBundle.IsGameCompleted;

            m_minimap.BeginUpdate();

            List <IMatchPlayerControllerCli> defeatedPlayers = null;

            for (int p = 0; p < playersCommands.Length; ++p)
            {
                CommandsArray commands = playersCommands[p];
                if (commands.Commands == null)
                {
                    continue;
                }

                if (error.Code == StatusCode.Outdated)
                {
                    Debug.LogWarning("Executing outdated command a little bit faster " + serverTick);
                }

                IMatchPlayerControllerCli playerController = m_playerControllers[p];
                long lagTicks = clientTick - serverTick;
                Debug.Assert(lagTicks >= 0);

                playerController.Execute(commands.Commands, clientTick, lagTicks);

                PlayerStats stats = m_playerStats[p];
                if (stats.IsInRoom && !playerController.IsInRoom)
                {
                    stats.IsInRoom = false;
                    //Raise player deactivated event;
                    Debug.Log("Player " + m_players[p].Name + " has left the game");

                    if (defeatedPlayers == null)
                    {
                        defeatedPlayers = new List <IMatchPlayerControllerCli>();
                    }
                    defeatedPlayers.Add(playerController);
                }
                else if (playerController.ControllableUnitsCount == 0)
                {
                    if (defeatedPlayers == null)
                    {
                        defeatedPlayers = new List <IMatchPlayerControllerCli>();
                    }
                    defeatedPlayers.Add(playerController);
                }

                stats.ControllableUnitsCount = playerController.ControllableUnitsCount;
            }

            if (defeatedPlayers != null)
            {
                for (int i = 0; i < defeatedPlayers.Count; ++i)
                {
                    IMatchPlayerControllerCli defeatedPlayer = defeatedPlayers[i];
//#warning Temporary disabled due to strange bugs
                    defeatedPlayer.DestroyAllUnitsAndAssets();

                    if (PlayerDefeated != null)
                    {
                        PlayerDefeated(defeatedPlayer.Index);
                    }
                }
            }

            if (!m_gSettings.DisableFogOfWar)
            {
                m_minimap.EndUpdate();
            }


            IsCompleted = isGameCompleted;
        }
        public bool Tick(long tick, out CommandsArray commands)
        {
            m_isPlayerInRoom = !m_isPlayerLeftRoom;

            bool isChanged = false;

            if (m_units.Length != m_commandBuffer.Commands.Length)
            {
                m_commandBuffer = new CommandsArray(new Cmd[m_idToUnit.Count]);
            }

            bool unitsChanged = false;

            for (int i = 0; i < m_units.Length; ++i)
            {
                IMatchUnitController unitController = m_units[i];

                Cmd cmd;
                unitController.Tick(tick, out cmd);

                IList <VoxelDataCellPair> createdVoxels = unitController.CreatedVoxels;
                if (createdVoxels.Count != 0)
                {
                    CreateAssets(createdVoxels);
                    for (int j = 0; j < m_otherPlayerControllers.Length; ++j)
                    {
                        m_otherPlayerControllers[j].CreateAssets(createdVoxels);
                    }
                }

                IList <VoxelData> eatenOrDestroyed = unitController.EatenOrDestroyedVoxels;
                if (eatenOrDestroyed.Count != 0)
                {
                    RemoveAssets(eatenOrDestroyed);
                    for (int j = 0; j < m_otherPlayerControllers.Length; ++j)
                    {
                        m_otherPlayerControllers[j].RemoveAssets(eatenOrDestroyed);
                    }
                }

                m_commandBuffer.Commands[i] = cmd;

                if (cmd != null)
                {
                    isChanged = true;

                    if (cmd.Code == CmdCode.Composite)
                    {
                        CompositeCmd composite = (CompositeCmd)cmd;
                        for (int c = 0; c < composite.Commands.Length; ++c)
                        {
                            unitsChanged = PostprocessCmd(unitsChanged, unitController, composite.Commands[c]);
                        }
                    }
                    else
                    {
                        unitsChanged = PostprocessCmd(unitsChanged, unitController, cmd);
                    }
                }


                if (!unitController.IsAlive)
                {
                    unitsChanged = RemoveUnitController(unitsChanged, unitController);
                }
            }


            if (unitsChanged)
            {
                m_units = m_idToUnit.Values.ToArray();
            }

            commands = m_commandBuffer;

            return(isChanged);
        }