// Works backward, looking up ideal steps in cameFrom, to reproduce the full path
    public Godot.Collections.Array reconstructPath(Vector2 currentVector)
    {
        String currentVectorId = vector2ToId(currentVector);

        Godot.Collections.Array totalPath = new Godot.Collections.Array();
        totalPath.Insert(0, currentVector);

        while (cameFrom.Contains(currentVectorId))
        {
            currentVector   = (Vector2)cameFrom[currentVectorId];
            currentVectorId = vector2ToId(currentVector);
            totalPath.Insert(0, currentVector);
        }

        return(totalPath);
    }
Example #2
0
    // Update and generate a game state snapshot
    private void _updateState()
    {
        // If not on the server, bail
        if (!GetTree().IsNetworkServer())
        {
            return;
        }

        // Initialize the "high level" snapshot
        Snapshot snapshot = new Snapshot();

        snapshot.signature = snapshotSignature;

        Godot.Collections.Array <String> removeSpawnPlayers = new Godot.Collections.Array <String>();

        foreach (KeyValuePair <int, NetworkPlayer> networkPlayer in network.networkPlayers)
        {
            String playerId = _agentPlayerPrefix + networkPlayer.Value.net_id;
            // Node may not being created yet
            if (!spawnPlayers.ContainsKey(playerId))
            {
                // Ideally should give a warning that a player node wasn't found
                continue;
            }

            Agent playerNode = spawnPlayers[playerId];

            if (playerNode == null || !IsInstanceValid(playerNode))
            {
                // Ideally should give a warning that a player node wasn't found
                continue;
            }

            Vector2 pPosition = playerNode.Position;
            float   pRotation = playerNode.Rotation;

            // Only update if player is not dead yet
            if (playerNode.getHealth() > 0)
            {
                // Check if there is any input for this player. In that case, update the state
                if (GameStates.playerInputs.ContainsKey(networkPlayer.Key) && GameStates.playerInputs[networkPlayer.Key].Count > 0)
                {
                    int rightWeapon = 0;
                    int leftWeapon  = 0;

                    // Calculate the delta
                    float delta = GameStates.updateDelta / (float)(GameStates.playerInputs[networkPlayer.Key].Count);

                    foreach (KeyValuePair <int, GameStates.PlayerInput> input in GameStates.playerInputs[networkPlayer.Key])
                    {
                        Vector2 moveDir = Vector2.Zero;
                        moveDir.y -= input.Value.Up;
                        moveDir.y += input.Value.Down;
                        moveDir.x -= input.Value.Left;
                        moveDir.x += input.Value.Right;

                        playerNode.changeWeapon(input.Value.RightWeaponIndex, Weapon.WeaponOrder.Right);
                        playerNode.changeWeapon(input.Value.LeftWeaponIndex, Weapon.WeaponOrder.Left);

                        if (!_waitingPeriod)
                        {
                            rightWeapon = input.Value.RightWeaponAction;
                            leftWeapon  = input.Value.LeftWeaponAction;
                        }
                        playerNode.Fire(Weapon.WeaponOrder.Right, rightWeapon);
                        playerNode.Fire(Weapon.WeaponOrder.Left, leftWeapon);

                        playerNode.RotateToward(input.Value.MousePosition, delta);
                        playerNode.MoveToward(moveDir, delta);
                    }

                    // Cleanup the input vector
                    GameStates.playerInputs[networkPlayer.Key].Clear();

                    GameStates.playerInputs.Remove(networkPlayer.Key);

                    ClientData clientData = new ClientData();
                    clientData.Id               = networkPlayer.Key + "";
                    clientData.Position         = playerNode.Position;
                    clientData.Rotation         = playerNode.Rotation;
                    clientData.RightWeapon      = rightWeapon;
                    clientData.LeftWeapon       = leftWeapon;
                    clientData.RightWeaponIndex = playerNode.GetCurrentWeaponIndex(Weapon.WeaponOrder.Right);
                    clientData.LeftWeaponIndex  = playerNode.GetCurrentWeaponIndex(Weapon.WeaponOrder.Left);
                    clientData.Health           = playerNode.getHealth();

                    snapshot.playerData.Add(networkPlayer.Key, clientData);
                }
            }
            else
            {
                removeSpawnPlayers.Insert(0, playerId);
            }
        }

        // Clean the input
        GameStates.playerInputs.Clear();

        foreach (String spawnPlayerId in removeSpawnPlayers)
        {
            // Respawn dead player if that team still allow new unit
            Team.TeamCode teamCode    = spawnPlayers[spawnPlayerId].GetCurrentTeam();
            String        displayName = spawnPlayers[spawnPlayerId].GetDisplayName();
            _removeUnitOnNetwork(spawnPlayerId);

            // Respawn if that team still allow new unit
            if (TeamMapAIs[(int)teamCode].isNewUnitAllow())
            {
                _spawnPlayer(spawnPlayerId.Replace(_agentPlayerPrefix, "") + ";" + (int)teamCode + ";" + _agentPlayerPrefix + _agentPlayerCounter + ";" + displayName);
                _agentPlayerCounter++;
            }
        }

        Godot.Collections.Array <String> removeSpawnBots = new Godot.Collections.Array <String>();

        foreach (Agent agent in SpawnBots.Values)
        {
            // Locate the bot node
            Agent enemyNode = (Agent)TeamMapAIs[(int)agent.GetCurrentTeam()].GetUnit(agent.Name);

            if (enemyNode == null || !IsInstanceValid(enemyNode))
            {
                // Ideally should give a warning that a bot node wasn't found
                continue;
            }


            int rightWeapon = (int)GameStates.PlayerInput.InputAction.NOT_TRIGGER;
            int leftWeapon  = (int)GameStates.PlayerInput.InputAction.NOT_TRIGGER;

            if (!_waitingPeriod)
            {
                rightWeapon = enemyNode.RightWeaponAction;
                leftWeapon  = enemyNode.LeftWeaponAction;
            }

            enemyNode.Fire(Weapon.WeaponOrder.Right, rightWeapon);
            enemyNode.Fire(Weapon.WeaponOrder.Left, leftWeapon);

            if (enemyNode.getHealth() > 0)
            {
                // Build bot_data entry
                ClientData clientData = new ClientData();
                clientData.Id               = enemyNode.Name;
                clientData.Position         = enemyNode.GlobalPosition;
                clientData.Rotation         = enemyNode.GlobalRotation;
                clientData.Health           = enemyNode.getHealth();
                clientData.RightWeapon      = rightWeapon;
                clientData.LeftWeapon       = leftWeapon;
                clientData.RightWeaponIndex = enemyNode.GetCurrentWeaponIndex(Weapon.WeaponOrder.Right);
                clientData.LeftWeaponIndex  = enemyNode.GetCurrentWeaponIndex(Weapon.WeaponOrder.Left);

                // Append into the snapshot
                snapshot.botData.Add(enemyNode.Name, clientData);

                // This logic is necessary to notify the AI that reload is pick up, so can continue with next state
                if (rightWeapon == (int)GameStates.PlayerInput.InputAction.RELOAD)
                {
                    enemyNode.RightWeaponAction = (int)GameStates.PlayerInput.InputAction.NOT_TRIGGER;
                }
                if (leftWeapon == (int)GameStates.PlayerInput.InputAction.RELOAD)
                {
                    enemyNode.LeftWeaponAction = (int)GameStates.PlayerInput.InputAction.NOT_TRIGGER;
                }
            }
            else
            {
                removeSpawnBots.Insert(0, enemyNode.Name);
            }
        }

        foreach (String spawnBotId in removeSpawnBots)
        {
            _removeUnitOnNetwork(spawnBotId);
        }

        if (removeSpawnBots.Count > 0)
        {
            _syncBots();
        }

        // Encode and broadcast the snapshot - if there is at least one connected client
        if (network.networkPlayers.Count > 1)
        {
            encodeSnapshot(snapshot);
        }
        // Make sure the next update will have the correct snapshot signature
        snapshotSignature += 1;
    }
