Esempio n. 1
0
    public bool HasOverlappedTargetWithWeapon(Vector2 targetPos, WeaponPart part)
    {
        LookaheadNode curSearchNode = this;

        bool crossedTarget = false;

        while (curSearchNode != null && curSearchNode.ParentNode != null)
        {
            Vector2 originFireVec = part.OwningTank.Hull.Schematic.OrigWeaponDirs[part.EquipIdx];
            float   range         = part.Schematic.Range;

            Vector2 curFireVec    = originFireVec.Rotate(curSearchNode.TankInfo.Rot);
            Vector2 parentFireVec = originFireVec.Rotate(curSearchNode.ParentNode.TankInfo.Rot);

            Vector2 curToTargetVec    = targetPos - curSearchNode.TankInfo.Pos;
            Vector2 parentToTargetVec = targetPos - curSearchNode.ParentNode.TankInfo.Pos;

            float curAngleDiff    = Vector2.SignedAngle(curFireVec, curToTargetVec);
            float parentAngleDiff = Vector2.SignedAngle(parentFireVec, parentToTargetVec);

            bool curFacing = Mathf.Abs(curAngleDiff) < 90f;

            if (curFacing && Mathf.Sign(curAngleDiff) != Mathf.Sign(parentAngleDiff) && curToTargetVec.magnitude < range && parentToTargetVec.magnitude < range)
            {
                crossedTarget = true;
                break;
            }

            curSearchNode = curSearchNode.ParentNode;
        }

        return(crossedTarget);
    }
Esempio n. 2
0
    public void PopulateTree(Tank tank, Map map, float searchTime, float timeStep, List <TreeSearchMoveInfo> possibleMoves)
    {
        root = new LookaheadNode(null, new Vector2(), false, tank.StateInfo, 0, new List <Node>());

        float elapsedTime = 0;
        List <LookaheadNode> nodesToPopulate = new List <LookaheadNode>();

        nodesToPopulate.Add(root);
        while (elapsedTime <= searchTime)
        {
            elapsedTime += timeStep;

            List <LookaheadNode> populatedChildren = new List <LookaheadNode>();
            foreach (LookaheadNode node in nodesToPopulate)
            {
                node.PopulateChildren(map, timeStep, possibleMoves);
                foreach (LookaheadNode childNode in node.ChildNodes)
                {
                    populatedChildren.Add(childNode);
                }
            }

            nodesToPopulate = populatedChildren;
        }
    }
Esempio n. 3
0
 public LookaheadNode(LookaheadNode parentNode, Vector2 incomingDir, bool incomingWasJet, TankStateInfo stateInfo, float elapsedTimeFromParent, List <Node> passedNodes)
 {
     ParentNode            = parentNode;
     IncomingDir           = incomingDir;
     IncomingWasJet        = incomingWasJet;
     TankInfo              = stateInfo;
     ElapsedTimeFromParent = elapsedTimeFromParent;
     PassedNodes           = passedNodes;
     ChildNodes            = new List <LookaheadNode>();
 }
Esempio n. 4
0
    public LookaheadNode GetNodeOneStepAfterRoot()
    {
        LookaheadNode curNode = this;

        while (curNode.ParentNode.ParentNode != null)
        {
            curNode = curNode.ParentNode;
        }

        return(curNode);
    }
Esempio n. 5
0
    public override AIAction[] CalcActionsToPerform()
    {
        Tank selfTank   = controller.SelfTank;
        Tank targetTank = controller.TargetTank;
        Map  map        = controller.Map;

        List <TreeSearchMoveInfo> possibleMoves = new List <TreeSearchMoveInfo>();

        possibleMoves.Add(new TreeSearchMoveInfo(new Vector2(0, 1), true));
        possibleMoves.Add(new TreeSearchMoveInfo(new Vector2(0, -1), true));
        possibleMoves.Add(new TreeSearchMoveInfo(new Vector2(0, 1).Rotate(90f), true));
        possibleMoves.Add(new TreeSearchMoveInfo(new Vector2(0, 1).Rotate(-90f), true));

        LookaheadTree tree = new LookaheadTree();

        tree.PopulateTree(selfTank, map, LookaheadTime, LookaheadTimeStep, possibleMoves);

        List <LookaheadNode> possibleNodes = tree.FindAllNodesAtSearchTime(LookaheadTime);

        possibleNodes = AIUtility.FilterByPathNotObstructed(possibleNodes);

        possibleNodes = AIUtility.FilterByDestNotObstructed(possibleNodes, map);

        possibleNodes = AIUtility.FilterByPassingBullet(possibleNodes, map);

        possibleNodes = AIUtility.FilterByAwayFromWall(possibleNodes, selfTank.StateInfo);

        LookaheadNode bestNode = null;
        float         bestCost = 0;

        foreach (LookaheadNode node in possibleNodes)
        {
            WeaponPart notUsed;
            int        targetTime = AIUtility.CalcMinTimeForAimerToHitAimee(targetTank.StateInfo, node.TankInfo, targetTank.Hull.GetAllWeapons(), out notUsed);
            int        selfTime   = AIUtility.CalcMinTimeForAimerToHitAimee(node.TankInfo, targetTank.StateInfo, selfTank.Hull.GetAllWeapons(), out notUsed);

            float cost = targetTime - selfTime;

            if (bestNode == null || bestCost < cost)
            {
                bestNode = node;
                bestCost = cost;
            }
        }

        timeSinceLastJet = Time.time;

        List <AIAction> actions = new List <AIAction>();

        actions.Add(new JetInDirAction(bestNode.IncomingDir, controller));

        return(actions.ToArray());
    }
