Ejemplo n.º 1
0
    public void CreatePathBetweenNodes(SettlementPathNode firstNode, int secondNodeDirection, int width, int length = -1)
    {
        SettlementPathNode second = firstNode.Connected[secondNodeDirection];

        if (second == null)
        {
            Debug.Error("Paths are not connected");
            return;
        }

        Vec2i pathDiff         = second.Position - firstNode.Position; //Find the vector that describes first->second
        int   pathDiffLen      = pathDiff.x + pathDiff.z;              //Vector should have only 1 component, so total length can be written as sum
        int   startPointOffset = pathDiffLen / 4;
        int   startPoint       = MiscMaths.RandomRange(startPointOffset, pathDiffLen - startPointOffset);

        //Generate node between two existing nodes
        SettlementPathNode interPathNode = new SettlementPathNode(firstNode.Position + SettlementPathNode.GetDirection(secondNodeDirection) * startPoint);
        int oppositeDir = SettlementPathNode.OppositeDirection(secondNodeDirection);

        //TestNodes.Add(interPathNode);
        //Update connections
        firstNode.AddConnection(secondNodeDirection, interPathNode);
        interPathNode.AddConnection(oppositeDir, firstNode);
        second.AddConnection(oppositeDir, interPathNode);
        interPathNode.AddConnection(secondNodeDirection, second);
        CreatePathFromNode(interPathNode, width, length: length);
    }
Ejemplo n.º 2
0
    public void GenerateKingdomSettlementBases(Kingdom kingdom)
    {
        KingdomSettlements[kingdom] = new List <SettlementBase>(100);
        AddSettlementBaseToKingdom(kingdom, new SettlementBase(kingdom.CapitalChunk, 8, SettlementType.CAPITAL));

        int kingdomSize = KingdomChunks[kingdom].Count;
        //int cityCount = 1;
        //int townCount = 1;
        //int villageCount = 1;
        int cityCount    = MiscMaths.RandomRange(2, 3);
        int townCount    = MiscMaths.RandomRange(7, 9);
        int villageCount = MiscMaths.RandomRange(18, 25);

        if (kingdomSize > 400)
        {
            //   cityCount++;
            //   townCount += MiscMaths.RandomRange(1, 3);
            //  villageCount += MiscMaths.RandomRange(1, 8);
        }
        int distMult = 4;

        for (int i = 0; i < cityCount; i++)
        {
            Vec2i c = FindSpace(kingdom, 6 * distMult);
            if (c == null)
            {
                continue;
            }
            AddSettlementBaseToKingdom(kingdom, new SettlementBase(c, 6, SettlementType.CITY));
        }
        for (int i = 0; i < townCount; i++)
        {
            Vec2i c = FindSpace(kingdom, 4 * distMult);
            if (c == null)
            {
                continue;
            }
            AddSettlementBaseToKingdom(kingdom, new SettlementBase(c, 4, SettlementType.TOWN));
        }
        for (int i = 0; i < villageCount; i++)
        {
            Vec2i c = FindSpace(kingdom, 3 * distMult);
            if (c == null)
            {
                continue;
            }
            AddSettlementBaseToKingdom(kingdom, new SettlementBase(c, 3, SettlementType.VILLAGE));
        }

        /*
         * Vec2i city1 = FindSpace(kingdom, 12);
         * AddSettlementBaseToKingdom(kingdom, new SettlementBase(city1, 6, SettlementType.CITY));
         * Vec2i city2 = FindSpace(kingdom, 12);
         * AddSettlementBaseToKingdom(kingdom, new SettlementBase(city2, 6, SettlementType.CITY));*/
    }
