예제 #1
0
    static bool CanMoveTo(Vector2Int prev, Vector2Int cur, State goer, bool lastCell)
    {
        Region reg     = MapMetrics.GetRegion(cur),
               prevreg = MapMetrics.GetRegion(prev);

        if (reg.iswater != prevreg.iswater)
        {
            return(false);
        }
        State s = reg.ocptby == null ? reg.owner : reg.ocptby;

        if (goer == s)
        {
            return(true);
        }
        if (s == null)
        {
            return(true);
        }
        if (!lastCell && reg.Capital == cur)
        {
            return(false);
        }
        Army army = Army.ArmyInPoint(cur);

        if (army != null && !goer.diplomacy.haveWar(army?.owner.diplomacy))
        {
            return(false);
        }

        return(goer.diplomacy.canMove(s.diplomacy) || prevreg.owner == s);
    }
예제 #2
0
    public static void CalculateTownCollide(NavAgent agent)
    {
        Vector2 p = agent.pos;

        Vector2Int cell   = NavAgent.ToInt(p);
        Region     region = agent.lastCollidedTown;

        bool Collide()
        {
            if ((region.pos - p).sqrMagnitude < townRadiusSqr)
            {
                if (region.curOwner == agent.owner)
                {
                    agent.InTown = true;
                    return(true);
                }
                Vector2 n = (p - region.pos);
                agent.CollideForce += n.normalized * (1f - n.sqrMagnitude / townRadiusSqr);

                return(true);
            }
            return(false);
        }

        if (region != null)
        {
            if (Collide())
            {
                return;
            }
        }
        region = MapMetrics.GetRegion(cell);
        if (region.Capital == cell)
        {
            if (Collide())
            {
                return;
            }
        }
        foreach (var d in MapMetrics.OctoDelta)
        {
            if ((region = MapMetrics.GetRegion(cell + d))?.Capital == cell + d)
            {
                if (Collide())
                {
                    return;
                }
            }
        }
        agent.InTown           = false;
        agent.lastCollidedTown = null;
    }
예제 #3
0
    public static bool isPossibleMove(Vector2Int from, Vector2Int to, State goer)
    {
        Region startRegion = MapMetrics.GetRegion(from);
        Region endRegion   = MapMetrics.GetRegion(to);

        if (startRegion == endRegion)
        {
            return(true);
        }
        else if (startRegion.Continent != endRegion.Continent)
        {
            return(false);
        }

        attended.Clear();
        visitedRegions.Clear();

        attended.Enqueue(startRegion);
        visitedRegions.Add(startRegion);

        while (attended.Count != 0)
        {
            Region invest = attended.Dequeue();

            foreach (var neib in invest.neib)
            {
                if (neib.iswater)
                {
                    continue;
                }
                if (neib == endRegion)
                {
                    return(goer == neib.curOwner || goer.diplomacy.canMove(neib.curOwner.diplomacy));
                }
                if (!visitedRegions.Contains(neib) && (goer == neib.curOwner || goer.diplomacy.canMove(neib.curOwner.diplomacy)))
                {
                    attended.Enqueue(neib);
                    visitedRegions.Add(neib);
                }
            }
        }

        return(false);
    }
예제 #4
0
    public static List <Vector2Int> FindPath(Vector2Int from, Vector2Int to, State goer)
    {
        if (MapMetrics.GetRegion(from).Continent != MapMetrics.GetRegion(to).Continent)
        {
            return(null);
        }
        Node prev = new Node(Heuristic(from, to), from), next;

        distantion[from.y, from.x] = 0;
        Vector2Int pos;

        pq.Enqueue(prev);
        float dnext = 1000, dprev = CellMoveCost(from), dist;
        bool  find = false;

        while (pq.Count != 0)
        {
            prev = pq.Dequeue();
            used.Enqueue(prev.pos);
            if (prev.pos == to)
            {
                find = true;
                break;
            }
            dprev = CellMoveCost(prev.pos);
            for (int i = 0; i < 8; i++)
            {
                pos  = new Vector2Int(dx[i], dy[i]) + prev.pos;
                next = new Node(Heuristic(prev.pos, pos), pos);

                if (MapMetrics.InsideMap(pos.y, pos.x) && (dnext = CellMoveCost(pos)) < 100 && CanMoveTo(prev.pos, pos, goer, pos == to))
                {
                    dist = distantion[prev.pos.y, prev.pos.x] + ((i & 1) == 0 ? 0.5f : 0.7f) * (dnext + dprev);
                    if (distantion[pos.y, pos.x] >= 0 && distantion[pos.y, pos.x] <= dist)
                    {
                        continue;
                    }
                    if (distantion[pos.y, pos.x] < 0 || distantion[pos.y, pos.x] > dist)
                    {
                        if (distantion[pos.y, pos.x] < 0)
                        {
                            pq.Enqueue(new Node(Heuristic(prev.pos, next.pos) + dist, next.pos));
                        }
                        distantion[pos.y, pos.x] = dist;
                        parent[pos.y, pos.x]     = prev.pos;
                    }
                }
            }
        }

        List <Vector2Int> path = null;

        if (find)
        {
            path = ListPool <Vector2Int> .Get();

            while (from != to)
            {
                path.Add(to);
                to = parent[to.y, to.x];
            }
            //path.Add(to);without fromPoint
            path.Reverse();
        }
        while (used.Count != 0)
        {
            pos = used.Dequeue();
            distantion[pos.y, pos.x] = -1;
        }
        while (pq.Count != 0)
        {
            pos = pq.Dequeue().pos;
            distantion[pos.y, pos.x] = -1;
        }
        return(path);
    }