Example #1
0
        public Vector3 GetOffset(Position pos)
        {
            var blockOffset  = LandDefs.GetBlockOffset(ObjCellID, pos.ObjCellID);
            var globalOffset = blockOffset + pos.Frame.Origin - Frame.Origin;

            return(globalOffset);
        }
Example #2
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);
            }
        }
Example #3
0
        public Vector3 LocalToGlobal(Position pos, Vector3 point)
        {
            var cellOffset  = pos.Frame.LocalToGlobal(point);
            var blockOffset = LandDefs.GetBlockOffset(ObjCellID, pos.ObjCellID);

            return(blockOffset + cellOffset);
        }
        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();
            }
        }
Example #5
0
        /// <summary>s
        /// Gets the landcell from a landblock. If the cell is an indoor cell and hasn't been loaded, it will be loaded.<para />
        /// This function is thread safe
        /// </summary>
        public static ObjCell get_landcell(ulong iBlockCellID)
        {
            /*if ((iBlockCellID | 0xFFFF) == 0x1D9FFFF)
             * {
             *  Console.WriteLine(System.Environment.StackTrace);
             *  var debug = true;
             * }*/

            //Console.WriteLine($"get_landcell({blockCellID:X8}");

            var landblock = get_landblock(iBlockCellID);

            if (landblock == null)
            {
                return(null);
            }

            var     cellID = iBlockCellID & 0xFFFF;
            ObjCell cell   = null;

            // outdoor cells
            if (cellID < 0x100)
            {
                var lcoord = LandDefs.gid_to_lcoord((uint)iBlockCellID, false);
                if (lcoord == null)
                {
                    return(null);
                }
                var landCellIdx = ((int)lcoord.Value.Y % 8) + ((int)lcoord.Value.X % 8) * landblock.SideCellCount;
                landblock.LandCells.TryGetValue(landCellIdx, out cell);
            }
            // indoor cells
            else
            {
                if (landblock.LandCells.TryGetValue((int)cellID, out cell))
                {
                    return(cell);
                }

                lock (landblock.LandCellMutex)
                {
                    if (landblock.LandCells.TryGetValue((int)cellID, out cell))
                    {
                        return(cell);
                    }

                    cell = DBObj.GetEnvCell((uint)iBlockCellID);
                    cell.CurLandblock = landblock;

                    landblock.LandCells.TryAdd((int)cellID, cell);
                    var envCell = (EnvCell)cell;
                    envCell.PostInit();
                }
            }
            return(cell);
        }
Example #6
0
        public float calc_water_depth(uint blockCellID, Vector3 point)
        {
            var  cellID = blockCellID & 0xFFFF;
            var  cellOffset = cellID - 1;
            uint cellX = 0, cellY = cellID;

            if (LandDefs.inbound_valid_cellid(cellID) && cellID < 0x100)
            {
                cellX = cellOffset / 8;
                cellY = cellOffset & 7;
            }
            uint terrainIdx;
            uint surfOffset = 0;

            // missing fpu instructions
            if (point.X <= point.Y)
            {
                terrainIdx = (cellY + 8 * cellX + cellX + 1);
                if (point.X == point.Y)
                {
                    terrainIdx--;
                }
            }
            else if (point.X >= point.Y)
            {
                terrainIdx = cellY + 8 * (cellX + 1) + cellX + 1;
            }
            else  // ?
            {
                terrainIdx = 8 * cellX + 10;
                surfOffset = (cellX + cellY) * 2;
            }
            var column   = Terrain[(int)terrainIdx & 0xFF];
            var hasWater = SurfChar[column + (int)surfOffset & 0x7F];

            if (hasWater != 0)
            {
                if (hasWater == 1)
                {
                    return(0.44999999f);
                }
                else
                {
                    return(0);
                }
            }
            else
            {
                return(0.1f);
            }
        }
