Example #1
0
        public static void RestoreTerrain(VM vm, TerrainBlend blend, byte roads)
        {
            var arch = vm.Context.Architecture;

            arch.DisableClip = true;

            var baseB = blend.Base;

            arch.Terrain.LightType = (baseB == TerrainType.WATER) ? TerrainType.SAND : blend.Base;
            arch.Terrain.DarkType  = (blend.Blend == TerrainType.WATER) ? blend.Base : blend.Blend;
            arch.Terrain.GenerateGrassStates();

            //clear all previous roads/sea
            VMArchitectureTools.FloorPatternRect(arch, new Rectangle(0, 0, arch.Width, 5), 0, 0, 1);
            VMArchitectureTools.FloorPatternRect(arch, new Rectangle(arch.Width - 7, 0, 7, arch.Height), 0, 0, 1);
            VMArchitectureTools.FloorPatternRect(arch, new Rectangle(0, arch.Height - 7, arch.Width, 7), 0, 0, 1);
            VMArchitectureTools.FloorPatternRect(arch, new Rectangle(0, 0, 5, arch.Height), 0, 0, 1);

            if (baseB == TerrainType.WATER)
            {
                //...
                VMArchitectureTools.FloorPatternRect(arch, new Rectangle(1, 1, arch.Width - 3, arch.Height - 3), 0, 65534, 1);
            }

            //blend flags start at top left, then go clockwise. (top right, bottom right..)

            if ((blend.WaterFlags & 1) > 0)
            {
                FillTileLine(arch, W, 0, 0, 1, WaterLineSegments, false);
            }
            if ((blend.WaterFlags & 4) > 0)
            {
                FillTileLine(arch, W, 0, 0, 1, WaterLineSegments, true);
            }
            if ((blend.WaterFlags & 16) > 0)
            {
                FillTileLine(arch, W, (short)(arch.Width - 1), 0, 1, WaterLineSegments, false);
            }
            if ((blend.WaterFlags & 64) > 0)
            {
                FillTileLine(arch, W, 0, (short)(arch.Height - 1), 1, WaterLineSegments, true);
            }

            if ((blend.WaterFlags & 2) > 0)
            {
                FillTiles(arch, W, 1, 1, 1, 1, 1);
            }
            if ((blend.WaterFlags & 8) > 0)
            {
                FillTiles(arch, W, (short)(arch.Width - 2), 1, 1, 1, 1);
            }
            if ((blend.WaterFlags & 32) > 0)
            {
                FillTiles(arch, W, (short)(arch.Width - 2), (short)(arch.Height - 2), 1, 1, 1);
            }
            if ((blend.WaterFlags & 128) > 0)
            {
                FillTiles(arch, W, 1, (short)(arch.Height - 2), 1, 1, 1);
            }

            if ((blend.WaterFlags & 5) == 5)
            {
                StampTilemap(arch, TopWaterCorner, 1, 1, 1);
            }
            if ((blend.WaterFlags & 20) == 20)
            {
                StampTilemap(arch, RightWaterCorner, (short)(arch.Width - 7), 1, 1);
            }
            if ((blend.WaterFlags & 80) == 80)
            {
                StampTilemap(arch, BottomWaterCorner, (short)(arch.Width - 7), (short)(arch.Height - 7), 1);
            }
            if ((blend.WaterFlags & 65) == 65)
            {
                StampTilemap(arch, LeftWaterCorner, 1, (short)(arch.Height - 7), 1);
            }

            /*
             *
             * if ((blend.WaterFlags & 1) > 0) VMArchitectureTools.FloorPatternRect(arch, new Rectangle(1, 1, 4, arch.Height - 2), 0, 65534, 1);
             * if ((blend.WaterFlags & 2) > 0) VMArchitectureTools.FloorPatternRect(arch, new Rectangle(1, 1, arch.Width-2, 4), 0, 65534, 1);
             * if ((blend.WaterFlags & 4) > 0) VMArchitectureTools.FloorPatternRect(arch, new Rectangle(arch.Width-5, 1, 4, arch.Height - 2), 0, 65534, 1);
             * if ((blend.WaterFlags & 8) > 0) VMArchitectureTools.FloorPatternRect(arch, new Rectangle(1, arch.Height-5, arch.Width-2, 4), 0, 65534, 1);
             *
             */

            //hard blends into the next terrain type

            FillTerrainRect(arch, new Rectangle(0, 0, 1, arch.Height - 1), (byte)(((blend.AdjFlags & 1) > 0) ? 255 : 0));
            FillTerrainRect(arch, new Rectangle(0, 0, arch.Width - 1, 1), (byte)(((blend.AdjFlags & 4) > 0) ? 255 : 0));
            FillTerrainRect(arch, new Rectangle(arch.Width - 2, 0, 1, arch.Height - 1), (byte)(((blend.AdjFlags & 16) > 0) ? 255 : 0));
            FillTerrainRect(arch, new Rectangle(0, arch.Height - 2, arch.Width - 1, 1), (byte)(((blend.AdjFlags & 64) > 0) ? 255 : 0));

            /*
             * FillTerrainRect(arch, new Rectangle(0, 0, 1, 1), (byte)(((blend.AdjFlags & 2) > 0) ? 255 : 0));
             * FillTerrainRect(arch, new Rectangle(arch.Width - 2, 0, 1, 1), (byte)(((blend.AdjFlags & 8) > 0) ? 255 : 0));
             * FillTerrainRect(arch, new Rectangle(arch.Width - 2, arch.Height - 2, 1, 1), (byte)(((blend.AdjFlags & 32) > 0) ? 255 : 0));
             * FillTerrainRect(arch, new Rectangle(0, arch.Height - 2, 1, 1), (byte)(((blend.AdjFlags & 128) > 0) ? 255 : 0));
             */

            //smooth blends into the next terrain type

            ApplyTerrainBlend(arch, RotateByte(blend.AdjFlags, 0), new Rectangle(0, 0, arch.Width - 1, 24), 255, 0, -11,
                              new Point[] { new Point(0, 0), new Point(arch.Width - 1, 0) },
                              new float[] { (135f / 180f) * (float)Math.PI, (225f / 180f) * (float)Math.PI },
                              new float[] { (15f / 180f) * (float)Math.PI, (-15f / 180f) * (float)Math.PI });

            ApplyTerrainBlend(arch, RotateByte(blend.AdjFlags, 6), new Rectangle(arch.Width - 25, 0, 24, arch.Height - 1), 0, 11, 0,
                              new Point[] { new Point(arch.Width - 1, 0), new Point(arch.Width - 1, arch.Height - 1) },
                              new float[] { (225f / 180f) * (float)Math.PI, (315f / 180f) * (float)Math.PI },
                              new float[] { (15f / 180f) * (float)Math.PI, (-15f / 180f) * (float)Math.PI });

            ApplyTerrainBlend(arch, RotateByte(blend.AdjFlags, 4), new Rectangle(0, arch.Height - 25, arch.Width - 1, 24), 0, 0, 11,
                              new Point[] { new Point(arch.Width - 1, arch.Height - 1), new Point(0, arch.Height - 1) },
                              new float[] { (315f / 180f) * (float)Math.PI, (45f / 180f) * (float)Math.PI },
                              new float[] { (15f / 180f) * (float)Math.PI, (-15f / 180f) * (float)Math.PI });

            ApplyTerrainBlend(arch, RotateByte(blend.AdjFlags, 2), new Rectangle(0, 0, 24, arch.Height - 1), 255, -11, 0,
                              new Point[] { new Point(0, arch.Height - 1), new Point(0, 0) },
                              new float[] { (45f / 180f) * (float)Math.PI, (135f / 180f) * (float)Math.PI },
                              new float[] { (15f / 180f) * (float)Math.PI, (-15f / 180f) * (float)Math.PI });

            RestoreRoad(vm, roads);
            if (vm.GetGlobalValue(11) == -1)
            {
                //set road dir. should only really do this FIRST EVER time, then road dir changes after are manual and rotate the contents of the lot.
                vm.TSOState.Size &= 0xFFFF;
                vm.TSOState.Size |= PickRoadDir(roads) << 16;
            }

            PositionLandmarkObjects(vm);

            arch.SignalTerrainRedraw();
            arch.DisableClip = false;
        }