Ejemplo n.º 3
0
    void SlowWorldTick()
    {
        List <LoadedProjectile> toRem = new List <LoadedProjectile>();

        foreach (LoadedProjectile p in LoadedProjectiles)
        {
            if (!MiscMaths.WithinDistance(p.transform.position, Player.Position, 40))
            {
                toRem.Add(p);
            }
        }
        foreach (LoadedProjectile proj in toRem)
        {
            LoadedProjectiles.Remove(proj);
            Destroy(proj.gameObject);
        }
    }
        public static string GetRandomAltString(int length, int seed)
        {
            var s    = "";
            var rand = new System.Random(seed);

            for (var i = 0; i < length; i++)
            {
                if (MiscMaths.IsOdd(i))
                {
                    s += NUMERIC[rand.Next(NUMERIC.Length)];
                }
                else
                {
                    s += ALPHA[rand.Next(ALPHA.Length)];
                }
            }

            return(s);
        }
        public static string GetRandomString(string characters, int length, int seed)
        {
            var s    = "";
            var rand = new System.Random(seed);

            for (var i = 0; i < length; i++)
            {
                if (MiscMaths.IsOdd(i))
                {
                    s += characters[rand.Next(characters.Length)];
                }
                else
                {
                    s += characters[rand.Next(characters.Length)];
                }
            }

            return(s);
        }
Ejemplo n.º 6
0
    public static Vec2i AddEntrance(Building b, int entranceSide, int disp = -1)
    {
        if (disp == -1)
        {
            //If entrance is facing z axis, displacement in in x
            if (entranceSide == NORTH_ENTRANCE || entranceSide == SOUTH_ENTRANCE)
            {
                disp = MiscMaths.RandomRange(1, b.Width - 1);
            }
            else
            {
                disp = MiscMaths.RandomRange(1, b.Height - 1);
            }
        }

        Vec2i entrance = null;

        if (entranceSide == NORTH_ENTRANCE)
        {
            entrance = new Vec2i(disp, b.Height - 1);
        }
        else if (entranceSide == SOUTH_ENTRANCE)
        {
            entrance = new Vec2i(disp, 0);
        }
        else if (entranceSide == EAST_ENTRANCE)
        {
            entrance = new Vec2i(b.Width - 1, disp);
        }
        else if (entranceSide == WEST_ENTRANCE)
        {
            entrance = new Vec2i(0, disp);
        }
        b.BuildingObjects[entrance.x, entrance.z] = null; //TODO - Set to door of correct type

        return(entrance);
    }
Ejemplo n.º 7
0
    /// <summary>
    /// Generates the world.
    /// Initiates a <see cref="TerrainGenerator"/> & generates the base Terrain <see cref="TerrainGenerator.GenerateBaseTerrain"/>
    /// Then Initiates a <see cref="KingdomsGenerator"/> that generates all the kingdoms, as well as claiming all their territory
    /// Then generates terrain details using <see cref="TerrainGenerator.GenerateWorldDetailTerrain"/>
    /// Finally, generates all settlements using <see cref="KingdomsGenerator.GenerateAllKingdomSettlements"/>
    ///
    /// TODO - Add dungeon generation, add settlement details generation (roads + paths)
    /// </summary>
    /// <returns></returns>
    public void GenerateWorld(WorldManager wm)
    {
        //Set Random init state based on seed
        Random.InitState(Seed);
        MiscMaths.SetRandomSeed(Seed);
        //Initiate empty world and generate base terrain
        World = new World();
        wm.SetWorld(World);

        //Create a default RNG to be used by the generators (Not thread safe)
        MainGenerator = new GenerationRandom(Seed);
        //Generation starts
        TerrainGenerator = new TerrainGenerator(this, World);
        RiverGenerator   = new RiverGenerator(this);
        LakeGenerator    = new LakeGenerator(this);


        Debug.BeginDeepProfile("chunk_base_gen");

        TerrainGenerator.GenerateChunkBases();//Generate the chunk bases, these only define if they are land or sea.

        //Generates fine terrain details: rivers, lakes, (todo - marshes, more variety to forrests?)
        TerrainGenerator.GenerateTerrainDetails();

        Debug.EndDeepProfile("chunk_base_gen");



        //TODO - check if this is still required (probably not)
        ChunkGenerator = new ChunkGenerator(this);



        Debug.BeginDeepProfile("kingdom_set_gen");
        //We then generate empty kingdoms based on these empty chunks
        KingdomsGenerator kingGen = new KingdomsGenerator(World, this);

        //We also generate the all empty settlements for the world.
        kingGen.GenerateEmptyKingdomsFromBaseChunks(4);
        //Generates all settlement chunks
        PreGeneratedChunks = kingGen.GenerateSettlements();

        Debug.EndDeepProfile("kingdom_set_gen");


        Debug.BeginDeepProfile("chunk_struct_gen");
        //Generate chunk structures (bandit camps, etc)
        StructureGenerator = new ChunkStructureGenerator(this);
        StructureGenerator.GenerateStructureShells();

        //Iterate all chunks generated for chunk structures, add them to the PreGeneratedChunks
        foreach (KeyValuePair <Vec2i, ChunkData> kvp in StructureGenerator.GenerateAllStructures())
        {
            PreGeneratedChunks.Add(kvp.Key, kvp.Value);
        }
        Debug.EndDeepProfile("chunk_struct_gen");


        Debug.BeginDeepProfile("terrain_map_gen");
        //Create a simple map based on the terrain of the world
        GenerateTerrainMap(TerrainGenerator.ChunkBases);
        Debug.EndDeepProfile("terrain_map_gen");
    }