Example #3
0
    // Update and generate a game state snapshot
    private void updateState()
    {
        // If not on the server, bail
        if (!GetTree().IsNetworkServer())
        {
            return;
        }
        // Initialize the "high level" snapshot
        Snapshot snapshot = new Snapshot();

        snapshot.signature = snapshotSignature;

        foreach (KeyValuePair <int, NetworkPlayer> networkPlayer in network.networkPlayers)
        {
            // Node may not being created yet
            if (!HasNode("client_" + networkPlayer.Value.net_id))
            {
                // Ideally should give a warning that a player node wasn't found
                continue;
            }

            // Locate the player's node. Even if there is no input/update, it's state will be dumped
            // into the snapshot anyway
            Player playerNode = (Player)GetNode("client_" + networkPlayer.Value.net_id);

            if (!IsInstanceValid(playerNode) || playerNode == null)
            {
                // Ideally should give a warning that a player node wasn't found
                continue;
            }

            Vector2 pPosition = playerNode.Position;
            float   pRotation = playerNode.Rotation;


            // Check if there is any input for this player. In that case, update the state
            if (gameStates.playerInputs.ContainsKey(networkPlayer.Key) && gameStates.playerInputs[networkPlayer.Key].Count > 0)
            {
                bool primaryWeapon   = false;
                bool secondaryWeapon = false;

                // Calculate the delta
                float delta = gameStates.updateDelta / (float)(gameStates.playerInputs[networkPlayer.Key].Count);

                foreach (KeyValuePair <int, GameStates.PlayerInput> input in gameStates.playerInputs[networkPlayer.Key])
                {
                    Vector2 moveDir = new Vector2();
                    if (input.Value.up)
                    {
                        moveDir.y = -1;
                    }
                    if (input.Value.down)
                    {
                        moveDir.y = 1;
                    }
                    if (input.Value.left)
                    {
                        moveDir.x = -1;
                    }
                    if (input.Value.right)
                    {
                        moveDir.x = 1;
                    }
                    primaryWeapon   = input.Value.primaryWepaon;
                    secondaryWeapon = input.Value.secondaryWepaon;
                    if (input.Value.changePrimaryWeapon)
                    {
                        playerNode.changePrimaryWeapon(playerNode.currentPrimaryWeaponIndex + 1);
                    }
                    if (input.Value.changeSecondaryWeapon)
                    {
                        playerNode.changeSecondaryWeapon(playerNode.currentSecondaryWeaponIndex + 1);
                    }
                    playerNode._shoot(primaryWeapon, secondaryWeapon);
                    playerNode.move(moveDir, input.Value.mousePosition, delta);
                }

                // Cleanup the input vector
                gameStates.playerInputs[networkPlayer.Key].Clear();

                gameStates.playerInputs.Remove(networkPlayer.Key);

                ClientData clientData = new ClientData();
                clientData.id                   = networkPlayer.Key + "";
                clientData.position             = playerNode.Position;
                clientData.rotation             = playerNode.Rotation;
                clientData.primaryWepaon        = primaryWeapon;
                clientData.secondaryWepaon      = secondaryWeapon;
                clientData.primaryWeaponIndex   = playerNode.currentPrimaryWeaponIndex;
                clientData.secondaryWeaponIndex = playerNode.currentSecondaryWeaponIndex;
                clientData.health               = playerNode.getHealth();

                snapshot.playerData.Add(networkPlayer.Key, clientData);
            }
        }

        // Clean the input
        gameStates.playerInputs.Clear();

        Godot.Collections.Array <String> removeSpawnBots = new Godot.Collections.Array <String>();

        foreach (SpawnBot spawnBot in spawnBots.Values)
        {
            // Locate the bot node
            Enemy enemyNode = (Enemy)GetNode(spawnBot.name);

            if (enemyNode == null)
            {
                // Ideally should give a warning that a bot node wasn't found
                continue;
            }

            enemyNode._shoot(enemyNode.isPrimaryWeapon, enemyNode.isSecondaryWeapon);

            if (enemyNode.getHealth() > 0)
            {
                // Build bot_data entry
                ClientData clientData = new ClientData();
                clientData.id                   = spawnBot.name;
                clientData.position             = enemyNode.GlobalPosition;
                clientData.rotation             = enemyNode.GlobalRotation;
                clientData.health               = enemyNode.getHealth();
                clientData.primaryWepaon        = enemyNode.isPrimaryWeapon;
                clientData.secondaryWepaon      = enemyNode.isSecondaryWeapon;
                clientData.primaryWeaponIndex   = enemyNode.currentPrimaryWeaponIndex;
                clientData.secondaryWeaponIndex = enemyNode.currentSecondaryWeaponIndex;

                // Append into the snapshot
                snapshot.botData.Add(spawnBot.name, clientData);
            }
            else
            {
                removeSpawnBots.Insert(0, spawnBot.name);
            }
        }

        foreach (String spawnBotId in removeSpawnBots)
        {
            removeClient(spawnBotId);
        }

        if (removeSpawnBots.Count > 0)
        {
            syncBots(-1);
        }

        // Encode and broadcast the snapshot - if there is at least one connected client
        if (network.networkPlayers.Count > 1)
        {
            encodeSnapshot(snapshot);
        }
        // Make sure the next update will have the correct snapshot signature
        snapshotSignature += 1;
    }
 private void CombineSets()
 {
     TotalGenome.Insert((int)ChromosomeSet.Maternal, MaternalChromosomeSet);
     TotalGenome.Insert((int)ChromosomeSet.Paternal, PaternalChromosomeSet);
 }