Example #7
0
        public LandCell get_landcell(uint cellID)
        {
            var landblock = get_landblock(cellID);

            if (landblock == null)
            {
                return(null);
            }

            var lcoord      = LandDefs.gid_to_lcoord(cellID);
            var landCellIdx = ((int)lcoord.Value.Y % 8) + ((int)lcoord.Value.X % 8) * landblock.SideCellCount;

            return(landblock.LandCells[landCellIdx]);
        }
Example #8
0
        public Landblock(CellLandblock landblock)
            : base(landblock)
        {
            Init();

            ID = landblock.Id;
            BlockInfoExists = landblock.HasObjects;
            if (BlockInfoExists)
            {
                Info = (LandblockInfo)DBObj.Get(new QualifiedDataID(2, ID - 1));
            }
            BlockCoord = LandDefs.blockid_to_lcoord(landblock.Id).Value;
            _landblock = landblock;
            get_land_limits();
        }
Example #9
0
        public LandCell get_landcell(uint cellID)
        {
            var lcoord = LandDefs.gid_to_lcoord(cellID).Value;

            var idx = ((int)lcoord.Y & 7) + ((int)lcoord.X & 7) * SideCellCount;

            if (LandCells[idx].ID == cellID)
            {
                return((LandCell)LandCells[idx]);
            }
            else
            {
                return(null);
            }
        }
Example #10
0
        public void GetCellRotation(uint landblockID, uint x, uint y, ref bool singleTextureCell, ref uint surfNum, ref LandDefs.Rotation rotation)
        {
            var lcoord = LandDefs.blockid_to_lcoord(landblockID);

            var globalCellX = (int)(lcoord.Value.X + x);
            var globalCellY = (int)(lcoord.Value.Y + y);

            // no palette shift

            // SW / SE / NE / NW
            var i        = (int)(LandDefs.VertexDim * x + y);
            var terrain  = Terrain[i];
            var t1       = (terrain & 0x7F) >> 2;
            var r1       = terrain & 3;
            var j        = (int)(LandDefs.VertexDim * (x + 1) + y);
            var terrain2 = Terrain[j];
            var t2       = (terrain2 & 0x7F) >> 2;
            var r2       = terrain2 & 3;
            var terrain3 = Terrain[j + 1];
            var t3       = (terrain3 & 0x7F) >> 2;
            var r3       = terrain3 & 3;
            var terrain4 = Terrain[i + 1];
            var t4       = (terrain4 & 0x7F) >> 2;
            var r4       = terrain4 & 3;

            /*Console.WriteLine($"LandblockStruct.GetCellRotation({landblockID:X8}, x:{x}, y:{y})");
             * Console.WriteLine($"I1: {i}, I2: {j}, I3: {j+1}, I4: {i+1}");
             * if (r1 != 0 || r2 != 0 || r3 != 0 || r4 != 0)
             *  Console.WriteLine($"R1: {r1}, R2: {r2}, R3: {r3}, R4: {r4}");
             * Console.WriteLine($"T1: {(LandDefs.TerrainType)t1}, T2: {(LandDefs.TerrainType)t2}, T3: {(LandDefs.TerrainType)t3}, T4: {(LandDefs.TerrainType)t4}");*/

            var palCodes = new List <uint>();

            palCodes.Add(GetPalCode(r1, r2, r3, r4, t1, t2, t3, t4));   // 0
            //palCodes.Add(GetPalCode(r2, r3, r4, r1, t2, t3, t4, t1));   // 270
            //palCodes.Add(GetPalCode(r3, r4, r1, r2, t3, t4, t1, t2));   // 180
            //palCodes.Add(GetPalCode(r4, r1, r2, r3, t4, t1, t2, t3));   // 90

            var singleRoadCell = r1 == r2 && r1 == r3 && r1 == r4;
            var singleTypeCell = t1 == t2 && t1 == t3 && t1 == t4;

            singleTextureCell = r1 != 0 ? singleRoadCell : singleRoadCell && singleTypeCell;

            var regionDesc  = DatManager.PortalDat.RegionDesc;
            var minimizePal = true;

            LandSurf.Instance.SelectTerrain(globalCellX, globalCellY, ref surfNum, ref rotation, palCodes, 1, minimizePal);
        }
