Beispiel #1
0
 public void PrintMoveMap(Movemap movemap, Node.TileGameStatus characterFraction)
 {
     foreach (var tilePosition in movemap.MoveCoords)
     {
         Movemap.SetTile(tilePosition, MoveTile);
     }
     foreach (var tilePosition in movemap.MeleeCoords)
     {
         if (GetNode(tilePosition).GameStatus == characterFraction)
         {
             Movemap.SetTile(tilePosition, AllyTile);
         }
         else
         {
             Movemap.SetTile(tilePosition, EnemyTile);
         }
     }
     foreach (var tilePosition in movemap.RangeCoords)
     {
         if (GetNode(tilePosition).GameStatus == characterFraction)
         {
             Movemap.SetTile(tilePosition, AllyTile);
         }
         else
         {
             Movemap.SetTile(tilePosition, EnemyTile);
         }
     }
 }
Beispiel #2
0
    public void DefineAvailableMeleeTargets(Movemap movemap, Character currentCharacter, List <Character> characterList, List <Node.TileGameStatus> targetFractions, int attackDistance)
    {
        foreach (var character in characterList)
        {
            if (character.Properties.CurrentHealth <= 0 ||
                character == currentCharacter ||
                !targetFractions.Contains(Node.GetTileStatusFromCharacter(character)))
            {
                continue;
            }

            Vector3Int offsetCoords = character.Coords;
            //check all directions
            for (int i = 0; i < 4; ++i)
            {
                offsetCoords = character.Coords + attackDistance * offsets[i];

                //if tile belongs to movemap and empty than character can attack target from it
                if (movemap.MoveCoords.IndexOf(offsetCoords) != -1)
                {
                    movemap.MeleeCoords.Add(character.Coords);
                    break;
                }
            }
        }
    }
Beispiel #3
0
    public Movemap Copy()
    {
        Movemap newMovemap = new Movemap();

        newMovemap.MoveCoords.AddRange(MoveCoords);
        newMovemap.MeleeCoords.AddRange(MeleeCoords);
        newMovemap.RangeCoords.AddRange(RangeCoords);
        return(newMovemap);
    }
Beispiel #4
0
    public void PrintCharacterMoveMap(Character character, List <Character> characterList, int attackDistance)
    {
        Node.TileGameStatus fraction;
        fraction = Node.GetTileStatusFromCharacter(character);
        List <Node.TileGameStatus> fractionList = new List <Node.TileGameStatus>();

        if (fraction == Node.TileGameStatus.Ally)
        {
            fractionList.Add(Node.TileGameStatus.Enemy);
        }
        else
        {
            fractionList.Add(Node.TileGameStatus.Ally);
        }
        _movemap = BuildMovemap(fraction, character.Properties.Speed, character.Coords);
        DefineAvailableMeleeTargets(_movemap, character, characterList, fractionList, attackDistance);
        PrintMoveMap(_movemap, fraction);
    }
Beispiel #5
0
    public List <Vector3Int> DefinePositionsToAttackTarget(Movemap movemap, Character target, int attackDistance)
    {
        Vector3Int        offsetCoords = target.Coords;
        List <Vector3Int> positions    = new List <Vector3Int>();

        //check all directions
        for (int i = 0; i < 4; ++i)
        {
            offsetCoords = target.Coords + attackDistance * offsets[i];

            //if tile belongs to movemap and empty than character can attack from it
            if (movemap.MoveCoords.IndexOf(offsetCoords) != -1)
            {
                positions.Add(offsetCoords);
            }
        }
        return(positions);
    }
