// Code to run when used by a player
        public override void Use(Player p, string message)
        {
            if (message != "")
            {
                string[] parameters = message.Split(' '); // Grab the parameters from the player's message
                if (parameters.Length == 5) // make sure there are 5 params
                {
                    switch (parameters[4])
                    {
                        case "flat":
                        case "pixel":
                        case "island":
                        case "mountains":
                        case "ocean":
                        case "forest":

                            break;

                        default:
                            p.SendMessage("Valid types: island, mountains, forest, ocean, flat, pixel"); return;
                    }

                    string name = parameters[0];
                    // create a new level...
                    try
                    {
                        Level lvl = new Level(name,
                                              Convert.ToUInt16(parameters[1]),
                                              Convert.ToUInt16(parameters[2]),
                                              Convert.ToUInt16(parameters[3]),
                                              parameters[4]);
                        lvl.changed = true;
                    }
                    finally
                    {
                        GC.Collect();
                        GC.WaitForPendingFinalizers();

                    }
                    Player.GlobalMessage("Level " + name + " created");
                }
                else
                {
                    p.SendMessage("Not enough parameters! <name> <x> <y> <z> <type>");
                }
            }
            else
            {
                Help(p);
            }
            if (Properties.ValidString(message, " "))
            {

            }
            else
            {
                p.SendMessage("Please use an alphanumerical characters only!");
            }
        }
 //return true if tree is near
 private bool TreeCheck(Level Lvl, ushort x, ushort z, ushort y, short dist)
 {
     for (short xx = (short)-dist; xx <= +dist; ++xx)
     {
         for (short yy = (short)-dist; yy <= +dist; ++yy)
         {
             for (short zz = (short)-dist; zz <= +dist; ++zz)
             {
                 if (Lvl.GetTile((ushort)(x + xx), (ushort)(z + zz ), (ushort)(y + yy)) == Block.trunk)
                 {
                     return true;
                 }
             }
         }
     }
     return false;
 }
        //Forces the edge of a map to slope lower for island map types
        float NegateEdge(ushort x, ushort y, Level Lvl)
        {
            float tempx = 0.0f, tempy = 0.0f;
            float temp;
            if (x != 0) { tempx = ((float)x / (float)Lvl.width) * 0.5f; }
            if (y != 0) { tempy = ((float)y / (float)Lvl.height) * 0.5f; }
            tempx = Math.Abs(tempx - 0.25f);
            tempy = Math.Abs(tempy - 0.25f);
            if (tempx > tempy)
            {
                temp = tempx - 0.15f;
            }
            else
            {
                temp = tempy - 0.15f;
            }

            //s.Log("temp = " + temp.ToString());
            if (temp > 0.0f) { return temp; }
            return 0.0f;
        }
 //returns the valve of a x,y terrain coordinate
 float GetPixel(ushort x, ushort y, Level Lvl)
 {
     if (x < 0) { return 0.0f; }
     if (x >= Lvl.width) { return 0.0f; }
     if (y < 0) { return 0.0f; }
     if (y >= Lvl.height) { return 0.0f;}
     divide += 1.0f;
     return terrain[x + y * Lvl.width];
 }
        //Averages over 9 points
        float GetAverage9(ushort x, ushort y, Level Lvl)
        {
            divide = 0.0f;
            float temp = GetPixel(x, y, Lvl);
            temp += GetPixel((ushort)(x + 1), y, Lvl);
            temp += GetPixel((ushort)(x - 1), y, Lvl);
            temp += GetPixel(x, (ushort)(y + 1), Lvl);
            temp += GetPixel(x, (ushort)(y - 1), Lvl);

            temp += GetPixel((ushort)(x + 1), (ushort)(y + 1), Lvl);
            temp += GetPixel((ushort)(x - 1), (ushort)(y + 1), Lvl);
            temp += GetPixel((ushort)(x + 1), (ushort)(y - 1), Lvl);
            temp += GetPixel((ushort)(x - 1), (ushort)(y - 1), Lvl);

            return temp / divide;
        }
 void GeneratePerlinNoise(float[] array, Level Lvl, string type, Random rand)
 {
     GenerateNormalized(array, 0.7f, 8, Lvl.width, Lvl.height, rand.Next(), 64);
 }
        public bool GenerateMap(Level Lvl, string type)
        {
            Logger.Log("Attemping to generate a map. Type: " + type);
            if (Inuse)
            {
                Logger.Log("Generator in use", LogType.Warning);
                return false;
            }

            Random rand = new System.Random();
            try
            {
                Inuse = true;
                terrain = new float[Lvl.width * Lvl.height];
                overlay = new float[Lvl.width * Lvl.height];

                if (!type.Equals("ocean"))
                { overlay2 = new float[Lvl.width * Lvl.height]; }

                //float dispAux, pd;
                ushort WaterLevel = (ushort)(Lvl.depth / 2 + 2);

                if (type.Equals("ocean"))
                {
                    WaterLevel = (ushort)(Lvl.depth * 0.85f);
                }

                //Generate the level
                GenerateFault(terrain, Lvl, type, rand);

                //APPLY FILTER to terrain
                FilterAverage(Lvl);

                //CREATE OVERLAY
                //GenerateFault(overlay, Lvl, "overlay", rand);
                Logger.Log("Creating overlay", LogType.Debug);
                GeneratePerlinNoise(overlay, Lvl, "", rand);

                if (!type.Equals("ocean"))
                {
                    Logger.Log("Planning trees", LogType.Debug);
                    GeneratePerlinNoise(overlay2, Lvl, "", rand);
                }

                Logger.Log("Converting height map", LogType.Debug);
                Logger.Log("And applying overlays", LogType.Debug);
                float RangeLow = 0.2f;
                float RangeHigh = 0.8f;
                float TreeDens = 0.35f;
                short TreeDist = 3;
                //changes the terrain range based on type, also tree threshold
                switch(type)
                {
                    case "island":
                        RangeLow = 0.4f;
                        RangeHigh = 0.75f;
                        break;
                    case "forest":
                        RangeLow = 0.45f;
                        RangeHigh = 0.8f;
                        TreeDens = 0.7f;
                        TreeDist = 2;
                        break;
                    case "mountains":
                        RangeLow = 0.3f;
                        RangeHigh = 0.9f;
                        TreeDist = 4;
                        break;
                    case "ocean":
                        RangeLow = 0.1f;
                        RangeHigh = 0.6f;
                        break;
                    default:
                        break;
                }

                //loops though evey X/Z coordinate
                for ( int bb = 0; bb < terrain.Length; bb++)
                {
                    ushort x = (ushort)(bb % Lvl.width);
                    ushort y = (ushort)(bb / Lvl.width);
                    ushort z;
                    if (type.Equals("island"))  //apply the edge dip
                    {
                        z = Evaluate(Lvl, Range(terrain[bb], RangeLow - NegateEdge(x, y, Lvl), RangeHigh - NegateEdge(x, y, Lvl)));
                    }
                    else
                    {
                        z = Evaluate(Lvl, Range(terrain[bb], RangeLow, RangeHigh));
                    }
                    if (z > WaterLevel)
                    {
                        for (ushort zz = 0; z - zz >= 0; zz++)
                        {
                            if (overlay[bb] < 0.72f)    //If not zoned for rocks or gravel
                            {
                                if (type.Equals("island"))      //increase sand height for island
                                {
                                    if (z > WaterLevel + 2)
                                    {
                                        if (zz == 0) { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.grass); }      //top layer
                                        else if (zz < 3) { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.dirt); }   //next few
                                        else { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.rock); }               //ten rock it
                                    }
                                    else
                                    {
                                        Lvl.Blockchange(x, (ushort)(z - zz), y, Block.sand);                        //SAAAND extra for islands
                                    }
                                }
                                else
                                {
                                    if (zz == 0) { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.grass); }
                                    else if (zz < 3) { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.dirt); }
                                    else { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.rock); }
                                }
                            }
                            else
                            {
                                Lvl.Blockchange(x, (ushort)(z - zz), y, Block.rock);    //zoned for above sea level rock floor
                            }
                        }

                        if (overlay[bb] < 0.25f)    //Zoned for flowers
                        {
                            int temprand = rand.Next(12);

                            switch (temprand)
                            {
                                case 10:
                                    Lvl.Blockchange(x, (ushort)(z + 1), y, Block.redflower);
                                    break;
                                case 11:
                                    Lvl.Blockchange(x, (ushort)(z + 1), y, Block.yellowflower);
                                    break;
                                default:
                                    break;
                            }
                        }

                        if (!type.Equals("ocean"))  //Oceans dont have trees
                        {
                            if (overlay[bb] < 0.65f && overlay2[bb] < TreeDens) //If not a rock zoned area and is zoned for possible trees
                            {
                                if (Lvl.GetTile(x, (ushort)(z + 1), y) == Block.air)    //No flowers here right?
                                {
                                    if (Lvl.GetTile(x, z, y) == Block.grass)    //Im not on sand am I either?
                                    {
                                        if (rand.Next(13) == 0)
                                        {
                                            if (!TreeCheck(Lvl, x, z, y, TreeDist))       //Am I too close to other trees?
                                            { AddTree(Lvl, x, (ushort)(z + 1), y, rand); }
                                        }
                                    }
                                }
                            }
                        }

                    }
                    else    //Must be on/under the water line then
                    {
                        for (ushort zz = 0; WaterLevel - zz >= 0; zz++)
                        {
                            if (WaterLevel - zz > z)
                            {Lvl.Blockchange(x, (ushort)(WaterLevel - zz), y, Block.water);}    //better fill the water aboce me
                            else if (WaterLevel - zz > z-3)
                            {
                                if (overlay[bb] < 0.75f)
                                {
                                    Lvl.Blockchange(x, (ushort)(WaterLevel - zz), y, Block.sand);   //sand top
                                }
                                else
                                {
                                    Lvl.Blockchange(x, (ushort)(WaterLevel - zz), y, Block.gravel);  //zoned for gravel
                                }
                            }
                            else
                            {Lvl.Blockchange(x, (ushort)(WaterLevel - zz), y, Block.rock);}
                        }
                    }
                }

            }
            catch
            {
                Logger.Log("Map Generator Failed", LogType.Error);
                Inuse = false;
                return false;
            }

            terrain = new float[0]; //Derp
            overlay = new float[0]; //Derp
            overlay2 = new float[0]; //Derp

            Inuse = false;

            return true;
        }
        void GenerateFault(float[] array,Level Lvl, string type, Random rand)
        {
            float startheight = 0.5f;
            float dispAux;
            ushort i, j, k, halfX, halfZ;
            float a, b, c, w, d;

            float DispMax, DispMin, DispChange;
            DispMax = 0.01f;
            DispChange = -0.0025f;
            if (type.Equals("mountains"))
            {
                DispMax = 0.02f;
                startheight = 0.6f;
            }
            else if (type.Equals("overlay"))
            {
                DispMax = 0.02f;
                DispChange = -0.01f;
            }

            for (int x = 0; x < array.Length; x++)
            {
                array[x] = startheight;
                //overlay[x] = 0.5f;
            }
            DispMin = -DispMax;
            float disp = DispMax;
            //if (terrainHeights == NULL)
            //    return (TERRAIN_ERROR_NOT_INITIALISED);

            halfX = (ushort)(Lvl.width / 2);
            halfZ = (ushort)(Lvl.height / 2);
            int numIterations = (int)((Lvl.width + Lvl.height));
            Logger.Log("Iterations = " + numIterations.ToString(), LogType.Debug);
            for (k = 0; k < numIterations; k++)
            {
                //s.Log("itteration " + k.ToString());
                d = (float)Math.Sqrt(halfX * halfX + halfZ * halfZ);
                w = (float)(rand.NextDouble() * 360);
                //w = (float)(rand.NextDouble()*90);
                a = (float)Math.Cos(w);
                b = (float)Math.Sin(w);

                c = ((float)rand.NextDouble()) * 2 * d - d;
                //c = ((float)rand.NextDouble() / 1) * 2 * d - d;
                //float disp = (float)(rand.NextDouble()* 0.02f - 0.01f);
                //iterationsDone++;
                //if (iterationsDone < itMinDisp)
                //    disp = maxDisp + (iterationsDone / (itMinDisp + 0.0)) * (minDisp - maxDisp);
                //else
                //    disp = minDisp;
                for (i = 0; i < Lvl.height; i++)
                {
                    for (j = 0; j < Lvl.width; j++)
                    {
                        //switch (terrainFunction)
                        //{
                        //case STEP:
                        if ((i - halfZ) * a + (j - halfX) * b + c > 0)
                            dispAux = disp;
                        else
                            dispAux = -disp;
                        //    break;
                        /*case SIN:
                            pd = ((i - halfZ) * a + (j - halfX) * b + c) / terrainWaveSize;
                            if (pd > 1.57) pd = 1.57;
                            else if (pd < 0) pd = 0;
                            dispAux = -disp / 2 + sin(pd) * disp;
                            break;
                        case COS:
                            pd = ((i - halfZ) * a + (j - halfX) * b + c) / terrainWaveSize;
                            if (pd > 3.14) pd = 3.14;
                            else if (pd < -3.14) pd = -3.14;
                            dispAux = disp - (terrainWaveSize / (terrainGridWidth + 0.0)) + cos(pd) * disp;
                            break;
                    }*/
                        //s.Log("adding " + dispAux.ToString());
                        AddTerrainHeight(array, j, i, Lvl.width, dispAux);
                        //terrainHeights[i * terrainGridWidth + j] += dispAux;
                    }
                }

                disp += DispChange;
                if (disp < DispMin) { disp = DispMax; }
            }
        }
        //applys the average filter
        void FilterAverage(Level Lvl)
        {
            Logger.Log("Applying average filtering", LogType.Debug);

            float[] filtered = new float[terrain.Length];

            for (int bb = 0; bb < terrain.Length; bb++)
            {
                ushort x = (ushort)(bb % Lvl.width);
                ushort y = (ushort)(bb / Lvl.width);
                filtered[bb] = GetAverage9(x, y, Lvl);
            }

            for (int bb = 0; bb < terrain.Length; bb++)
            {
                terrain[bb] = filtered[bb];
            }
        }
 //converts the float into a ushort for map height
 ushort Evaluate(Level lvl, float height)
 {
     ushort temp = (ushort)(height * lvl.depth);
     if (temp < 0) return 0;
     if (temp > lvl.depth - 1) return (ushort)(lvl.depth - 1);
     return temp;
 }
        //
        void AddTree(Level Lvl, ushort x, ushort z, ushort y, Random Rand)
        {
            byte height = (byte)Rand.Next(4, 7);
            for (ushort zz = 0; zz < height; zz++)
            {
                if (Lvl.GetTile(x, (ushort)(z + zz), y) == Block.air)   //Not likly to trigger anyway
                {
                    Lvl.Blockchange(x, (ushort)(z + zz), y, Block.trunk);
                }
                else
                {
                    height = (byte)zz;
                }
            }

            short top = (short)(height - 3);

            for (short xx = (short)-top; xx <= top; ++xx)
            {
                for (short yy = (short)-top; yy <= top; ++yy)
                {
                    for (short zz = (short)-top; zz <= top; ++zz)
                    {
                        if (Lvl.GetTile((ushort)(x + xx), (ushort)(z + zz + height), (ushort)(y + yy)) == Block.air)   //Not likly to trigger anyway
                        {
                            //short Dist = (short)(Math.Abs(xx) + Math.Abs(yy) + Math.Abs(zz));
                            short Dist = (short)(Math.Sqrt(xx * xx + yy * yy + zz * zz));
                            if (Dist < top + 1)
                            {
                                if (Rand.Next((int)(Dist)) < 2)
                                {
                                    Lvl.Blockchange((ushort)(x + xx), (ushort)(z + zz + height), (ushort)(y + yy), Block.leaf);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #12
0
        void SetupLevels()
        {
            levels = new List<Level>(Properties.MaxMaps);
            MapGen = new MapGenerator();

            Random random = new Random();

            if (File.Exists("levels/" + Properties.MainLevel + ".lvl"))
            {
                mainLevel = Level.Load(Properties.MainLevel);
                if (mainLevel == null)
                {
                    if (File.Exists("levels/" + Properties.MainLevel + ".lvl.backup"))
                    {
                        Logger.Log("Atempting to load backup.", LogType.Debug);
                        File.Copy("levels/" + Properties.MainLevel + ".lvl.backup", "levels/" + Properties.MainLevel + ".lvl", true);
                        mainLevel = Level.Load(Properties.MainLevel);
                        if (mainLevel == null)
                        {
                            Logger.Log("BACKUP FAILED!", LogType.Error);
                        }
                    }
                    else
                    {
                        Logger.Log("BACKUP NOT FOUND!", LogType.Error);
                    }

                }
            }
            else
            {
                Logger.Log("Warning: No main.lvl found.", LogType.Debug);
                Logger.Log("Creating Default main.lvl", LogType.Debug);
                mainLevel = new Level(Properties.MainLevel, 128, 64, 128, "flat");

                mainLevel.permissionvisit = LevelPermission.Guest;
                mainLevel.permissionbuild = LevelPermission.Guest;
                mainLevel.Save();
            }
            levels.Add(mainLevel);

            if (File.Exists("autoload.txt"))
            {
                try
                {
                    string[] lines = File.ReadAllLines("autoload.txt");
                    foreach (string line in lines)
                    {
                        //int temp = 0;
                        string _line = line.Trim();
                        try
                        {

                            if (_line == "") { continue; }
                            if (_line[0] == '#') { continue; }
                            int index = _line.IndexOf("=");

                            string key = line.Split('=')[0].Trim();
                            string value;
                            try
                            {
                                value = line.Split('=')[1].Trim();
                            }
                            catch
                            {
                                value = "0";
                            }

                            if (!key.Equals("main"))
                            {
                                Command.all.Find("load").Use(key + " " + value);
                            }
                            else // Main's already loaded so we just check and set the physics level
                            {
                                try
                                {
                                    int temp = int.Parse(value);
                                    if (temp >= 0 && temp <= 2)
                                    {
                                        mainLevel.physics = temp;
                                    }
                                }
                                catch
                                {
                                    Logger.Log("The Physics variable for main in autoload.txt is invalid!", LogType.Warning);
                                }
                            }

                        }
                        catch (Exception ex)
                        {
                            Logger.Log(_line + " failed.", LogType.Error);
                            Logger.Log(ex.Message, LogType.ErrorMessage);
                        }
                    }
                }
                catch
                {
                    Logger.Log("autoload.txt error", LogType.Error);
                }
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
            else
            {
                Logger.Log("autoload.txt does not exist", LogType.Debug);
            }
        }
 public static void GlobalMessageLevel(Level l, string message)
 {
     players.ForEach(delegate(Player p) { if (p.level == l) p.SendMessage(message); });
 }
Exemple #14
0
        public static Level Load(string name, byte phys)
        {
            Level level = null;
            string path = "levels/" + name + ".lvl";
            if (File.Exists(path))
            {

                FileStream fs = File.OpenRead(path);
                try
                {
                    GZipStream gs = new GZipStream(fs, CompressionMode.Decompress);
                    byte[] ver = new byte[2];
                    gs.Read(ver, 0, ver.Length);
                    ushort version = BitConverter.ToUInt16(ver, 0);
                    if (version == 1875)
                    {

                    }
                    else if (version == 1874)
                    {
                        byte[] header = new byte[16]; gs.Read(header, 0, header.Length);
                        ushort width = BitConverter.ToUInt16(header, 0);
                        ushort height = BitConverter.ToUInt16(header, 2);
                        ushort depth = BitConverter.ToUInt16(header, 4);
                        level = new Level(name, width, depth, height, "empty");
                        level.spawnx = BitConverter.ToUInt16(header, 6);
                        level.spawnz = BitConverter.ToUInt16(header, 8);
                        level.spawny = BitConverter.ToUInt16(header, 10);
                        level.rotx = header[12]; level.roty = header[13];
                        level.permissionvisit = (LevelPermission)header[14];
                        level.permissionbuild = (LevelPermission)header[15];
                    }
                    else
                    {
                        byte[] header = new byte[12]; gs.Read(header, 0, header.Length);
                        ushort width = version;
                        ushort height = BitConverter.ToUInt16(header, 0);
                        ushort depth = BitConverter.ToUInt16(header, 2);
                        level = new Level(name, width, depth, height, "empty");
                        level.spawnx = BitConverter.ToUInt16(header, 4);
                        level.spawnz = BitConverter.ToUInt16(header, 6);
                        level.spawny = BitConverter.ToUInt16(header, 8);
                        level.rotx = header[10]; level.roty = header[11];
                    }

                    level.physics = phys;

                    byte[] blocks = new byte[level.width * level.height * level.depth];
                    gs.Read(blocks, 0, blocks.Length);
                    for (int i = 0; i < level.width * level.height * level.depth; ++i)
                    {
                        level.blocks[i] = blocks[i];
                    }
                    gs.Close();
                    Logger.Log("LOADED: Level \"" + name + "\".");
                    level.backedup = true;
                }
                catch (Exception ex)
                {
                    Logger.Log("ERROR loading level \"" + name + "\".", LogType.Error);
                    Logger.Log(ex.StackTrace, LogType.ErrorMessage);
                    level = null;
                }
                finally { fs.Close(); }
            }
            else
            {
                Logger.Log("ERROR loading level \"" + name + "\".", LogType.Error);
                level = null;
            }

            return level;
        }