Example #11
0
        /// <summary>
        /// Gets the landcell from a landblock. If the cell is an indoor cell and hasn't been loaded, it will be loaded.<para />
        /// This function is thread safe
        /// </summary>
        public static ObjCell get_landcell(uint blockCellID)
        {
            //Console.WriteLine($"get_landcell({blockCellID:X8}");

            var landblock = get_landblock(blockCellID);

            if (landblock == null)
            {
                return(null);
            }

            var     cellID = blockCellID & 0xFFFF;
            ObjCell cell   = null;

            // outdoor cells
            if (cellID < 0x100)
            {
                var lcoord = LandDefs.gid_to_lcoord(blockCellID, false);
                if (lcoord == null)
                {
                    return(null);
                }
                var landCellIdx = ((int)lcoord.Value.Y % 8) + ((int)lcoord.Value.X % 8) * landblock.SideCellCount;
                landblock.LandCells.TryGetValue(landCellIdx, out cell);
            }
            // indoor cells
            else
            {
                if (landblock.LandCells.TryGetValue((int)cellID, out cell))
                {
                    return(cell);
                }

                lock (landblock.LandCellMutex)
                {
                    if (landblock.LandCells.TryGetValue((int)cellID, out cell))
                    {
                        return(cell);
                    }

                    cell = DBObj.GetEnvCell(blockCellID);
                    landblock.LandCells.TryAdd((int)cellID, cell);
                    var envCell = (EnvCell)cell;
                    envCell.PostInit();
                }
            }
            return(cell);
        }
Example #12
0
        public Landblock(CellLandblock landblock)
            : base(landblock)
        {
            Init();

            ID = landblock.Id;
            //Console.WriteLine("Loading landblock " + ID.ToString("X8"));
            BlockInfoExists = landblock.HasObjects;
            if (BlockInfoExists)
            {
                Info = DBObj.GetLandblockInfo(ID - 1);
            }
            BlockCoord = LandDefs.blockid_to_lcoord(landblock.Id).Value;
            _landblock = landblock;
            get_land_limits();
        }
Example #13
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);
                }
            }
        }
Example #14
0
        public override TransitionState FindEnvCollisions(Transition transition)
        {
            var transitState = check_entry_restrictions(transition);

            if (transitState != TransitionState.OK)
            {
                return(transitState);
            }

            var path = transition.SpherePath;

            var blockOffset = LandDefs.GetBlockOffset(path.CheckPos.ObjCellID, ID);
            var localPoint  = transition.SpherePath.GlobalLowPoint - blockOffset;

            Polygon walkable = null;

            if (!find_terrain_poly(localPoint, ref walkable))
            {
                return(transitState);
            }

            var objInfo = transition.ObjectInfo;

            if (get_block_water_type() == LandDefs.WaterType.EntirelyWater &&
                !objInfo.State.HasFlag(ObjectInfoState.IsViewer) && !objInfo.Object.State.HasFlag(PhysicsState.Missile))
            {
                return(TransitionState.Collided);
            }
            var waterDepth = get_water_depth(localPoint);

            var checkPos = new Sphere(path.GlobalSphere[0]);

            checkPos.Center -= LandDefs.GetBlockOffset(path.CheckPos.ObjCellID, ID);

            var result = objInfo.ValidateWalkable(checkPos, walkable.Plane, WaterType != LandDefs.WaterType.NotWater, waterDepth, transition, ID);

            if (result != TransitionState.OK && PhysicsObj.IsPicking)
            {
                Picker.PickResult.Type    = PickType.LandCell;
                Picker.PickResult.ObjCell = this;
                Picker.PickResult.HitPoly = walkable;
            }
            return(result);
        }