Ejemplo n.º 8
0
    /// <summary>
    /// Takes a building plan and generates a full building from it.
    /// TODO - Currently messy, fix
    /// </summary>
    /// <param name="plan"></param>
    /// <param name="width"></param>
    /// <param name="height"></param>
    /// <param name="entrance"></param>
    /// <returns></returns>
    public static Building CreateBuilding(BuildingPlan plan, int width = -1, int height = -1, int entrance = 0)
    {
        if (width == -1)
        {
            width = MiscMaths.RandomRange(plan.MinSize, plan.MaxSize);
        }
        else if (width < plan.MinSize)
        {
            width = plan.MinSize;
        }
        else if (width > plan.MaxSize)
        {
            width = plan.MaxSize;
        }

        if (height == -1)
        {
            height = MiscMaths.RandomRange(plan.MinSize, plan.MaxSize);
        }
        else if (height < plan.MinSize)
        {
            height = plan.MinSize;
        }
        else if (height > plan.MaxSize)
        {
            height = plan.MaxSize;
        }

        Tile[,] buildingBase = new Tile[width, height];
        WorldObjectData[,] buildingObjects = new WorldObjectData[width, height];

        if (plan == Building.HOUSE)
        {
            House h = new House(width, height);
            h.SetBuilding(buildingBase, buildingObjects);
            return(GenerateHouse(h, BuildingStyle.stone));
        }
        if (plan == Building.BLACKSMITH)
        {
            Blacksmith b = new Blacksmith(width, height);
            b.SetBuilding(buildingBase, buildingObjects);
            return(GenerateBlacksmith(b, BuildingStyle.stone));
        }
        if (plan == Building.MARKET)
        {
            MarketPlace market = new MarketPlace(width, height);
            market.SetBuilding(buildingBase, buildingObjects);
            return(GenerateMarket(market, BuildingStyle.stone));
        }
        if (plan == Building.BARACKS)
        {
            Baracks baracks = new Baracks(width, height);
            baracks.SetBuilding(buildingBase, buildingObjects);
            return(GenerateBaracks(baracks));
        }

        /*
         * if(plan == Building.MARKET)
         * {
         *  MarketPlace market = new MarketPlace(width, height);
         *  market.SetBuilding(buildingBase, buildingObjects);
         *  return GenerateMarket(market, BuildingStyle.stone);
         * }
         * if(plan == Building.BARACKSCITY)
         * {
         *  Baracks bar = new Baracks(width, height);
         *  bar.SetBuilding(buildingBase, buildingObjects);
         *  return GenerateCityBaracks(bar);
         * }
         * if (plan == Building.BARACKSCITY || plan == Building.BARACKSTOWN)
         * {
         *
         * }*/

        //Default for now
        House ht = new House(width, height);

        ht.SetBuilding(buildingBase, buildingObjects);
        return(GenerateHouse(ht, BuildingStyle.stone));
    }
