예제 #1
0
        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);
            }
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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);
                }
            }
        }
예제 #4
0
 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();
     }
 }
예제 #5
0
파일: Position.cs 프로젝트: Zegeger/ACE
 public void adjust_to_outside()
 {
     LandDefs.AdjustToOutside(this);
 }
예제 #6
0
        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);
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
        }