Example #15
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();
     }
 }
Example #16
0
        /// <summary>
        /// Returns a list of outdoor cells within visible range of player
        /// </summary>
        public List <ObjCell> GetOutdoorCells(ObjCell cell)
        {
            // get cell x/y global offset
            var lcoord = LandDefs.get_outside_lcoord(cell.ID, PhysicsObj.Position.Frame.Origin.X, PhysicsObj.Position.Frame.Origin.Y).Value;

            // includes the origin cell
            var blockLength = (int)CellRadiusOutside * 2 + 1;
            var cells       = new List <ObjCell>(/*blockLength * blockLength*/);

            var start = new Vector2(lcoord.X - CellRadiusOutside, lcoord.Y - CellRadiusOutside);
            var end   = new Vector2(lcoord.X + CellRadiusOutside, lcoord.Y + CellRadiusOutside);

            for (var cellX = start.X; cellX <= end.X; cellX++)
            {
                for (var cellY = start.Y; cellY <= end.Y; cellY++)
                {
                    var blockCellID = LandDefs.lcoord_to_gid(cellX, cellY);
                    var _cell       = LScape.get_landcell((uint)blockCellID);
                    if (_cell == null)
                    {
                        continue;
                    }
                    cells.Add(_cell);

                    // does this outdoor cell contain a building?
                    // if so, add all of its cells
                    var landCell = _cell as LandCell;
                    if (landCell.has_building())
                    {
                        //Console.WriteLine($"Found building in cell {landCell.ID:X8}");
                        var buildingCells = landCell.Building.get_building_cells();
                        //Console.WriteLine("# cells: " + buildingCells.Count);
                        cells.AddRange(buildingCells);
                    }
                }
            }
            return(cells);
        }
Example #17
0
        public static ObjCell get_landcell(uint blockCellID)
        {
            var landblock = get_landblock(blockCellID);

            if (landblock == null)
            {
                return(null);
            }

            var     cellID = blockCellID & 0xFFFF;
            ObjCell cell   = null;

            // outdoor cells
            if (cellID < 0x100)
            {
                var lcoord = LandDefs.gid_to_lcoord(blockCellID, false);
                if (lcoord == null)
                {
                    return(null);
                }
                var landCellIdx = ((int)lcoord.Value.Y % 8) + ((int)lcoord.Value.X % 8) * landblock.SideCellCount;
                landblock.LandCells.TryGetValue(landCellIdx, out cell);
            }
            // indoor cells
            else
            {
                landblock.LandCells.TryGetValue((int)cellID, out cell);
                if (cell != null)
                {
                    return(cell);
                }
                cell = (EnvCell)DBObj.Get(new QualifiedDataID(3, blockCellID));
                landblock.LandCells.Add((int)cellID, cell);
                ((EnvCell)cell).build_visible_cells();
            }
            return(cell);
        }
Example #18
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);
            }
        }
Example #19
0
        public Vector3 GetOffset(Position pos, Vector3 rotation)
        {
            var blockOffset = LandDefs.GetBlockOffset(ObjCellID, pos.ObjCellID);

            return(blockOffset + pos.LocalToGlobal(rotation) - Frame.Origin);
        }