Esempio n. 6
0
    public override AIAction[] CalcActionsToPerform()
    {
        List <AIAction> actions = new List <AIAction>();

        Map map = controller.Map;

        elapsedTimeSinceLastUpdate += Time.deltaTime;

        if (elapsedTimeSinceLastUpdate >= UpdatePeriod)
        {
            LookaheadNode requestNode = pickDirToPursue();

            forwardVecWhenUpdate = controller.SelfTank.GetForwardVec();
            prevMoveDir          = requestNode.IncomingDir;
            prevMoveIsJet        = requestNode.IncomingWasJet;

            elapsedTimeSinceLastUpdate = 0;
        }

        if (prevMoveIsJet)
        {
            if (elapsedTimeSinceLastUpdate == 0)
            {
                actions.Add(new JetInDirAction(prevMoveDir, controller));

                CombatDebugHandler.Instance.RegisterObject("maneuver_move_dir", prevMoveDir);
            }
        }
        else
        {
            float angleDiffSinceUpdate = Vector2.SignedAngle(forwardVecWhenUpdate, controller.SelfTank.GetForwardVec());
            actions.Add(new GoInDirAction(prevMoveDir.Rotate(angleDiffSinceUpdate), controller));

            CombatDebugHandler.Instance.RegisterObject("maneuver_move_dir", prevMoveDir.Rotate(angleDiffSinceUpdate));
        }

        return(actions.ToArray());
    }
