Example #1
0
    //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;
    }
Example #5
0
 public void ChangeSelection(PlanetNode node)
 {
     if (isCursorActive)
     {
         currentSelectedNode = node;
         if (OnSelectionChange != null)
         {
             OnSelectionChange.Invoke(node);
         }
         UpdateSelectionUI();
     }
 }
Example #6
0
 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--;
                    }
                }
            }
        }
Example #8
0
        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);
        }
Example #10
0
    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);
        }
    }
Example #11
0
    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;
    }
Example #12
0
    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);
    }
Example #13
0
 public static void DrawGizmoForMyScript(PlanetNode planetNode, GizmoType gizmoType)
 {
     Handles.color = Color.yellow;
     Handles.Label(planetNode.transform.position, planetNode.gameObject.name);
 }
Example #14
0
        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));
    }