Example #20
0
        public static void find_cell_list(Position position, int numSphere, List <Sphere> sphere, CellArray cellArray, ref ObjCell currCell, SpherePath path)
        {
            cellArray.NumCells     = 0;
            cellArray.AddedOutside = false;

            var visibleCell = GetVisible(position.ObjCellID);

            if ((position.ObjCellID & 0xFFFF) >= 0x100)
            {
                if (path != null)
                {
                    path.HitsInteriorCell = true;
                }

                cellArray.add_cell(position.ObjCellID, visibleCell);
            }
            else
            {
                LandCell.add_all_outside_cells(position, numSphere, sphere, cellArray);
            }

            if (visibleCell != null && numSphere != 0)
            {
                for (var i = 0; i < cellArray.Cells.Count; i++)
                {
                    var cell = cellArray.Cells.Values.ElementAt(i);
                    if (cell == null)
                    {
                        continue;
                    }

                    cell.find_transit_cells(position, numSphere, sphere, cellArray, path);
                }
                //var checkCells = cellArray.Cells.Values.ToList();
                //foreach (var cell in checkCells)
                //cell.find_transit_cells(position, numSphere, sphere, cellArray, path);

                if (currCell != null)
                {
                    currCell = null;
                    foreach (var cell in cellArray.Cells.Values)
                    {
                        if (cell == null)
                        {
                            continue;
                        }

                        var blockOffset = LandDefs.GetBlockOffset(position.ObjCellID, cell.ID);
                        var localPoint  = sphere[0].Center - blockOffset;

                        if (cell.point_in_cell(localPoint))
                        {
                            currCell = cell;
                            if ((cell.ID & 0xFFFF) >= 0x100)
                            {
                                if (path != null)
                                {
                                    path.HitsInteriorCell = true;
                                }
                                return;     // break?
                            }
                        }
                    }
                }
            }
            if (!cellArray.LoadCells && (position.ObjCellID & 0xFFFF) >= 0x100)
            {
                var cells = cellArray.Cells.Values.ToList();
                foreach (var cell in cells)
                {
                    if (cell == null)
                    {
                        continue;
                    }

                    if (visibleCell.ID == cell.ID)
                    {
                        continue;
                    }

                    var found = false;

                    foreach (var stab in ((EnvCell)visibleCell).VisibleCells.Values)
                    {
                        if (stab == null)
                        {
                            continue;
                        }

                        if (cell.ID == stab.ID)
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        cellArray.remove_cell(cell);
                    }
                }
            }
        }
Example #21
0
 public void adjust_to_outside()
 {
     LandDefs.AdjustToOutside(this);
 }
Example #22
0
        public void ConstructPolygons(uint landblockID)
        {
            var lcoord = LandDefs.blockid_to_lcoord(landblockID).Value;

            var polyNum   = 1;
            var seedA     = (uint)((int)lcoord.X * LandDefs.VertexPerCell * 214614067);
            var seedB     = (uint)((int)lcoord.X * LandDefs.VertexPerCell * 1109124029);
            var vertexCnt = 0;

            for (var x = 0; x < SideCellCount; x++)
            {
                var lcoordX      = lcoord.X + x;
                var originY      = 1;
                var colVertexCnt = 0;
                var originX      = polyNum;

                for (var y = 0; y < SideCellCount; y++)
                {
                    var lcoordY = (int)lcoord.Y + y;
                    var magicB  = seedB;
                    var magicA  = seedA + 1813693831;

                    for (var i = 0; i < LandDefs.VertexPerCell; i++)
                    {
                        var idxI = vertexCnt + i;
                        var idxJ = colVertexCnt;

                        for (var j = 0; j < LandDefs.VertexPerCell; j++)
                        {
                            var splitDir = (uint)(((int)lcoord.Y * LandDefs.VertexPerCell + idxJ) * magicA - magicB - 1369149221);
                            var polyIdx  = (LandDefs.VertexPerCell * i + j) * 2;

                            var cellIdx     = x * SideCellCount + y;
                            var vertIdx     = idxI * SideVertexCount + idxJ;
                            var firstVertex = (idxI * SidePolyCount + idxJ) * 2;
                            var nextVertIdx = (idxI + 1) * SideVertexCount + idxJ;

                            var lcell = (LandCell)LandCells[cellIdx];

                            if (splitDir * 2.3283064e-10 < 0.5f)
                            {
                                //  2    1---0
                                //  | \   \  |
                                //  |  \   \ |
                                //  0---1    2

                                SWtoNEcut[cellIdx] = false;

                                lcell.Polygons[polyIdx]     = AddPolygon(firstVertex, vertIdx, nextVertIdx, vertIdx + 1);
                                lcell.Polygons[polyIdx + 1] = AddPolygon(firstVertex + 1, nextVertIdx + 1, vertIdx + 1, nextVertIdx);
                            }
                            else
                            {
                                //     2   2---1
                                //    / |  |  /
                                //   /  |  | /
                                //  0---1  0

                                SWtoNEcut[cellIdx] = true;

                                lcell.Polygons[polyIdx]     = AddPolygon(firstVertex, vertIdx, nextVertIdx, nextVertIdx + 1);
                                lcell.Polygons[polyIdx + 1] = AddPolygon(firstVertex + 1, vertIdx, nextVertIdx + 1, vertIdx + 1);
                            }
                            idxJ++;
                        }
                        magicA += 214614067;
                        magicB += 1109124029;
                    }

                    var cellID   = (uint)LandDefs.lcoord_to_gid(lcoordX, lcoordY);
                    var landCell = LandCells[x * SideCellCount + y];
                    landCell.ID                 = cellID;
                    landCell.Pos.ObjCellID      = cellID;
                    landCell.Pos.Frame.Origin.X = originX * LandDefs.HalfSquareLength;
                    landCell.Pos.Frame.Origin.Y = originY * LandDefs.HalfSquareLength;

                    originY      += 2;
                    colVertexCnt += LandDefs.VertexPerCell;
                }
                vertexCnt += LandDefs.VertexPerCell;
                seedB     += 1109124029 * (uint)LandDefs.VertexPerCell;
                seedA     += 214614067 * (uint)LandDefs.VertexPerCell;
                polyNum   += 2;
            }
        }
