//Add node based on the indexing of the typeOfNode, will determine what kind of node spawn at each index. //Insert the appropriate list of integers to spawn the appropriate node types for each node. protected void GenerateInitPlanet(GraphGenerator generator, List <int> nodeTypes, int numberOfNodes, float scale) { listOfNodes = new List <PlanetNode>(); listOfLinks = new List <PlanetLink>(); GraphGenerator.GraphData graphData = generator.Generate(numberOfNodes, scale, containerForBoth.transform.position); for (int i = 0; i < graphData.nodes.Count; i++) { if (i > nodeTypes.Count - 1) { break; } GameObject obj = Instantiate(typeOfNode[nodeTypes[i]], graphData.nodes[i], graphData.nodes_rot[i], containerForNodes.transform); PlanetNode node = obj.GetComponent <PlanetNode>(); node.index = i; listOfNodes.Add(node); } for (int i = 0; i < graphData.links.Count; i += 2) { //Will definetly have no direction links because i said so. if (!graphData.isLinksDirectional) { GameObject obj = Instantiate(typeOfLink, Vector3.zero, Quaternion.identity, containerForLinks.transform); PlanetLink link = obj.GetComponent <PlanetLink>(); int index1 = graphData.links[i]; int index2 = graphData.links[i + 1]; link.nodePrev = listOfNodes[index1]; link.nodeNext = listOfNodes[index2]; link.PlaceLinkAtNodes(); listOfLinks.Add(link); } } }
List <PlanetNode> GetPlanetRegionNodes(PlanetNode planetNode) { List <PlanetNode> regionNodes = new List <PlanetNode>(); if (!planetNodes.ContainsKey(new Vector2Int(planetNode.Q, planetNode.R))) { return(regionNodes); } HashSet <PlanetNode> visitedNodes = new HashSet <PlanetNode>(); Queue <PlanetNode> queue = new Queue <PlanetNode>(); queue.Enqueue(planetNode); visitedNodes.Add(planetNode); while (queue.Count > 0) { PlanetNode curNode = queue.Dequeue(); regionNodes.Add(curNode); foreach (PlanetNode neighbour in curNode.getNeighbours()) { if (!visitedNodes.Contains(neighbour)) { visitedNodes.Add(neighbour); queue.Enqueue(neighbour); } } } return(regionNodes); }
public void GenerateLandmarks(PlanetNode planet, EffectivePlanetSize effectivePlanetSize) { foreach (Territory territory in Territories) { territory.GenerateLandmarks(planet, effectivePlanetSize); } }
void CreatePlanetNode(int x, int y, Vector3 pos) { GameObject g = Instantiate(hexagon, pos, Quaternion.identity); g.transform.parent = nodeHolder; g.name = "Node_" + x + "_" + y; PlanetNode planetNode = new PlanetNode(x, y, pos, g); nodes[new Vector2Int(x, y)] = planetNode; planetNodes[new Vector2Int(x, y)] = planetNode; }
public void ChangeSelection(PlanetNode node) { if (isCursorActive) { currentSelectedNode = node; if (OnSelectionChange != null) { OnSelectionChange.Invoke(node); } UpdateSelectionUI(); } }
void SelectNode(PlanetNode node) { if (selectedNode1 == null) { selectedNode1 = node; } else if (selectedNode2 == null) { selectedNode2 = node; isSelectionDone = true; } }
public void GenerateLandmarks(PlanetNode planet, EffectivePlanetSize effectivePlanetSize) { if (planet == null) { throw new Exception("Tried to generate landmarks without a valid planet"); } int numLandmarks = Globals.RollD5(); if (effectivePlanetSize == EffectivePlanetSize.Large) { numLandmarks += 2; } else if (effectivePlanetSize == EffectivePlanetSize.Vast) { numLandmarks += 3; } for (int i = 0; i < numLandmarks; i++) { int randValue = Globals.RollD100(); if (randValue <= 20) { LandmarkCanyon++; } else if (randValue <= 35) { LandmarkCaveNetwork++; } else if (randValue <= 45) { LandmarkCrater++; } else if (randValue <= 65) { LandmarkMountain++; } else if (randValue <= 75) { LandmarkVolcano++; } else { if (!GenerateExceptionalLandmark(planet)) { i--; } } } }
private void AddXenosClick(object sender, RoutedEventArgs e) { var node = GetSelectedNode() as NativeSpeciesNode; PlanetNode planet = node?.Parent as PlanetNode; if (planet != null) { XenosNode xenos = new XenosNode(planet.WorldType, false, node.SystemCreationRules) { Parent = node }; node.Children.Add(xenos); xenos.Generate(); node.Dirty = true; } }
public List <WorldType> GetWorldTypesForNotableSpecies(PlanetNode planet) { List <WorldType> worldTypes = new List <WorldType>(); foreach (Territory territory in Territories) { WorldType territoryType = WorldType.TemperateWorld; /* * DeathWorld, * DesertWorld, * IceWorld, * JungleWorld, * OceanWorld, * TemperateWorld, * VolcanicWorld, */ if (territory.BaseTerrain == TerritoryBaseTerrain.Wasteland) { if (territory.TerritoryTraitExtremeTemperature > 0) { if (planet.ClimateType == ClimateTypes.ColdWorld) { territoryType = WorldType.IceWorld; } if (planet.ClimateType == ClimateTypes.HotWorld) { territoryType = WorldType.DesertWorld; } } } if (territory.BaseTerrain == TerritoryBaseTerrain.Forest) { if (planet.ClimateType == ClimateTypes.HotWorld || planet.ClimateType == ClimateTypes.BurningWorld || (planet.ClimateType == ClimateTypes.TemperateWorld && territory.TerritoryTraitExtremeTemperature > 0)) { territoryType = WorldType.JungleWorld; } } worldTypes.Add(territoryType); } return(worldTypes); }
void RemoveNode(Node node) { //We don't really remove the 'node' but we make the node to a blanknode Vector2Int key = new Vector2Int(node.Q, node.R); if (!nodes.ContainsKey(key)) { return; } if (node is PlanetNode) { PlanetNode planetNode = node as PlanetNode; nodes.TryRemove(key, out _); planetNodes.TryRemove(key, out _); Destroy(planetNode.gameObject); CreateBlankNode(key.x, key.y, planetNode.worldPos); } }
IEnumerator WaitForNodeSelection() { if (GM.player.numOfBridges <= 0) { PushMessage("You have ran out of links!"); yield break; } isSelectionDone = false; ChangeInteractableAllButtons(false); button_cancelBuildLink.gameObject.SetActive(true); OnSelectionChange += SelectNode; ShowExtraInfo("You are now building a link. Click on 2 nodes (the little box buttons) to establish the link."); while (!isSelectionDone) { yield return(null); } if (!isLinkBuildingCancel) { GM.planet.MakeLink(selectedNode1.index, selectedNode2.index); GM.player.numOfBridges--; selectedNode1 = null; selectedNode2 = null; } else { isLinkBuildingCancel = false; } HideExtraInfo(); UpdatePlayerStatsUI(); CheckForLinkExistence(GM.player.currentNodeIndex); ChangeInteractableAllButtons(true); button_cancelBuildLink.gameObject.SetActive(false); OnSelectionChange -= SelectNode; isSelectionDone = true; }
public new List <PlanetNode> getNeighbours() { List <PlanetNode> neightbours = new List <PlanetNode>(); PlanetNode W = getNeighbor(HexDirection.W); PlanetNode NW = getNeighbor(HexDirection.NW); PlanetNode NE = getNeighbor(HexDirection.NE); PlanetNode E = getNeighbor(HexDirection.E); PlanetNode SE = getNeighbor(HexDirection.SE); PlanetNode SW = getNeighbor(HexDirection.SW); if (W != null) { neightbours.Add(W); } if (NW != null) { neightbours.Add(NW); } if (NE != null) { neightbours.Add(NE); } if (E != null) { neightbours.Add(E); } if (SE != null) { neightbours.Add(SE); } if (SW != null) { neightbours.Add(SW); } return(neightbours); }
public static void DrawGizmoForMyScript(PlanetNode planetNode, GizmoType gizmoType) { Handles.color = Color.yellow; Handles.Label(planetNode.transform.position, planetNode.gameObject.name); }
private void CheckNodeObjects(SystemObject obj) { var currentParent = ExtractParents(obj); if (currentParent.Ring.HasValue) { var parentnode = _nodes.Where(m => m.BodyId == currentParent.Ring).FirstOrDefault(); var childnode = _nodes.Where(m => m.BodyId == obj.Id).FirstOrDefault(); if (parentnode == null) { parentnode = new RingNode(currentParent.Ring.Value); _nodes.Add(parentnode); } if (childnode == null) { childnode = SystemNode.CreateNodeFromObject(obj); _nodes.Add(childnode); } parentnode.ChildList.Add(childnode); childnode.ParentList.Add(parentnode); UpdateStarsystemMap?.Invoke(childnode); return; } if (currentParent.Planet.HasValue) { var parentnode = _nodes.Where(m => m.BodyId == currentParent.Planet).FirstOrDefault(); var childnode = _nodes.Where(m => m.BodyId == obj.Id).FirstOrDefault(); if (parentnode == null) { parentnode = new PlanetNode(currentParent.Planet.Value); _nodes.Add(parentnode); } if (childnode == null) { childnode = SystemNode.CreateNodeFromObject(obj); _nodes.Add(childnode); } parentnode.ChildList.Add(childnode); childnode.ParentList.Add(parentnode); UpdateStarsystemMap?.Invoke(childnode); return; } if (currentParent.Star.HasValue) { var parentnode = _nodes.Where(m => m.BodyId == currentParent.Star).FirstOrDefault(); var childnode = _nodes.Where(m => m.BodyId == obj.Id).FirstOrDefault(); if (parentnode == null) { parentnode = new StarNode(currentParent.Star.Value); _nodes.Add(parentnode); } if (childnode == null) { childnode = SystemNode.CreateNodeFromObject(obj); _nodes.Add(childnode); } parentnode.ChildList.Add(childnode); childnode.ParentList.Add(parentnode); UpdateStarsystemMap?.Invoke(childnode); return; } if (currentParent.Null.HasValue) { var parentnode = _nodes.Where(m => m.BodyId == currentParent.Null).FirstOrDefault(); var childnode = _nodes.Where(m => m.BodyId == obj.Id).FirstOrDefault(); if (parentnode == null) { parentnode = new BarycenterNode(currentParent.Null.Value); _nodes.Add(parentnode); } if (childnode == null) { childnode = SystemNode.CreateNodeFromObject(obj); _nodes.Add(childnode); } parentnode.ChildList.Add(childnode); childnode.ParentList.Add(parentnode); UpdateStarsystemMap?.Invoke(childnode); return; } }
private bool GenerateExceptionalLandmark(PlanetNode planet) { for (int i = 0; i < 5; i++) // Safety measure in case of impossible conditions, and to reroll if chances are plain bad { int chance = 0; switch (Globals.RollD5()) { case 1: // Glacier switch (planet.ClimateType) { case ClimateTypes.BurningWorld: chance -= 100; break; case ClimateTypes.HotWorld: chance -= 20; break; case ClimateTypes.TemperateWorld: chance += 10; break; case ClimateTypes.ColdWorld: chance += 50; break; case ClimateTypes.IceWorld: chance += 100; break; default: throw new ArgumentOutOfRangeException(); } if (BaseTerrain == TerritoryBaseTerrain.Mountain) { chance += 25; } chance += TerritoryTraitExtremeTemperature * 15; if (Globals.RollD100() <= chance) { LandmarkGlacier++; return(true); } break; case 2: // Inland Sea chance = 50; if (BaseTerrain == TerritoryBaseTerrain.Mountain) { chance -= 50; } if (BaseTerrain == TerritoryBaseTerrain.Wasteland) { chance -= 60; } if (planet.ClimateType == ClimateTypes.BurningWorld) { chance -= 100; } if (planet.ClimateType == ClimateTypes.HotWorld) { chance -= 40; } chance += TerritoryTraitExpansive * 15; chance += TerritoryTraitFertile * 35; chance -= TerritoryTraitStagnant * 30; if (Globals.RollD100() <= chance) { LandmarkInlandSea++; return(true); } break; case 3: // Perpetual Storm if (planet.AtmosphereType == AtmosphereTypes.None || planet.AtmosphereType == AtmosphereTypes.Thin) { continue; } chance = 30; if (planet.AtmosphereType == AtmosphereTypes.Heavy) { chance += 25; } if (planet.ClimateType == ClimateTypes.IceWorld) { chance += 20; } if (planet.ClimateType == ClimateTypes.BurningWorld) { chance += 20; } if (planet.ClimateType == ClimateTypes.ColdWorld) { chance += 10; } if (planet.ClimateType == ClimateTypes.HotWorld) { chance += 10; } chance += TerritoryTraitBoundary * 20; chance += TerritoryTraitDesolate * 10; chance += TerritoryTraitExtremeTemperature * 15; chance -= TerritoryTraitFertile * 15; chance -= TerritoryTraitNotableSpecies * 10; chance += TerritoryTraitRuined * 50; chance -= TerritoryTraitStagnant * 20; if (Globals.RollD100() <= chance) { LandmarkPerpetualStorm++; return(true); } break; case 4: // Reef chance = 50; if (planet.ClimateType == ClimateTypes.BurningWorld) { chance -= 50; } if (BaseTerrain == TerritoryBaseTerrain.Mountain) { chance -= 40; } if (BaseTerrain == TerritoryBaseTerrain.Wasteland) { chance -= 40; } if (Globals.RollD100() <= chance) { LandmarkReef++; return(true); } break; case 5: // Whirlpool chance = 50; if (planet.ClimateType == ClimateTypes.BurningWorld) { chance -= 50; } if (BaseTerrain == TerritoryBaseTerrain.Mountain) { chance -= 40; } if (BaseTerrain == TerritoryBaseTerrain.Wasteland) { chance -= 40; } if (planet.GetNumOrbitalFeatures() < 2) { chance -= 45; } else { chance += (planet.GetNumOrbitalFeatures() - 2) * 50; } if (Globals.RollD100() <= chance) { LandmarkWhirlpool++; return(true); } break; } } return(false); }
public NodeData(PlanetNode planetNode) { this.planetNode = planetNode; }
public void FindPath(PathRequest request, Action <PathResult> callback) { Stopwatch sw = new Stopwatch(); sw.Start(); Dictionary <Vector2Int, NodeData> nodeData = new Dictionary <Vector2Int, NodeData>(); Node[] waypoints = new Node[0]; bool pathSuccess = false; Heap <NodeData> openSet = new Heap <NodeData>(10); HashSet <NodeData> closedSet = new HashSet <NodeData>(); HashSet <Vector2Int> targetCoords = new HashSet <Vector2Int>(); PlanetNode targetNode = null; foreach (PlanetNode n in request.targetPos) { if (!targetCoords.Contains(n.Coord)) { PlanetNode cur; if (World.planetNodes.TryGetValue(n.Coord, out cur)) { if (targetNode == null) { targetNode = cur; } targetCoords.Add(n.Coord); } } } if (targetCoords.Count == 0) { if (showDebugInfo) { print("PF: No targetNode is a planetNode " + request.startPos); } callback(new PathResult(waypoints, pathSuccess, request.callback)); return; } PlanetNode startNode; if (!World.planetNodes.TryGetValue(request.startPos.Coord, out startNode)) { if (showDebugInfo) { print("PF: startPos not in planetPointPointer: " + request.startPos); } callback(new PathResult(waypoints, pathSuccess, request.callback)); return; } NodeData startNodeData = new NodeData(startNode); nodeData.Add(startNode.Coord, startNodeData); if (targetCoords.Contains(request.startPos.Coord)) { if (showDebugInfo) { print("PF: Already on the correct node: " + request.startPos); } waypoints = new Node[1]; waypoints[0] = startNode; callback(new PathResult(waypoints, true, request.callback)); return; } openSet.Add(startNodeData); while (openSet.Count > 0) { NodeData currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (targetCoords.Contains(currentNode.planetNode.Coord)) { sw.Stop(); if (showDebugInfo) { print("Path found: " + sw.ElapsedMilliseconds + " ms"); } targetNode = currentNode.planetNode; pathSuccess = true; break; } foreach (PlanetNode n in currentNode.planetNode.getNeighbours()) { Vector2Int neighbourKey = new Vector2Int(n.Q, n.R); NodeData neighbour = null; if (nodeData.ContainsKey(neighbourKey)) { neighbour = nodeData[neighbourKey]; if (closedSet.Contains(neighbour)) { continue; } } else { nodeData[neighbourKey] = new NodeData(n); neighbour = nodeData[neighbourKey]; } int newMovementCostToNeighbour; if (request.useWeights) { newMovementCostToNeighbour = currentNode.gCost + currentNode.planetNode.distanceTo(neighbour.planetNode) + neighbour.planetNode.movementPenalty; } else { newMovementCostToNeighbour = currentNode.gCost + currentNode.planetNode.distanceTo(neighbour.planetNode); } if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = neighbour.planetNode.distanceTo(targetNode); neighbour.parent = currentNode.planetNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } if (pathSuccess) { waypoints = RetracePath(startNode, targetNode, nodeData); pathSuccess = waypoints.Length > 0; } callback(new PathResult(waypoints, pathSuccess, request.callback)); }