示例#1
0
        private static void HandlePhysicsLandblock(Landblock landblock, double timeTick, ConcurrentQueue <WorldObject> movedObjects)
        {
            foreach (WorldObject wo in landblock.GetWorldObjectsForPhysicsHandling())
            {
                // set to TRUE if object changes landblock
                var landblockUpdate = false;

                // detect player movement
                // TODO: handle players the same as everything else
                if (wo is Player player)
                {
                    wo.InUpdate = true;

                    var newPosition = HandlePlayerPhysics(player, timeTick);

                    // update position through physics engine
                    if (newPosition != null)
                    {
                        landblockUpdate = wo.UpdatePlayerPhysics(newPosition);
                    }

                    wo.InUpdate = false;
                }
                else
                {
                    landblockUpdate = wo.UpdateObjectPhysics();
                }

                if (landblockUpdate)
                {
                    movedObjects.Enqueue(wo);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Returns TRUE if current cell is a House cell
        /// </summary>
        public static bool IsRestrictable(this Position p, Landblock landblock)
        {
            var cell = landblock.IsDungeon ? p.Cell : p.GetOutdoorCell();

            return(HouseCell.HouseCells.ContainsKey(cell));
        }
示例#3
0
 public void SetAdjacency(Adjacency adjacency, Landblock landblock)
 {
     adjacencies[adjacency] = landblock;
 }
示例#4
0
        public static List <ModelMesh> Load(Landblock _landblock)
        {
            var landblock = _landblock.CellLandblock;

            // get the landblock cell offsets
            var blockX = (landblock.Id >> 24) * 8;
            var blockY = (landblock.Id >> 16 & 0xFF) * 8;

            var scenery = new List <ModelMesh>();

            for (var i = 0; i < landblock.Terrain.Count; i++)
            {
                var terrain = landblock.Terrain[i];

                var terrainType = terrain >> 2 & 0x1F;      // TerrainTypes table size = 32 (grass, desert, volcano, etc.)
                var sceneType   = terrain >> 11;            // SceneTypes table size = 89 total, 32 which can be indexed for each terrain type

                var sceneInfo = (int)LandblockMesh.RegionDesc.TerrainInfo.TerrainTypes[terrainType].SceneTypes[sceneType];
                var scenes    = LandblockMesh.RegionDesc.SceneInfo.SceneTypes[sceneInfo].Scenes;
                if (scenes.Count == 0)
                {
                    continue;
                }

                var cellX = i / LandblockMesh.VertexDim;
                var cellY = i % LandblockMesh.VertexDim;

                var globalCellX = (uint)(cellX + blockX);
                var globalCellY = (uint)(cellY + blockY);

                var cellMat   = globalCellY * (712977289 * globalCellX + 1813693831) - 1109124029 * globalCellX + 2139937281;
                var offset    = cellMat * 2.3283064e-10;
                var scene_idx = (int)(scenes.Count * offset);
                if (scene_idx >= scenes.Count)
                {
                    scene_idx = 0;
                }

                var sceneId = scenes[scene_idx];

                var scene = DatManager.PortalDat.ReadFromDat <Scene>(sceneId);

                var cellXMat = -1109124029 * globalCellX;
                var cellYMat = 1813693831 * globalCellY;
                cellMat = 1360117743 * globalCellX * globalCellY + 1888038839;

                for (uint j = 0; j < scene.Objects.Count; j++)
                {
                    var obj   = scene.Objects[(int)j];
                    var noise = (uint)(cellXMat + cellYMat - cellMat * 23399) * 2.3283064e-10;

                    if (noise < obj.Freq && obj.WeenieObj == 0)
                    {
                        var position = Displace(obj, globalCellX, globalCellY, j);

                        // ensure within landblock range, and not near road
                        var lx = cellX * LandblockMesh.CellSize + position.X;
                        var ly = cellY * LandblockMesh.CellSize + position.Y;

                        // TODO: ensure walkable slope
                        if (lx < 0 || ly < 0 || lx > LandblockMesh.LandblockSize || ly > LandblockMesh.LandblockSize || OnRoad(obj, landblock, lx, ly))
                        {
                            continue;
                        }

                        // load scenery
                        var model = new ModelMesh(obj.ObjId, obj.BaseLoc);
                        model.ObjectDesc = obj;
                        model.Cell       = new Vector2(cellX, cellY);
                        model.Position   = new Vector3(position.X, position.Y, GetZ(_landblock, model));
                        model.Rotation   = Quaternion.CreateFromYawPitchRoll(0, 0, RotateObj(obj, globalCellX, globalCellY, j));
                        model.Scale      = ScaleObj(obj, globalCellX, globalCellY, j);
                        model.BuildPolygons();
                        model.BoundingBox = new BoundingBox(model);

                        // collision detection
                        if (Collision(_landblock.Buildings, model) || Collision(scenery, model))
                        {
                            continue;
                        }

                        scenery.Add(model);
                    }
                }
            }
            return(scenery);
        }