Example #23
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);
        }
Example #24
0
        public uint get_terrain(uint cellID, Vector3 point)
        {
            var lcoord = LandDefs.gid_to_lcoord(cellID).Value;

            return(Terrain[(int)lcoord.X * 255 * 9 + (int)lcoord.Y]);
        }
Example #25
0
        public static ObjCell find_cell_list(Position position, int numSphere, List <Sphere> sphere, CellArray cellArray, ObjCell currCell, SpherePath path)
        {
            cellArray.NumCells     = 0;
            cellArray.AddedOutside = false;

            var cell = GetVisible(position.ObjCellID);

            if ((position.ObjCellID & 0xFFFF) >= 0x100)
            {
                if (path != null)
                {
                    path.HitsInteriorCell = true;
                }

                cellArray.add_cell(position.ObjCellID, cell);
            }
            else
            {
                LandCell.add_all_outside_cells(position, numSphere, sphere, cellArray);
            }

            if (cell != null && numSphere != 0)
            {
                foreach (var otherCell in cellArray.Cells)
                {
                    if (otherCell != null)
                    {
                        otherCell.find_transit_cells(position, numSphere, sphere, cellArray, path);
                    }
                }
                if (currCell != null)
                {
                    foreach (var otherCell in cellArray.Cells)
                    {
                        var blockOffset = LandDefs.GetBlockOffset(position.ObjCellID, otherCell.ID);
                        var localPoint  = sphere[0].Center - blockOffset;

                        if (otherCell.point_in_cell(localPoint) && (otherCell.ID & 0xFFFF) >= 0x100)
                        {
                            if (path != null)
                            {
                                path.HitsInteriorCell = true;
                            }
                            return(otherCell);
                        }
                    }
                }
            }
            if (!cellArray.LoadCells && (position.ObjCellID & 0xFFFF) >= 0x100)
            {
                foreach (var otherCell in cellArray.Cells)
                {
                    if (cell.ID != otherCell.ID)
                    {
                        continue;
                    }

                    var found = false;
                    foreach (var stab in cell.StabList)
                    {
                        if (otherCell.ID == stab)
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        cellArray.remove_cell(otherCell);
                    }
                }
            }
            return(null);
        }
Example #26
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);
        }