Esempio n. 7
0
    void OnDrawGizmos()
    {
        if (Application.isPlaying && Application.isEditor)
        {
            Color origColor = Gizmos.color;

            if (basicTankInfoDebugOn)
            {
                Tank       aiTank = CombatHandler.Instance.AITankController.SelfTank;
                WeaponPart part   = aiTank.Hull.GetAllWeapons()[0];

                Gizmos.color = Color.red;
                Gizmos.DrawLine(
                    part.CalculateFirePos(),
                    part.CalculateFirePos() + part.CalculateFireVec() * 50f);

                Gizmos.color = Color.green;
                Gizmos.DrawLine(
                    aiTank.transform.position,
                    (Vector2)aiTank.transform.position + aiTank.GetForwardVec() * 50f);

                Gizmos.color = Color.blue;
                Gizmos.DrawLine(
                    aiTank.transform.position,
                    (Vector2)aiTank.transform.position + aiTank.GetBackwardVec() * 50f);
            }

            if (moveTestDebugOn)
            {
                Gizmos.color = Color.green;

                Gizmos.DrawWireSphere(targetPosForMoveTest, 20);
            }

            if (actuationDebugOn)
            {
                Tank aiTank = CombatHandler.Instance.AITankController.SelfTank;

                object obj = getRegisterdObj("actuation_arc_vectors");
                if (obj != null)
                {
                    List <Vector2> arcVectors = (List <Vector2>)obj;

                    Gizmos.color = Color.green;
                    Gizmos.DrawLine(aiTank.transform.position, aiTank.transform.position + (Vector3)arcVectors[0] * 50f);
                    Gizmos.DrawLine(aiTank.transform.position, aiTank.transform.position + (Vector3)arcVectors[1] * 50f);

                    Gizmos.color = Color.blue;
                    Gizmos.DrawLine(aiTank.transform.position, aiTank.transform.position + (Vector3)arcVectors[2] * 50f);
                    Gizmos.DrawLine(aiTank.transform.position, aiTank.transform.position + (Vector3)arcVectors[3] * 50f);
                }

                Vector2 size       = aiTank.Hull.Schematic.Size;
                Vector2 forwardVec = aiTank.GetForwardVec();
                Vector2 leftVec    = forwardVec.Rotate(90);
                Vector2 rightVec   = forwardVec.Rotate(-90);

                Vector3 leftWheelPos  = (Vector2)aiTank.transform.position + leftVec * size.x / 2f;
                Vector3 rightWheelPos = (Vector2)aiTank.transform.position + rightVec * size.x / 2f;

                Gizmos.color = Color.magenta;
                Gizmos.DrawLine(leftWheelPos, leftWheelPos + ((Vector3)forwardVec * 100 * aiTank.Hull.LeftCurPower));
                Gizmos.DrawLine(rightWheelPos, rightWheelPos + ((Vector3)forwardVec * 100 * aiTank.Hull.RightCurPower));
            }

            Goal curGoal = (Goal)getRegisterdObj("goal");

            if (mapDisplayDebugOn)
            {
                // Draw Map
                Map map = CombatHandler.Instance.AITankController.Map;
                for (int x = 0; x < map.Cols; ++x)
                {
                    for (int y = 0; y < map.Rows; ++y)
                    {
                        bool    blocked = !map.GetNodeAtIdx(x, y).NodeTraversable();
                        Vector2 pos     = map.IdxToPosition(x, y);

                        Gizmos.color = !blocked ? Color.green : Color.red;
                        Gizmos.DrawWireCube(pos, new Vector3(map.TileDim, map.TileDim, map.TileDim));
                    }
                }
            }

            if (maneuverGoalDebugOn && curGoal != null && curGoal.GetType() == typeof(ManeuverGoal))
            {
                if (maneuverCurMoveDir)
                {
                    object obj = getRegisterdObj("maneuver_move_dir");
                    if (obj != null)
                    {
                        Vector2 vec    = (Vector2)obj;
                        Tank    aiTank = CombatHandler.Instance.AITankController.SelfTank;

                        Gizmos.color = Color.green;
                        Gizmos.DrawLine(aiTank.transform.position, (Vector2)aiTank.transform.position + vec.normalized * 50f);
                    }
                }

                if (maneuverNodesAtSearchTime)
                {
                    object obj = getRegisterdObj("maneuver_nodes_at_searchtime");
                    if (obj != null)
                    {
                        List <LookaheadNode> nodeList = (List <LookaheadNode>)obj;

                        Gizmos.color = Color.green;
                        foreach (LookaheadNode node in nodeList)
                        {
                            Gizmos.DrawWireSphere(node.TankInfo.Pos, 20);
                        }
                    }
                }

                if (maneuverPathNotObstructedFilter)
                {
                    object obj = getRegisterdObj("maneuver_path_unobstructed_filter");
                    if (obj != null)
                    {
                        List <LookaheadNode> nodeList = (List <LookaheadNode>)obj;

                        Gizmos.color = Color.green;
                        foreach (LookaheadNode node in nodeList)
                        {
                            Gizmos.DrawWireSphere(node.TankInfo.Pos, 20);
                        }
                    }
                }

                if (maneuverDestNotObstructedFilter)
                {
                    object obj = getRegisterdObj("maneuver_dest_not_obstructed_filter");
                    if (obj != null)
                    {
                        List <LookaheadNode> nodeList = (List <LookaheadNode>)obj;

                        Gizmos.color = Color.green;
                        foreach (LookaheadNode node in nodeList)
                        {
                            Gizmos.DrawWireSphere(node.TankInfo.Pos, 20);
                        }
                    }
                }

                if (maneuverBulletFilter)
                {
                    object obj = getRegisterdObj("maneuver_bullet_filter");
                    if (obj != null)
                    {
                        List <LookaheadNode> nodeList = (List <LookaheadNode>)obj;

                        Gizmos.color = Color.green;
                        foreach (LookaheadNode node in nodeList)
                        {
                            Gizmos.DrawWireSphere(node.TankInfo.Pos, 20);
                        }
                    }
                }

                if (maneuverAwayFromWallFilter)
                {
                    object obj = getRegisterdObj("maneuver_away_from_wall_filter");
                    if (obj != null)
                    {
                        List <LookaheadNode> nodeList = (List <LookaheadNode>)obj;

                        Gizmos.color = Color.green;
                        foreach (LookaheadNode node in nodeList)
                        {
                            Gizmos.DrawWireSphere(node.TankInfo.Pos, 20);
                        }
                    }
                }

                if (maneuverRunawayNodes)
                {
                    object obj = getRegisterdObj("maneuver_runaway_cost_infos");
                    if (obj != null)
                    {
                        List <ManeuverGoal.CostInfo> infos = (List <ManeuverGoal.CostInfo>)obj;

                        float maxCost = infos.Max(c => c.Cost);

                        foreach (ManeuverGoal.CostInfo info in infos)
                        {
                            Gizmos.color = new Color(info.Cost / maxCost, 0, 1f - info.Cost / maxCost);
                            Gizmos.DrawWireSphere(info.Node.TankInfo.Pos, 20);
                        }
                    }
                }

                if (maneuverGoingforItNode)
                {
                    object obj = getRegisterdObj("maneuver_going_cost_infos");
                    if (obj != null)
                    {
                        List <ManeuverGoal.CostInfo> infos = (List <ManeuverGoal.CostInfo>)obj;

                        float maxCost = infos.Max(c => c.Cost);

                        foreach (ManeuverGoal.CostInfo info in infos)
                        {
                            Gizmos.color = new Color(info.Cost / maxCost, 0, 1f - info.Cost / maxCost);
                            Gizmos.DrawWireSphere(info.Node.TankInfo.Pos, 20);
                        }
                    }
                }

                if (maneuverBestNode)
                {
                    object obj = getRegisterdObj("maneuver_best_node");
                    if (obj != null)
                    {
                        LookaheadNode node = (LookaheadNode)obj;

                        Gizmos.color = Color.green;
                        Gizmos.DrawWireSphere(node.TankInfo.Pos, 20);
                    }
                }
            }


            if (predictFutureDebugOn)
            {
                object obj = getRegisterdObj("test_future_pos_lis");
                if (obj != null)
                {
                    List <Vector2> posList = (List <Vector2>)obj;

                    Gizmos.color = Color.green;
                    foreach (Vector2 pos in posList)
                    {
                        Gizmos.DrawWireSphere(pos, 20);
                    }
                }
            }

            if (displayAITankRange)
            {
                Tank tank = CombatHandler.Instance.AITankController.SelfTank;

                WeaponPart maxRangeWeapon = null;
                foreach (WeaponPart part in tank.Hull.GetAllWeapons())
                {
                    if (maxRangeWeapon == null || maxRangeWeapon.Schematic.Range < part.Schematic.Range)
                    {
                        maxRangeWeapon = part;
                    }
                }

                Gizmos.color = Color.green;
                Gizmos.DrawWireSphere(tank.transform.position, maxRangeWeapon.Schematic.Range);
            }

            Gizmos.color = origColor;
        }
    }