Ejemplo n.º 9
0
    /// <summary>
    /// Generates the basic walls, floor, and entrance for any building.
    /// Picks the exact position of entrance, and returns it
    /// </summary>
    /// <param name="width"></param>
    /// <param name="height"></param>
    /// <param name="buildingObjects">Building objects to be filled with walls</param>
    /// <param name="buildTiles"></param>
    /// <param name="entranceID"></param>
    /// <param name="style"></param>
    /// <returns></returns>
    public static Vec2i GenerateWallsFloorAndEntrance(int width, int height, WorldObjectData[,] buildingObjects,
                                                      Tile[,] buildTiles, int entranceID, BuildingStyle style, int entraceDis = -1, WorldObjectData wallType = null, Tile tileType = null)
    {
        int entWidth = 2;

        if (entraceDis == -1)
        {
            if (entranceID == NORTH_ENTRANCE || entranceID == SOUTH_ENTRANCE)
            {
                entraceDis = MiscMaths.RandomRange(1, width - 1);
            }
            else
            {
                entraceDis = MiscMaths.RandomRange(1, height - 1);
            }
        }

        //Decide the position of the entrance
        Vec2i entrance = null;

        if (entranceID == NORTH_ENTRANCE)
        {
            entrance = new Vec2i(entraceDis, height - 1);
        }
        else if (entranceID == SOUTH_ENTRANCE)
        {
            entrance = new Vec2i(entraceDis, 0);
        }
        else if (entranceID == EAST_ENTRANCE)
        {
            entrance = new Vec2i(width - 1, entraceDis);
        }
        else if (entranceID == WEST_ENTRANCE)
        {
            entrance = new Vec2i(0, entraceDis);
        }


        //Assign correct wall type if none given
        if (wallType == null)
        {
            switch (style)
            {
            case BuildingStyle.stone:
                wallType = new BrickWall(new Vec2i(0, 0));
                break;

            case BuildingStyle.wood:
                //TODO - Add
                wallType = new BrickWall(new Vec2i(0, 0));
                break;
            }
        }//Asign correct tile type if none given
        if (tileType == null)
        {
            switch (style)
            {
            case BuildingStyle.stone:
                tileType = Tile.STONE_FLOOR;
                break;

            case BuildingStyle.wood:
                tileType = Tile.WOOD_FLOOR;
                break;
            }
        }
        //Iterate all points
        for (int x = 0; x < width; x++)
        {
            for (int z = 0; z < height; z++)
            {
                //Asign tile
                buildTiles[x, z] = tileType;
                if (x == 0 || x == width - 1 || z == 0 || z == height - 1)
                {
                    //Asign wall if no entrance
                    if (!(entrance.x == x & entrance.z == z))
                    {
                        if (x == 3)
                        {
                            buildingObjects[x, z] = new BuildingWall(new Vec2i(0, 0), "brick", 5,
                                                                     new GlassWindow(new Vec2i(0, 0), new Vec2i(0, 1)), 2);
                        }
                        else
                        {
                            buildingObjects[x, z] = new BuildingWall(new Vec2i(0, -1), "brick", 5);
                        }
                    }
                }
            }
        }
        //(buildingObjects[0, 0] as BuildingWall).AddRoof(new Roof(new Vec2i(0, 0), new Vec2i(width, height)));

        return(entrance);
    }
