Example #1
0
        public static void RestoreTerrain(VM vm, RestoreLotType type = RestoreLotType.Normal)
        {
            //take center of lotstate
            RestoreTerrain(vm, vm.TSOState.Terrain.BlendN[1, 1], vm.TSOState.Terrain.Roads[1, 1], type);

            RestoreHeight(vm, vm.TSOState.Terrain, 1, 1);
        }
Example #2
0
        public static void EnsureCoreObjects(VM vm, RestoreLotType type)
        {
            var del = MovePositions.Where(x => x.Type != RestoreLotType.Generic && x.Type != type).Select(x => EntityByGUID(vm, x.GUID)).Where(x => x != null).ToList();

            foreach (var ent in del)
            {
                ent.Delete(true, vm.Context);
            }
            var fail = MovePositions.Where(x =>
            {
                //find an object of this type
                var ent = EntityByGUID(vm, x.GUID);
                return((x.Type == type || x.Type == RestoreLotType.Generic) && (ent == null || ent.Position == LotTilePos.OUT_OF_WORLD));
            });

            if (fail.Count() > 0)
            {
                PositionLandmarkObjects(vm, type);
            }
        }
Example #3
0
        /// <summary>
        /// Positions the Landmark objects depending on the lot direction. (npc/car portals, bin, mailbox, phone)
        /// </summary>
        /// <param name="vm">The VM.</param>
        public static void PositionLandmarkObjects(VM vm, RestoreLotType type)
        {
            var arch      = vm.Context.Architecture;
            var lotSInfo  = vm.TSOState.Size;
            var lotSize   = lotSInfo & 255;
            var lotFloors = ((lotSInfo >> 8) & 255) + 2;
            var lotDir    = (lotSInfo >> 16);

            var dim = VMBuildableAreaInfo.BuildableSizes[lotSize];

            //need to rotate the lot dir towards the road. bit weird cos we're rotating a rectangle

            var w = arch.Width;
            var h = arch.Height;
            //little bit different from the array in VMContext. Want the tile positions outside buildable area
            //so min x and y are 5 instead of 6.
            var corners = new Vector2[]
            {
                new Vector2(5, 5),         // top, default orientation
                new Vector2(w - 7, 5),     // right
                new Vector2(w - 7, h - 7), // bottom
                new Vector2(5, h - 7)      // left
            };
            var perpIncrease = new Vector2[]
            {
                new Vector2(0, -1), //bottom left road side
                new Vector2(1, 0),
                new Vector2(0, 1),
                new Vector2(-1, 0)
            };

            //rotation 0: move perp from closer point to top bottom -> left (90 degree ccw of perp)
            //rotation 1: choose closer pt to top left->top (90 degree ccw of perp)
            //rotation 2: choose closer pt to top top->right (90 degree cw of perp)

            var pt1 = corners[(lotDir + 2) % 4];
            var pt2 = corners[(lotDir + 3) % 4];

            var ctr = (pt1 + pt2) / 2; //ok.

            var xperp = perpIncrease[(lotDir + 1) % 4];
            var yperp = perpIncrease[(lotDir + 2) % 4];

            //move relative position objs
            foreach (var pos in MovePositions)
            {
                var rpos = ctr + (pos.X * xperp) + (pos.Y * yperp);
                var ent  = EntityByGUID(vm, pos.GUID);
                if (type != RestoreLotType.Blank && ent == null && (pos.Type == type || pos.Type == RestoreLotType.Generic))
                {
                    ent = vm.Context.CreateObjectInstance(pos.GUID, LotTilePos.OUT_OF_WORLD, Direction.NORTH).BaseObject;
                }
                if (ent != null)
                {
                    var result = ent.MultitileGroup.BaseObject.SetPosition(LotTilePos.FromBigTile((short)rpos.X, (short)rpos.Y, 1), (Direction)(1 << ((lotDir * 2 + pos.DirOff) % 8)), vm.Context, VMPlaceRequestFlags.AllowIntersection);
                    if (result.Status != VMPlacementError.Success)
                    {
                        // if we can't place the object, put it oow.
                        ent.MultitileGroup.BaseObject.SetPosition(LotTilePos.OUT_OF_WORLD, (Direction)(1 << ((lotDir * 2 + pos.DirOff) % 8)), vm.Context);
                    }
                }
            }

            // finally, must position npc portals. These are on the sidewalk, but at the far edge of the lot.
            // ped, npc1, npc2 (0x81E6BEF9, 0x23BC2034, 0x4E57C380)
            // if there is water on the space we can't intersect it :(

            // for now just choose pavement corners. These are safe from being in water.
            var npc1 = EntityByGUID(vm, 0x23BC2034);

            if (npc1 != null)
            {
                npc1.SetPosition(LotTilePos.FromBigTile((short)pt1.X, (short)pt1.Y, 1), (Direction)(1 << ((lotDir * 2 + 0) % 8)), vm.Context);
            }
            var npc2 = EntityByGUID(vm, 0x4E57C380);

            if (npc2 != null)
            {
                npc2.SetPosition(LotTilePos.FromBigTile((short)pt2.X, (short)pt2.Y, 1), (Direction)(1 << ((lotDir * 2 + 0) % 8)), vm.Context);
            }
            var ped = EntityByGUID(vm, 0x81E6BEF9);

            if (ped != null)
            {
                ped.SetPosition(LotTilePos.FromBigTile((short)ctr.X, (short)ctr.Y, 1), (Direction)(1 << ((lotDir * 2 + 0) % 8)), vm.Context);
            }

            var rPos = ctr + (-13 * xperp) + (2 * yperp);

            if (ped != null)
            {
                StampTerrainmap(arch, CarDirtRoad, (short)rPos.X, (short)rPos.Y, xperp, yperp);
            }
        }
Example #4
0
 public GUIDToPosition(uint guid, short x, short y, int dirOff, RestoreLotType type = RestoreLotType.Generic)
 {
     GUID = guid; X = x; Y = y; DirOff = dirOff; Type = type;
 }
Example #5
0
        public static void RestoreTerrain(VM vm, TerrainBlend blend, byte roads, RestoreLotType type)
        {
            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, type);

            arch.SignalTerrainRedraw();
            arch.DisableClip = false;
        }