public void init_buildings() { if (Info == null || SideCellCount != 8) { return; } uint maxSize = 0, stabNum = 0; foreach (var info in Info.Buildings) { var building = BuildingObj.makeBuilding(info.ModelId, info.Portals, info.NumLeaves); var position = new Position(ID, new AFrame(info.Frame)); var outside = LandDefs.AdjustToOutside(position); var cell = get_landcell(position.ObjCellID); if (cell == null) { continue; } building.set_initial_frame(position.Frame); // hack building.PartArray.Parts[0].Pos = position; building.Position = position; cell.Building = building; building.add_to_cell(cell); // SortCell? Buildings.Add(building); building.add_to_stablist(ref StabList, ref maxSize, ref stabNum); } }
public void init_static_objs() { if (SideCellCount != 8) { return; } if (StaticObjects.Count > 0) { adjust_scene_obj_height(); foreach (var obj in StaticObjects) { if (!obj.is_completely_visible()) { obj.calc_cross_cells_static(); } } } else if (Info != null) { foreach (var info in Info.Objects) { var obj = PhysicsObj.makeObject(info.Id, 0, false); obj.DatObject = true; var position = new Position(ID, new AFrame(info.Frame)); var outside = LandDefs.AdjustToOutside(position); var cell = get_landcell(position.ObjCellID); if (cell == null) { //Console.WriteLine($"Landblock {ID:X8} - failed to spawn static object {info.Id:X8}"); obj.DestroyObject(); continue; } obj.add_obj_to_cell(cell, position.Frame); add_static_object(obj); } if (Info.RestrictionTables != null) { foreach (var kvp in Info.RestrictionTables) { var lcoord = LandDefs.gid_to_lcoord(kvp.Key); if (lcoord == null) { continue; } var idx = ((int)lcoord.Value.Y & 7) + ((int)lcoord.Value.X & 7) * SideCellCount; LandCells[idx].RestrictionObj = kvp.Value; } } } if (UseSceneFiles) { get_land_scenes(); } }
public static void add_all_outside_cells(Position position, int numSphere, List <Sphere> spheres, CellArray cellArray) { if (cellArray.AddedOutside) { return; } if (numSphere != 0) { foreach (var sphere in spheres) { var cellPoint = position.ObjCellID; var center = sphere.Center; if (!LandDefs.AdjustToOutside(ref cellPoint, ref center)) { break; } var point = new Vector2(); point.X = center.X - (float)Math.Floor(center.X / 24.0f) * 24.0f; point.Y = center.Y - (float)Math.Floor(center.Y / 24.0f) * 24.0f; var minRad = sphere.Radius; var maxRad = 24.0f - minRad; var lcoord = LandDefs.gid_to_lcoord(cellPoint); if (lcoord != null) { add_outside_cell(cellArray, lcoord.Value); check_add_cell_boundary(cellArray, point, lcoord.Value, minRad, maxRad); } } } else { if (!LandDefs.AdjustToOutside(position)) { return; } var lcoord = LandDefs.gid_to_lcoord(position.ObjCellID); if (lcoord != null) { add_outside_cell(cellArray, lcoord.Value); } } }
public void init_static_objs() { if (SideCellCount != 8) { return; } if (StaticObjects.Count > 0) { adjust_scene_obj_height(); foreach (var obj in StaticObjects) { if (!obj.is_completely_visible()) { obj.calc_cross_cells_static(); } } } else if (Info != null) { foreach (var info in Info.Objects) { var obj = PhysicsObj.makeObject(info.Id, 0, false); obj.DatObject = true; var position = new Position(ID, new AFrame(info.Frame)); var outside = LandDefs.AdjustToOutside(position); var cell = get_landcell(position.ObjCellID); if (cell == null) { continue; } obj.add_obj_to_cell(cell, position.Frame); add_static_object(obj); } } if (UseSceneFiles) { get_land_scenes(); } }
public void adjust_to_outside() { LandDefs.AdjustToOutside(this); }
public void get_land_scenes() { //Console.WriteLine("Loading scenery for " + ID.ToString("X8")); // ported from Scenery Scenery = new List <PhysicsObj>(); // get the landblock cell offsets var blockX = (ID >> 24) * 8; var blockY = (ID >> 16 & 0xFF) * 8; for (uint i = 0; i < Terrain.Count; i++) { var terrain = Terrain[(int)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)DatManager.PortalDat.RegionDesc.TerrainInfo.TerrainTypes[terrainType].SceneTypes[sceneType]; var scenes = DatManager.PortalDat.RegionDesc.SceneInfo.SceneTypes[sceneInfo].Scenes; if (scenes.Count == 0) { continue; } var cellX = i / LandDefs.VertexDim; var cellY = i % LandDefs.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 + j)) * 2.3283064e-10; if (noise < obj.Freq && obj.WeenieObj == 0) { // pseudo-randomized placement var position = ObjectDesc.Displace(obj, globalCellX, globalCellY, j); var lx = cellX * LandDefs.CellLength + position.X; var ly = cellY * LandDefs.CellLength + position.Y; var loc = new Vector3(lx, ly, position.Z); // ensure within landblock range, and not near road if (lx < 0 || ly < 0 || lx >= LandDefs.BlockLength || ly >= LandDefs.BlockLength || OnRoad(loc)) { continue; } // load scenery var pos = new Position(ID); pos.Frame.Origin = loc; var outside = LandDefs.AdjustToOutside(pos); var cell = get_landcell(pos.ObjCellID); if (cell == null) { continue; } // check for buildings var sortCell = (SortCell)cell; if (sortCell != null && sortCell.has_building()) { continue; } Polygon walkable = null; var terrainPoly = cell.find_terrain_poly(pos.Frame.Origin, ref walkable); if (walkable == null) { continue; } // ensure walkable slope if (!ObjectDesc.CheckSlope(obj, walkable.Plane.Normal.Z)) { continue; } walkable.Plane.set_height(ref pos.Frame.Origin); // rotation if (obj.Align != 0) { pos.Frame = ObjectDesc.ObjAlign(obj, walkable.Plane, pos.Frame.Origin); } else { pos.Frame = ObjectDesc.RotateObj(obj, globalCellX, globalCellY, j, pos.Frame.Origin); } // build object var physicsObj = PhysicsObj.makeObject(obj.ObjId, 0, false); physicsObj.DatObject = true; physicsObj.set_initial_frame(pos.Frame); if (!physicsObj.obj_within_block()) { //Console.WriteLine($"Landblock {ID:X8} scenery: failed to spawn {obj.ObjId:X8}"); physicsObj.DestroyObject(); continue; } physicsObj.add_obj_to_cell(cell, pos.Frame); var scale = ObjectDesc.ScaleObj(obj, globalCellX, globalCellY, j); physicsObj.SetScaleStatic(scale); Scenery.Add(physicsObj); } } } //Console.WriteLine("Landblock " + ID.ToString("X8") + " scenery count: " + Scenery.Count); }
public static void add_all_outside_cells(int numParts, List <PhysicsPart> parts, CellArray cellArray, uint id) { if (cellArray.AddedOutside) { return; } cellArray.AddedOutside = true; if (numParts == 0) { return; } var min_x = 0; var min_y = 0; var max_x = 0; var max_y = 0; for (var i = 0; i < numParts; i++) { var curPart = parts[i]; var loc = new Position(curPart.Pos); if (!LandDefs.AdjustToOutside(loc)) { continue; } var _lcoord = LandDefs.gid_to_lcoord(loc.ObjCellID); if (_lcoord == null) { continue; } var lcoord = _lcoord.Value; var lx = (int)(((loc.ObjCellID & 0xFFFF) - 1) / 8); var ly = (int)(((loc.ObjCellID & 0xFFFF) - 1) % 8); for (var j = 0; j < numParts; j++) { var otherPart = parts[j]; if (otherPart == null) { continue; } // add if missing: otherPart.Always2D, checks degrades.degradeMode != 1 var bbox = new BBox(); bbox.LocalToGlobal(otherPart.GetBoundingBox(), otherPart.Pos, loc); var min_cx = (int)Math.Floor(bbox.Min.X / 24.0f); var min_cy = (int)Math.Floor(bbox.Min.Y / 24.0f); var max_cx = (int)Math.Floor(bbox.Max.X / 24.0f); var max_cy = (int)Math.Floor(bbox.Max.Y / 24.0f); min_x = Math.Min(min_cx - lx, min_x); min_y = Math.Min(min_cy - ly, min_y); max_x = Math.Max(max_cx - lx, max_x); max_y = Math.Max(max_cy - ly, max_y); } add_cell_block(min_x + (int)lcoord.X, min_y + (int)lcoord.Y, max_x + (int)lcoord.X, max_y + (int)lcoord.Y, cellArray, id); } }
public void get_land_scenes() { // ported from Scenery Scenery = new List <PhysicsObj>(); // get the landblock cell offsets var blockX = (ID >> 24) * 8; var blockY = (ID >> 16 & 0xFF) * 8; for (var i = 0; i < Terrain.Count; i++) { var terrain = Terrain[(int)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)DatManager.PortalDat.RegionDesc.TerrainInfo.TerrainTypes[terrainType].SceneTypes[sceneType]; var scenes = DatManager.PortalDat.RegionDesc.SceneInfo.SceneTypes[sceneInfo].Scenes; if (scenes.Count == 0) { continue; } var cellX = i / LandDefs.VertexDim; var cellY = i % LandDefs.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 + j)) * 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 * LandDefs.CellLength + position.X; var ly = cellY * LandDefs.CellLength + position.Y; // TODO: ensure walkable slope if (lx < 0 || ly < 0 || lx >= LandDefs.BlockLength || ly >= LandDefs.BlockLength || OnRoad(obj, lx, ly)) { continue; } // load scenery var pos = new Position(ID); pos.Frame.Origin = new Vector3(lx, ly, 0); pos.Frame.Orientation = Quaternion.CreateFromYawPitchRoll(0, 0, RotateObj(obj, globalCellX, globalCellY, j)); var outside = LandDefs.AdjustToOutside(pos); var cell = get_landcell(pos.ObjCellID); //if (cell == null) continue; Polygon walkable = null; var terrainPoly = cell.find_terrain_poly(pos.Frame.Origin, ref walkable); walkable.Plane.set_height(ref pos.Frame.Origin); // todo: collision detection var physicsObj = PhysicsObj.makeObject(obj.ObjId, 0, false); //physicsObj.set_initial_frame(pos.Frame); physicsObj.add_obj_to_cell(cell, pos.Frame); Scenery.Add(physicsObj); } } } //Console.WriteLine("Landblock " + ID.ToString("X8") + " scenery count: " + Scenery.Count); }