Ejemplo n.º 10
0
    /// <summary>
    /// Physics update for the entity
    ///
    /// </summary>
    private void FixedUpdate()
    {
        //RigidBody.angularVelocity = Vector3.zero;
        if (GameManager.Paused)
        {
            return;
        }
        if (IsIdle)
        {
            return;
        }



        Debug.BeginDeepProfile("le_fixed_update");

        if (!(Entity is Player))
        {
            DebugGUI.Instance.SetData("ent", GameManager.Paused + "_" + IsIdle + "_" + MoveDirection);
            if (MiscMaths.DistanceSqr(transform.position, GameManager.PlayerManager.Player.Position) > (World.ChunkSize * 4) * (World.ChunkSize * 4))
            {
                IsIdle = true;
            }
        }

        EntityHealthBar.SetHealthPct(Entity.CombatManager.CurrentHealth / Entity.CombatManager.MaxHealth);

        if (transform.position.y < 0)
        {
            transform.position = new Vector3(transform.position.x, 0, transform.position.z);
        }

        Vec2i cPos = World.GetChunkPosition(transform.position);

        //Check if the current chunk is loaded
        if (!GameManager.WorldManager.CRManager.IsCurrentChunkPositionLoaded(cPos))
        {
            //If not, keep position dixed with +ve y value, to prevent falling through world.
            transform.position = new Vector3(transform.position.x, 1, transform.position.z);
        }



        //If we have a specified move direction
        if (MoveDirection != Vector2.zero)
        {
            float tileSpeed = 1; //TODO - get tile speed
            //Finds correct speed associated with running/walking for this entity
            float entitySpeed = IsRunning?Entity.MovementData.RunSpeed:Entity.MovementData.WalkSpeed;

            AnimationManager.SetSpeedPercentage(entitySpeed / Entity.MovementData.RunSpeed);

            Vector2 v2Pos      = new Vector2(transform.position.x, transform.position.z);
            Vector2 targetDisp = TargetPosition - v2Pos;
            float   targetMag  = targetDisp.magnitude;
            Vector3 vel        = new Vector3(MoveDirection.x, 0, MoveDirection.y) * tileSpeed * entitySpeed;
            RigidBody.velocity = new Vector3(MoveDirection.x, 0, MoveDirection.y) * tileSpeed * entitySpeed;

            //If the distance the body will move in a frame (|velocity|*dt) is more than the desired amount (target mag)
            //Then we must scale the velocity down
            if (RigidBody.velocity.magnitude * Time.fixedDeltaTime > targetMag)
            {
                RigidBody.velocity = RigidBody.velocity * targetMag / (Time.fixedDeltaTime * RigidBody.velocity.magnitude);
            }


            if (Entity is Player)
            {
                DebugGUI.Instance.SetData("Vel", RigidBody.velocity + " | " + vel);
            }
        }
        else
        {
            AnimationManager.SetSpeedPercentage(0);
        }
        //If we have a specified look direction
        if (LookTowards != Vector3.zero)
        {
            float      angle = Vector3.SignedAngle(Vector3.forward, LookTowards - transform.position, Vector3.up);
            Quaternion quat  = Quaternion.Euler(new Vector3(0, angle, 0));
            transform.rotation = Quaternion.Slerp(transform.rotation, quat, Time.fixedDeltaTime * LOOK_ROTATION_SPEED);
            Entity.SetLookAngle(transform.rotation.eulerAngles.y);
        }

        //Check if we are on the ground
        bool IsOnGround = OnGround();

        //Debug info for player Jumping
        if (Entity is Player)
        {
            DebugGUI.Instance.SetData("jump_vel", VerticalVelocity);
            DebugGUI.Instance.SetData("onGround", IsOnGround);
            DebugGUI.Instance.SetData("isJumping", IsJumping);
            DebugGUI.Instance.SetData("isFalling", IsFalling);
        }

        //Check if we are off the ground
        if (!IsOnGround)
        {
            //If so, update vertical position and velocity accordingly
            VerticalVelocity   -= 9.81f * Time.fixedDeltaTime;
            transform.position += Vector3.up * VerticalVelocity * Time.fixedDeltaTime;
            //Next, if we are off the ground but not jumping, it must mean we're falling
            if (!IsJumping)
            {
                //If not currently falling, set it to true
                if (!IsFalling)
                {
                    IsFalling = true;
                    AnimationManager.SetFalling();
                }
            }
        }
        else if (VerticalVelocity > 0)
        {
            //If we are on the ground, but our velocity is positive, we must be jumping
            VerticalVelocity   -= 9.81f * Time.fixedDeltaTime;
            transform.position += Vector3.up * VerticalVelocity * Time.fixedDeltaTime;
        }
        else if ((IsJumping || IsFalling) && !IsWaitingForJump)
        {
            //If we are on the ground, but still jumping or falling, set both to false. reset velocity
            IsJumping        = false;
            VerticalVelocity = 0;
            IsFalling        = false;
            //Then play the land animation
            AnimationManager.LandJump();
        }

        //Reset variables
        LookTowards   = Vector3.zero;
        MoveDirection = Vector2.zero;
        Entity.SetPosition(transform.position);

        Debug.EndDeepProfile("le_fixed_update");

        return;
    }