Esempio n. 8
0
 public CostInfo(LookaheadNode node, int cost)
 {
     Node = node;
     Cost = cost;
 }
Esempio n. 9
0
    private LookaheadNode goingForItBehaviour(List <LookaheadNode> possibleNodes)
    {
        Tank selfTank   = controller.SelfTank;
        Tank targetTank = controller.TargetTank;

        List <CostInfo> nodeCosts = new List <CostInfo>();

        bool        overlapNodeExists = false;
        Vector2     diffVec           = targetTank.transform.position - selfTank.transform.position;
        List <bool> overlaps          = new List <bool>();

        foreach (LookaheadNode node in possibleNodes)
        {
            bool nodeOverlaps = false;
            foreach (WeaponPart part in selfTank.Hull.GetAllWeapons())
            {
                if (node.HasOverlappedTargetWithWeapon(targetTank.transform.position, part))
                {
                    overlapNodeExists = true;
                    nodeOverlaps      = true;
                    break;
                }
            }

            overlaps.Add(nodeOverlaps);
        }
        Debug.Assert(possibleNodes.Count == overlaps.Count, "Possible nodes and overlap count don't match. Should never happen");

        for (int i = 0; i < possibleNodes.Count; ++i)
        {
            LookaheadNode node = possibleNodes[i];

            WeaponPart notUsed;
            int        targetTime = AIUtility.CalcMinTimeForAimerToHitAimee(targetTank.StateInfo, node.TankInfo, targetTank.Hull.GetAllWeapons(), out notUsed);
            int        selfTime   = AIUtility.CalcMinTimeForAimerToHitAimee(node.TankInfo, targetTank.StateInfo, selfTank.Hull.GetAllWeapons(), out notUsed);

            int cost = targetTime - selfTime;

            bool overlapCondition = true;
            if (overlapNodeExists)
            {
                overlapCondition = overlaps[i];
            }

            if (overlapCondition)
            {
                nodeCosts.Add(new CostInfo(node, cost));
            }
        }

        CombatDebugHandler.Instance.RegisterObject("maneuver_going_cost_infos", nodeCosts);

        CostInfo bestInfo = null;

        foreach (CostInfo info in nodeCosts)
        {
            if (bestInfo == null || info.Cost > bestInfo.Cost)
            {
                bestInfo = info;
            }
        }

        bestInfo = handleSameCostCostInfos(bestInfo, nodeCosts);

        CombatDebugHandler.Instance.RegisterObject("maneuver_best_node", bestInfo.Node);

        return(bestInfo.Node.GetNodeOneStepAfterRoot());
    }