Improved Sector Map
Added Boss Icon Added Home Icon Added Legend Placing bosses at chokepoints Adjusted home zone placement Added per-faction areas of influence
This commit is contained in:
parent
f10804ac11
commit
7f3f198f61
29 changed files with 2936 additions and 308 deletions
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DataStructures.ViliWonka.Heap;
|
||||
using Unity.Mathematics;
|
||||
using JM.LinqFaster;
|
||||
using static Unity.Mathematics.math;
|
||||
|
|
@ -7,10 +9,21 @@ using static Unity.Mathematics.math;
|
|||
public class Sector
|
||||
{
|
||||
public List<SectorZone> Zones = new List<SectorZone>();
|
||||
public Dictionary<MegaCorporation, SectorZone> OccupantSources = new Dictionary<MegaCorporation, SectorZone>();
|
||||
public Dictionary<MegaCorporation, SectorZone> HomeZones = new Dictionary<MegaCorporation, SectorZone>();
|
||||
public Dictionary<MegaCorporation, SectorZone> BossZones = new Dictionary<MegaCorporation, SectorZone>();
|
||||
public SectorZone Entrance;
|
||||
public SectorZone Exit;
|
||||
|
||||
|
||||
private SectorZone[] _exitPath;
|
||||
|
||||
public SectorZone[] ExitPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return _exitPath ??= FindPath(Entrance, Exit);
|
||||
}
|
||||
}
|
||||
|
||||
class DijkstraVertex
|
||||
{
|
||||
public float Cost;
|
||||
|
|
@ -18,30 +31,29 @@ public class Sector
|
|||
public SectorZone Zone;
|
||||
}
|
||||
|
||||
public List<SectorZone> ConnectedRegion(SectorZone v, SectorZone ignoreZone = null)
|
||||
{
|
||||
List<SectorZone> members = new List<SectorZone>();
|
||||
members.Add(v);
|
||||
while (true)
|
||||
{
|
||||
var lastCount = members.Count;
|
||||
// For each member, add all vertices that are connected to it but are not already a member
|
||||
// Also, if there is a zone being ignored, do not traverse across it
|
||||
foreach (SectorZone m in members.ToArray())
|
||||
members.AddRange(m.AdjacentZones
|
||||
.Where(z => !members.Contains(z) && !(m == v && ignoreZone == z)));
|
||||
// If we have stopped finding neighbors, stop traversing
|
||||
if (members.Count == lastCount)
|
||||
return members;
|
||||
}
|
||||
}
|
||||
// public HashSet<SectorZone> ConnectedRegion(SectorZone v, SectorZone ignoreZone = null)
|
||||
// {
|
||||
// var members = new HashSet<SectorZone> {v};
|
||||
// while (true)
|
||||
// {
|
||||
// var lastCount = members.Count;
|
||||
// // For each member, add all vertices that are connected to it but are not already a member
|
||||
// // Also, if there is a zone being ignored, do not traverse across it
|
||||
// foreach (var zone in members.ToArray())
|
||||
// foreach(var adjacentZone in zone.AdjacentZones)
|
||||
// if (!members.Contains(adjacentZone) && !(zone == v && ignoreZone == adjacentZone))
|
||||
// members.Add(adjacentZone);
|
||||
// // If we have stopped finding neighbors, stop traversing
|
||||
// if (members.Count == lastCount)
|
||||
// return members;
|
||||
// }
|
||||
// }
|
||||
|
||||
//public int TotalDistance(SectorZone v) => ConnectedRegionDistance(v).Sum(x => x.distance);
|
||||
|
||||
public Dictionary<SectorZone, int> ConnectedRegionDistance(SectorZone v)
|
||||
{
|
||||
Dictionary<SectorZone, int> members = new Dictionary<SectorZone, int>();
|
||||
members.Add(v,0);
|
||||
var members = new Dictionary<SectorZone, int> {{v, 0}};
|
||||
int cost = 1;
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -60,31 +72,83 @@ public class Sector
|
|||
cost++;
|
||||
}
|
||||
}
|
||||
|
||||
public List<SectorZone> FindPath(SectorZone source, SectorZone target, bool bestFirst = false)
|
||||
|
||||
public HashSet<SectorZone> ConnectedRegion(
|
||||
SectorZone v,
|
||||
SectorZone ignoreLink1,
|
||||
SectorZone ignoreLink2,
|
||||
int maxDistance = int.MaxValue)
|
||||
{
|
||||
SortedList<float,DijkstraVertex> members = new SortedList<float,DijkstraVertex>{{0, new DijkstraVertex{Zone = source}}};
|
||||
List<DijkstraVertex> searched = new List<DijkstraVertex>();
|
||||
return ConnectedRegion(v, x => x.Item1 != ignoreLink1 || x.Item2 != ignoreLink2, maxDistance);
|
||||
}
|
||||
|
||||
public HashSet<SectorZone> ConnectedRegion(
|
||||
SectorZone v,
|
||||
SectorZone ignoreZone,
|
||||
int maxDistance = int.MaxValue)
|
||||
{
|
||||
return ConnectedRegion(v, x => x.Item2 != ignoreZone, maxDistance);
|
||||
}
|
||||
|
||||
public HashSet<SectorZone> ConnectedRegion(
|
||||
SectorZone v,
|
||||
int maxDistance = int.MaxValue)
|
||||
{
|
||||
return ConnectedRegion(v, x => true, maxDistance);
|
||||
}
|
||||
|
||||
public HashSet<SectorZone> ConnectedRegion(
|
||||
SectorZone v,
|
||||
Predicate<(SectorZone,SectorZone)> linkFilter,
|
||||
int maxDistance = int.MaxValue)
|
||||
{
|
||||
var visited = new HashSet<SectorZone> {v};
|
||||
int cost = 1;
|
||||
while (true)
|
||||
{
|
||||
var s = members.FirstOrDefault(m => !searched.Contains(m.Value)).Value; // Lowest cost unsearched node
|
||||
if (s == null) return null; // No vertices left unsearched
|
||||
var lastCount = visited.Count;
|
||||
// For each member, add all nodes that are connected to it but have not been visited
|
||||
// Also, if there is a zone being ignored, do not traverse across it
|
||||
foreach (var zone in visited.ToArray())
|
||||
foreach (var adjacentZone in zone.AdjacentZones)
|
||||
{
|
||||
if(!visited.Contains(adjacentZone) && linkFilter((zone, adjacentZone)))
|
||||
visited.Add(adjacentZone);
|
||||
}
|
||||
// If we have stopped finding neighbors, stop traversing
|
||||
if (visited.Count == lastCount || cost == maxDistance)
|
||||
return visited;
|
||||
cost++;
|
||||
}
|
||||
}
|
||||
|
||||
public SectorZone[] FindPath(SectorZone source, SectorZone target, bool bestFirst = false)
|
||||
{
|
||||
MinHeap<DijkstraVertex> unsearchedNodes = new MinHeap<DijkstraVertex>();
|
||||
unsearchedNodes.PushObj(new DijkstraVertex{Zone = source}, 0);
|
||||
//SortedList<float,DijkstraVertex> members = new SortedList<float,DijkstraVertex>{{0, new DijkstraVertex{Zone = source}}};
|
||||
var searched = new HashSet<SectorZone>();
|
||||
while (true)
|
||||
{
|
||||
if(unsearchedNodes.Count == 0) return null; // No nodes left unsearched
|
||||
var s = unsearchedNodes.PopObj(); // Lowest cost unsearched node
|
||||
if (s.Zone == target) // We found the path
|
||||
{
|
||||
Stack<DijkstraVertex> path = new Stack<DijkstraVertex>(); // Since we start at the end, use a LIFO collection
|
||||
path.Push(s);
|
||||
while(path.Peek().Parent!=null) // Keep pushing until we reach the start, which has no parent
|
||||
path.Push(path.Peek().Parent);
|
||||
return path.Select(dv => dv.Zone).ToList();
|
||||
return path.Select(dv => dv.Zone).ToArray();
|
||||
}
|
||||
// For each adjacent star (filter already visited stars unless heuristic is in use)
|
||||
foreach (var dijkstraStar in s.Zone.AdjacentZones
|
||||
.WhereSelectF(zone => !bestFirst || members.All(m => m.Value.Zone != zone),
|
||||
IEnumerable<SectorZone> zonesToSearch = s.Zone.AdjacentZones;
|
||||
if (!bestFirst) zonesToSearch = zonesToSearch.Where(z => !searched.Contains(z));
|
||||
foreach (var dijkstraStar in zonesToSearch
|
||||
// Cost is parent cost plus distance squared
|
||||
zone => new DijkstraVertex {Parent = s, Zone = zone, Cost = s.Cost + lengthsq(s.Zone.Position - zone.Position)}))
|
||||
.Select(zone => new DijkstraVertex {Parent = s, Zone = zone, Cost = s.Cost + lengthsq(s.Zone.Position - zone.Position)}))
|
||||
// Add new member to list, sorted by cost plus optional heuristic
|
||||
members.Add(bestFirst ? dijkstraStar.Cost + lengthsq(dijkstraStar.Zone.Position - target.Position) : dijkstraStar.Cost, dijkstraStar);
|
||||
searched.Add(s);
|
||||
unsearchedNodes.PushObj(dijkstraStar, bestFirst ? dijkstraStar.Cost + lengthsq(dijkstraStar.Zone.Position - target.Position) : dijkstraStar.Cost);
|
||||
searched.Add(s.Zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -96,5 +160,7 @@ public class SectorZone
|
|||
public List<SectorZone> AdjacentZones = new List<SectorZone>();
|
||||
public int Isolation;
|
||||
public Dictionary<SectorZone, int> Distance;
|
||||
public MegaCorporation[] Occupants;
|
||||
public MegaCorporation[] Megas;
|
||||
//public List<MegaCorporation> Megas;
|
||||
public MegaCorporation Owner;
|
||||
}
|
||||
Loading…
Reference in a new issue