Example #2
0
        public static int RestoreHeight(VM vm, VMTSOSurroundingTerrain terrain, int x, int y)
        {
            var sr = new float[4, 4];

            for (int oy = 0; oy < 4; oy++)
            {
                var srcY = Math.Min(3, Math.Max(0, oy + y - 1));
                for (int ox = 0; ox < 4; ox++)
                {
                    var srcX = Math.Min(3, Math.Max(0, ox + x - 1));
                    sr[3 - oy, ox] = terrain.Height[srcX, srcY];
                }
            }

            var baseLevel = (int)(((sr[1, 1] + sr[1, 2] + sr[2, 2] + sr[2, 1]) / 4) * 100);

            var target = vm.Context.Architecture.Terrain;
            var xn     = VMArchitectureTerrain.TerrainXNoise;
            var yn     = VMArchitectureTerrain.TerrainYNoise;

            for (int oy = 1; oy < target.Height; oy++)
            {
                for (int ox = 1; ox < target.Width; ox++)
                {
                    int index = (target.Height - oy) * target.Width + (target.Height - ox);

                    float fracy = (oy - 1f) / (target.Height - 2f);
                    fracy -= (yn[index] - 0.5f) / 5f;
                    float y1    = Cubic(sr[0, 0], sr[0, 1], sr[0, 2], sr[0, 3], fracy);
                    float y2    = Cubic(sr[1, 0], sr[1, 1], sr[1, 2], sr[1, 3], fracy);
                    float y3    = Cubic(sr[2, 0], sr[2, 1], sr[2, 2], sr[2, 3], fracy);
                    float y4    = Cubic(sr[3, 0], sr[3, 1], sr[3, 2], sr[3, 3], fracy);
                    float fracx = (ox - 1f) / (target.Width - 2f);
                    fracx -= (xn[index] - 0.5f) / 5f;

                    var h = Cubic(y1, y2, y3, y4, fracx);
                    target.Heights[index] = (short)(((h * 100f) - baseLevel));
                }
            }

            var lotSInfo = vm.TSOState.Size;

            if (vm.TSOState.OwnerID == 0)
            {
                lotSInfo = 10;
            }
            var ret = vm.Context.GetTSOBuildableArea(lotSInfo);

            var mailbox = vm.Entities.FirstOrDefault(m => (m.Object.OBJ.GUID == 0xEF121974 || m.Object.OBJ.GUID == 0x1D95C9B0));

            if (mailbox != null && mailbox.Position != LotTilePos.OUT_OF_WORLD)
            {
                var mailheight = target.Heights[mailbox.Position.TileY * target.Width + mailbox.Position.TileX];

                ret.Inflate(-1, -1);
                vm.Context.Architecture.DisableClip = true;
                VMArchitectureTools.RaiseTerrain(vm.Context.Architecture, ret, mailheight, false);
                vm.Context.Architecture.DisableClip = false;

                ret.Width--; ret.Height--;
                for (int oy = ret.Top; oy < ret.Bottom; oy++)
                {
                    for (int ox = ret.Left; ox < ret.Right; ox++)
                    {
                        int index = (oy) * target.Width + (ox);
                        target.GrassState[index] = 0;
                    }
                }
            }

            target.RegenerateCenters();
            if (VM.UseWorld)
            {
                vm.Context.Blueprint.Altitude        = target.Heights;
                vm.Context.Blueprint.AltitudeCenters = target.Centers;
            }

            foreach (var obj in vm.Entities)
            {
                obj.Position = obj.Position;
            }
            return(baseLevel);
        }