Beispiel #6
0
    /*
     * Movemap section
     */

    public Movemap BuildMovemap(Node.TileGameStatus fraction, int moveDistance, Vector3Int position)
    {
        Movemap     map            = new Movemap();
        List <Node> nodesToProcess = new List <Node>();

        Node currentNode = _graph.GetNode(position);

        if (currentNode.GameStatus == Node.TileGameStatus.Block)
        {
            return(map);
        }
        currentNode.ProcessValue  = moveDistance;
        currentNode.ProcessStatus = Node.NodeProcessStatus.InOpenList;
        nodesToProcess.Add(currentNode);
        map.MoveCoords.Add(currentNode.Coords);

        while (nodesToProcess.Count != 0)
        {
            currentNode = nodesToProcess[0];
            foreach (var connection in currentNode.Connections)
            {
                Node endNode = connection.EndNode;

                if ((endNode.ProcessStatus == Node.NodeProcessStatus.NotVisited ||
                     endNode.ProcessValue < currentNode.ProcessValue - 1) &&
                    endNode.GameStatus == Node.TileGameStatus.Empty)
                {
                    //first entry in open list and not taken by characters
                    if (endNode.ProcessStatus == Node.NodeProcessStatus.NotVisited)
                    {
                        map.MoveCoords.Add(endNode.Coords);
                    }

                    endNode.ProcessValue = currentNode.ProcessValue - 1;

                    //if node has been already waiting processing in open list then change order
                    if (endNode.ProcessStatus == Node.NodeProcessStatus.InOpenList)
                    {
                        nodesToProcess.Remove(endNode);
                    }

                    if (endNode.ProcessValue > 0)
                    {
                        int indexToInsert = nodesToProcess.FindLastIndex(delegate(Node node)
                        {
                            return(node.ProcessValue >= endNode.ProcessValue);
                        });
                        nodesToProcess.Insert(indexToInsert, endNode);
                        endNode.ProcessStatus = Node.NodeProcessStatus.InOpenList;
                    }
                    else
                    {
                        endNode.ProcessStatus = Node.NodeProcessStatus.InClosedList;
                    }
                }
            }
            nodesToProcess.Remove(currentNode);
            currentNode.ProcessStatus = Node.NodeProcessStatus.InClosedList;
        }
        _graph.RestoreProcessStatus();
        return(map);
    }
Beispiel #7
0
 public void SetMovemap(Movemap movemap)
 {
     _movemap = movemap;
 }
