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); } } }
/// <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)); }
public void SetAdjacency(Adjacency adjacency, Landblock landblock) { adjacencies[adjacency] = landblock; }
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); }