Beispiel #8
0
    //foreach possible decision pair it with target given by context
    //this is bad solution, because to create new qualifier we need to upgrade this method
    public void MakeDecisionsList(ContextBase context)
    {
        if (PossibleDecisions == null)
        {
            PossibleDecisions = new List <Decision>();
        }
        PossibleDecisions.Clear();
        for (int i = 0; i < Qualifiers.Count; ++i)
        {
            if (Qualifiers[i].Type == UtilityAISystem.Qualifiers.MeleeAttack)
            {
                for (int j = 0; j < context.AvailableMeleeTargets.Count; ++j)
                {
                    Character target = GameController.Instance.FindCharacter(context.AvailableMeleeTargets[j]);
                    //we need define from that side character can attack his target
                    List <Vector3Int> possibleTilesToAttack = GridSystem.Instance.GetNearMovemapTilesList(target.Coords);
                    if (GameController.Instance.IsCharactersStayNear(context.Provider.GetControlledCharacter(), target))
                    {
                        possibleTilesToAttack.Add(context.Provider.GetControlledCharacter().Coords);
                    }
                    foreach (var coords in possibleTilesToAttack)
                    {
                        Decision decision = new Decision();
                        decision.Context        = context.Copy();
                        decision.Context.Target = target;
                        decision.Context.Data.Add("AttackTile", coords);
                        decision.QualifierRef = Qualifiers[i];
                        PossibleDecisions.Add(decision);
                    }
                }
            }
            else if (Qualifiers[i].Type == UtilityAISystem.Qualifiers.Move)
            {
                Character currentCharacter = context.Provider.GetControlledCharacter();
                Movemap   movemap          = GridSystem.Instance.GetCurrentMovemap();
                for (int j = 0; j < movemap.MoveCoords.Count; ++j)
                {
                    if (movemap.MoveCoords[j] == currentCharacter.Coords)
                    {
                        continue;
                    }
                    Decision decision = new Decision();
                    decision.Context        = context.Copy();
                    decision.Context.Target = movemap.MoveCoords[j];
                    decision.QualifierRef   = Qualifiers[i];
                    PossibleDecisions.Add(decision);
                }
            }
            else if (Qualifiers[i].Type == UtilityAISystem.Qualifiers.RangedAttack)
            {
                for (int j = 0; j < context.AvailableRangedTargets.Count; ++j)
                {
                    Character target   = GameController.Instance.FindCharacter(context.AvailableRangedTargets[j]);
                    Decision  decision = new Decision();
                    decision.Context        = context.Copy();
                    decision.Context.Target = target;
                    decision.QualifierRef   = Qualifiers[i];
                    PossibleDecisions.Add(decision);
                }
            }
            else if (Qualifiers[i].Type == UtilityAISystem.Qualifiers.Skill)
            {
                Character user  = context.Provider.GetControlledCharacter();
                Skill     skill = user.Skills[Qualifiers[i].SkillNo];
                if (skill.CurrentCooldown > 0 || skill.CurrentCount == 0)
                {
                    continue;
                }
                if (skill.TypeTarget == Skill.TargetType.Self)
                {
                    Decision decision = new Decision();
                    decision.Context        = context.Copy();
                    decision.Context.Target = user;
                    decision.Context.Data.Add("SkillNo", Qualifiers[i].SkillNo);
                    decision.QualifierRef = Qualifiers[i];
                    PossibleDecisions.Add(decision);
                }
                else if (skill.TypeUse == Skill.UseType.Melee)
                {
                    //define list of target fractions
                    List <string> fractionList = new List <string>();
                    if (skill.FractionTarget == Skill.TargetFraction.Enemy)
                    {
                        fractionList.Add(user.GetOppositeFraction());
                    }
                    else if (skill.FractionTarget == Skill.TargetFraction.Ally)
                    {
                        fractionList.Add(user.tag);
                    }
                    else
                    {
                        fractionList.Add(user.GetOppositeFraction());
                        fractionList.Add(user.tag);
                    }
                    //define all data
                    Movemap skillMovemap = new Movemap();
                    skillMovemap.MoveCoords.AddRange(GridSystem.Instance.GetCurrentMovemap().MoveCoords);
                    //define all target that character can reach
                    GridSystem.Instance.DefineAvailableMeleeTargets(skillMovemap, user, GameController.Instance.CharacterList, GridSystem.ConvertFractionsFromStringToNode(fractionList), skill.Distance);

                    //define all positions to attack for all targets
                    List <List <Vector3Int> > possiblePositions = new List <List <Vector3Int> >();
                    for (int j = 0; j < skillMovemap.MeleeCoords.Count; ++j)
                    {
                        Character targetCharacter = GridSystem.Instance.GetCharacterFromCoords(skillMovemap.MeleeCoords[j]);
                        //get possible positions to attack
                        possiblePositions.Add(GridSystem.Instance.DefinePositionsToAttackTarget(skillMovemap, targetCharacter, skill.Distance));
                        //additional special checks
                        skill.AdditionalChecks(targetCharacter, possiblePositions[j]);
                        //if there no possible positions to attack than delete this target from list
                        if (possiblePositions[j].Count == 0)
                        {
                            skillMovemap.MeleeCoords.RemoveAt(j);
                            possiblePositions.RemoveAt(j);
                            --j;
                        }
                    }

                    //create decision to all pairs target-possible position
                    for (int j = 0; j < skillMovemap.MeleeCoords.Count; ++j)
                    {
                        foreach (var coords in possiblePositions[j])
                        {
                            Decision decision = new Decision();
                            decision.Context        = context.Copy();
                            decision.Context.Target = GridSystem.Instance.GetCharacterFromCoords(skillMovemap.MeleeCoords[j]);
                            decision.Context.Data.Add("AttackTile", coords);
                            decision.Context.Data.Add("SkillNo", Qualifiers[i].SkillNo);
                            decision.QualifierRef = Qualifiers[i];
                            PossibleDecisions.Add(decision);
                        }
                    }
                }
                else if (skill.TypeUse == Skill.UseType.Randged)
                {
                    //define list of target fractions
                    List <string> fractionList = new List <string>();
                    if (skill.FractionTarget == Skill.TargetFraction.Enemy)
                    {
                        fractionList.Add(user.GetOppositeFraction());
                    }
                    else if (skill.FractionTarget == Skill.TargetFraction.Ally)
                    {
                        fractionList.Add(user.tag);
                    }
                    else
                    {
                        fractionList.Add(user.GetOppositeFraction());
                        fractionList.Add(user.tag);
                    }

                    Movemap skillMovemap       = new Movemap();
                    bool    isThereEnemyNearby = GameController.Instance.IsThereEnemyNearby(user);

                    if ((isThereEnemyNearby && skill.UseNearEnemy) ||
                        (!isThereEnemyNearby && user.Properties.Class != CharacterClass.Archer))
                    {
                        foreach (var fraction in fractionList)
                        {
                            skillMovemap.RangeCoords.AddRange(GameController.Instance.DefineAvailableRangedTargets(user, fraction));
                        }
                    }
                    else if (!isThereEnemyNearby && user.Properties.Class == CharacterClass.Archer) //this can reduce amount of raycasts
                    {
                        skillMovemap.RangeCoords.AddRange(GridSystem.Instance.GetCurrentMovemap().RangeCoords);
                        if (fractionList.Contains(user.tag))
                        {
                            skillMovemap.RangeCoords.AddRange(GameController.Instance.DefineAvailableRangedTargets(user, user.tag));
                        }
                    }

                    foreach (var targetCoords in skillMovemap.RangeCoords)
                    {
                        Decision decision = new Decision();
                        decision.Context        = context.Copy();
                        decision.Context.Target = GridSystem.Instance.GetCharacterFromCoords(targetCoords);
                        decision.Context.Data.Add("SkillNo", Qualifiers[i].SkillNo);
                        decision.QualifierRef = Qualifiers[i];
                        PossibleDecisions.Add(decision);
                    }
                }
            }
        }
    }