public static unsafe bool LineOfSight(Point3D org, Point3D dest) { if (!World.InRange(org, dest, Map.m_MaxLOSDistance)) { return(false); } Point3D point3D1 = dest; if (org.X > dest.X || org.X == dest.X && org.Y > dest.Y || org.X == dest.X && org.Y == dest.Y && org.Z > dest.Z) { Point3D point3D2 = org; org = dest; dest = point3D2; } Point3DList point3Dlist = Map.m_PathList; if (org == dest) { return(true); } if (point3Dlist.Count > 0) { point3Dlist.Clear(); } int num1 = dest.X - org.X; int num2 = dest.Y - org.Y; int num3 = dest.Z - org.Z; double num4 = Math.Sqrt((double)(num1 * num1 + num2 * num2)); double num5 = num3 == 0 ? num4 : Math.Sqrt(num4 * num4 + (double)(num3 * num3)); double num6 = (double)num2 / num5; double num7 = (double)num1 / num5; double num8 = (double)num3 / num5; double num9 = (double)org.Y; double num10 = (double)org.Z; double num11 = (double)org.X; Point3D last; while (Map.NumberBetween(num11, dest.X, org.X, 0.5) && Map.NumberBetween(num9, dest.Y, org.Y, 0.5) && Map.NumberBetween(num10, dest.Z, org.Z, 0.5)) { int x = (int)Math.Round(num11); int y = (int)Math.Round(num9); int z = (int)Math.Round(num10); if (point3Dlist.Count > 0) { last = point3Dlist.Last; if (last.X != x || last.Y != y || last.Z != z) { point3Dlist.Add(x, y, z); } } else { point3Dlist.Add(x, y, z); } num11 += num7; num9 += num6; num10 += num8; } if (point3Dlist.Count == 0) { return(true); } last = point3Dlist.Last; if (last != dest) { point3Dlist.Add(dest); } Point3D top1 = org; Point3D bottom = dest; Map.FixPoints(ref top1, ref bottom); int count = point3Dlist.Count; MapPackage cache = Map.GetCache(); for (int index1 = 0; index1 < count; ++index1) { Point3D point3D2 = point3Dlist[index1]; int index2 = point3D2.X - cache.CellX; int index3 = point3D2.Y - cache.CellY; if (index2 < 0 || index3 < 0 || (index2 >= Renderer.cellWidth || index3 >= Renderer.cellHeight)) { return(false); } ArrayList arrayList = cache.cells[index2, index3]; bool flag1 = false; bool flag2 = false; for (int index4 = 0; index4 < arrayList.Count; ++index4) { ICell cell = (ICell)arrayList[index4]; if (cell is LandTile) { LandTile landTile = (LandTile)cell; for (int index5 = 0; index5 < Map.m_InvalidLandTiles.Length; ++index5) { if ((int)landTile.ID == Map.m_InvalidLandTiles[index5]) { flag1 = true; break; } } int z = 0; int avg = 0; int top2 = 0; Map.GetAverageZ(point3D2.X, point3D2.Y, ref z, ref avg, ref top2); if (z <= point3D2.Z && top2 >= point3D2.Z && (point3D2.X != point3D1.X || point3D2.Y != point3D1.Y || (z > point3D1.Z || top2 < point3D1.Z)) && !landTile.Ignored) { return(false); } } else if (cell is StaticItem) { flag2 = true; StaticItem staticItem = (StaticItem)cell; var itemDataPointer = staticItem.ItemDataPointer; TileFlag tileFlag = itemDataPointer->Flags; int num12 = (int)itemDataPointer->Height; if ((tileFlag & (TileFlag)1024L) != 0L) { num12 /= 2; } if ((int)staticItem.m_Z <= point3D2.Z && (int)staticItem.m_Z + num12 >= point3D2.Z && (tileFlag & (TileFlag)12288L) != 0L && (point3D2.X != point3D1.X || point3D2.Y != point3D1.Y || ((int)staticItem.m_Z > point3D1.Z || (int)staticItem.m_Z + num12 < point3D1.Z))) { return(false); } } else if (cell is DynamicItem) { flag2 = true; DynamicItem dynamicItem = (DynamicItem)cell; var itemDataPointer = Map.GetItemDataPointer(dynamicItem.ItemId); TileFlag tileFlag = (TileFlag)itemDataPointer->Flags; int num12 = (int)itemDataPointer->Height; if ((tileFlag & (TileFlag)1024L) != 0L) { num12 /= 2; } if ((int)dynamicItem.m_Z <= point3D2.Z && (int)dynamicItem.m_Z + num12 >= point3D2.Z && (tileFlag & (TileFlag)12288L) != 0L && (point3D2.X != point3D1.X || point3D2.Y != point3D1.Y || ((int)dynamicItem.m_Z > point3D1.Z || (int)dynamicItem.m_Z + num12 < point3D1.Z))) { return(false); } } } if (flag1 && !flag2) { return(false); } } return(true); }
public static bool CanFit(int x, int y, int z, int height, bool checkMobiles, bool requireSurface) { MapPackage cache = Map.GetCache(); int index1 = x - cache.CellX; int index2 = y - cache.CellY; if (index1 < 0 || index2 < 0 || (index1 >= Renderer.cellWidth || index2 >= Renderer.cellHeight)) { return(false); } bool flag1 = !requireSurface; ArrayList arrayList = cache.cells[index1, index2]; for (int index3 = 0; index3 < arrayList.Count; ++index3) { object obj = arrayList[index3]; if (obj is LandTile) { LandTile landTile = obj as LandTile; int z1 = 0; int avg = 0; int top = 0; Map.GetAverageZ(x, y, ref z1, ref avg, ref top); TileFlags landFlags = Map.GetLandFlags((int)landTile.ID & 16383); if (landFlags[(TileFlag)64L] && avg > z && z + height > z1) { return(false); } if (!landFlags[(TileFlag)64L] && z == avg && !landTile.Ignored) { flag1 = true; } } else if (obj is StaticItem) { StaticItem staticItem = obj as StaticItem; TileFlags tileFlags = Map.m_ItemFlags[(int)staticItem.ID & 16383]; bool flag2 = tileFlags[(TileFlag)512L]; bool flag3 = tileFlags[(TileFlag)64L]; if ((flag2 || flag3) && ((int)staticItem.Z + (int)staticItem.CalcHeight > z && z + height > (int)staticItem.Z)) { return(false); } if (flag2 && !flag3 && z == (int)staticItem.Z + (int)staticItem.CalcHeight) { flag1 = true; } } else if (obj is DynamicItem) { DynamicItem dynamicItem = obj as DynamicItem; TileFlags tileFlags = Map.m_ItemFlags[(int)dynamicItem.ID & 16383]; bool flag2 = tileFlags[(TileFlag)512L]; bool flag3 = tileFlags[(TileFlag)64L]; if ((flag2 || flag3) && ((int)dynamicItem.Z + (int)dynamicItem.CalcHeight > z && z + height > (int)dynamicItem.Z)) { return(false); } if (flag2 && !flag3 && z == (int)dynamicItem.Z + (int)dynamicItem.CalcHeight) { flag1 = true; } } else if (checkMobiles && obj is MobileCell) { MobileCell mobileCell = obj as MobileCell; if ((int)mobileCell.Z + 16 > z && z + (int)mobileCell.Height > (int)mobileCell.Z) { return(false); } } } return(flag1); }
public static MapPackage GetMap(int X, int Y, int W, int H) { if (Map.m_X == X && Map.m_Y == Y && (Map.m_Width == W && Map.m_Height == H) && (Map.m_World == Engine.m_World && Map.m_IsCached && !Map.m_QueueInvalidate)) { return(Map.m_Cached); } Map.m_QueueInvalidate = false; if (Map.m_Cached.cells != null) { int length1 = Map.m_Cached.cells.GetLength(0); int length2 = Map.m_Cached.cells.GetLength(1); for (int index1 = 0; index1 < length1; ++index1) { for (int index2 = 0; index2 < length2; ++index2) { ArrayList arrayList = Map.m_Cached.cells[index1, index2]; if (arrayList != null) { int count = arrayList.Count; for (int index3 = 0; index3 < count; ++index3) { ((IDisposable)arrayList[index3]).Dispose(); } } } } } Map.m_X = X; Map.m_Y = Y; Map.m_Width = W; Map.m_Height = H; Map.m_World = Engine.m_World; if (Map.m_StrongReferences == null) { Map.m_StrongReferences = new MapBlock[W * H]; } int length3 = W << 3; int length4 = H << 3; if (Map.m_CellPool == null) { Map.m_CellPool = new ArrayList[length3, length4]; for (int index1 = 0; index1 < length3; ++index1) { for (int index2 = 0; index2 < length4; ++index2) { Map.m_CellPool[index1, index2] = new ArrayList(4); } } } else { for (int index1 = 0; index1 < length3; ++index1) { for (int index2 = 0; index2 < length4; ++index2) { ArrayList arrayList = Map.m_CellPool[index1, index2]; for (int index3 = 0; index3 < arrayList.Count; ++index3) { AgentCell agentCell = arrayList[index3] as AgentCell; if (agentCell != null) { agentCell.Owner = (ArrayList)null; } } arrayList.Clear(); } } } if (Map.m_LandTiles == null) { Map.m_LandTiles = new LandTile[length3, length4]; for (int index1 = 0; index1 < length3; ++index1) { for (int index2 = 0; index2 < length4; ++index2) { Map.m_LandTiles[index1, index2] = new LandTile(); Map.m_LandTiles[index1, index2].x = index1; Map.m_LandTiles[index1, index2].y = index2; } } } if (Map.m_IndexPool == null) { Map.m_IndexPool = new byte[length3, length4]; } if (Map.m_FlagPool == null) { Map.m_FlagPool = new byte[length3, length4]; } ArrayList[,] arrayListArray = Map.m_CellPool; IComparer comparer = TileSorter.Comparer; Engine.Multis.Update(new MapPackage() { cells = arrayListArray, CellX = X << 3, CellY = Y << 3 }); int num1 = Engine.m_World; TileMatrix matrix = Map.GetMatrix(num1); Viewport viewport = World.Viewport; int num2 = 0; int x1 = X; while (num2 < W) { int num3 = 0; int y1 = Y; while (num3 < H) { MapBlock block = matrix.GetBlock(x1, y1); Map.m_StrongReferences[num3 * W + num2] = block; HuedTile[][][] huedTileArray1 = block == null ? matrix.EmptyStaticBlock : block.m_StaticTiles; if (block != null) { Tile[] tileArray = block.m_LandTiles; } else { Tile[] invalidLandBlock = matrix.InvalidLandBlock; } int index1 = 0; int x2 = x1 << 3; int index2 = num2 << 3; while (index1 < 8) { int index3 = 0; int y2 = y1 << 3; int index4 = num3 << 3; while (index3 < 8) { HuedTile[] huedTileArray2 = huedTileArray1[index1][index3]; for (int influence = 0; influence < huedTileArray2.Length; ++influence) { arrayListArray[index2, index4].Add((object)StaticItem.Instantiate(huedTileArray2[influence], influence, x2 * matrix.Height + y2 | influence << 25)); } LandTile landTile = viewport.GetLandTile(x2, y2, num1); landTile.x = index2; landTile.y = index4; arrayListArray[index2, index4].Add((object)landTile); ++index3; ++y2; ++index4; } ++index1; ++x2; ++index2; } ++num3; ++y1; } ++num2; ++x1; } int num4 = X << 3; int num5 = Y << 3; foreach (Item obj in World.Items.Values) { if (obj.InWorld && obj.Visible && !obj.IsMulti) { int index1 = obj.X - num4; int index2 = obj.Y - num5; if (index1 >= 0 && index1 < length3 && (index2 >= 0 && index2 < length4)) { AgentCell agentCell = obj.AcquireViewportCell(); arrayListArray[index1, index2].Add((object)agentCell); agentCell.Owner = arrayListArray[index1, index2]; } } } foreach (Mobile mobile in World.Mobiles.Values) { if (mobile.InWorld && mobile.Visible) { int index1 = mobile.X - num4; int index2 = mobile.Y - num5; if (index1 >= 0 && index1 < length3 && (index2 >= 0 && index2 < length4)) { AgentCell agentCell = mobile.AcquireViewportCell(); arrayListArray[index1, index2].Add((object)agentCell); agentCell.Owner = arrayListArray[index1, index2]; } } } for (int index1 = 0; index1 < length3; ++index1) { for (int index2 = 0; index2 < length4; ++index2) { ArrayList arrayList = arrayListArray[index1, index2]; if (arrayList.Count > 1) { arrayList.Sort(comparer); } } } MapPackage mapPackage = new MapPackage(); mapPackage.cells = arrayListArray; mapPackage.CellX = X << 3; mapPackage.CellY = Y << 3; Map.m_Cached = mapPackage; Map.m_IsCached = true; for (int index = -1; index <= H; ++index) { Engine.QueueMapLoad(X - 1, Y + index, matrix); } for (int index = 0; index < W; ++index) { Engine.QueueMapLoad(X + index, Y - 1, matrix); Engine.QueueMapLoad(X + index, Y + H, matrix); } for (int index = -1; index <= H; ++index) { Engine.QueueMapLoad(X + W, Y + index, matrix); } return(mapPackage); }
private static unsafe void GetStartZ(int xStart, int yStart, int zStart, out int zLow, out int zTop) { MapPackage cache = Map.GetCache(); int X = xStart - cache.CellX; int Y = yStart - cache.CellY; if (!Map.IsValid(X, Y)) { zLow = zStart; zTop = zStart; } else { LandTile landTile = World.Viewport.GetLandTile(xStart, yStart, Engine.m_World); ArrayList arrayList = cache.cells[X, Y]; bool impassable = landTile.Impassable; bool flag1 = (int)landTile.m_ID != 2 && (int)landTile.m_ID != 475 && ((int)landTile.m_ID < 430 || (int)landTile.m_ID > 437); int z = 0; int avg = 0; int top = 0; Map.GetAverageZ(xStart, yStart, ref z, ref avg, ref top); int num1 = zLow = zTop = 0; bool flag2 = false; if (flag1 && !impassable && zStart >= avg && (!flag2 || avg >= num1)) { zLow = z; num1 = avg; if (!flag2 || top > zTop) { zTop = top; } flag2 = true; } for (int index = 0; index < arrayList.Count; ++index) { IItem obj = arrayList[index] as IItem; if (obj != null) { ItemData *itemDataPointer = Map.GetItemDataPointer(obj.ItemId); TileFlag tileFlag = (TileFlag)itemDataPointer->Flags; if ((tileFlag & (TileFlag)512L) != 0L) { bool flag3 = (tileFlag & (TileFlag)1024L) != 0L; byte num2 = (byte)itemDataPointer->Height; int num3 = (int)obj.Z; int num4 = num3 + (flag3 ? (int)num2 / 2 : (int)num2); int num5 = num3 + itemDataPointer->Height; if (zStart >= num4 && (!flag2 || num4 >= num1)) { num1 = num4; if (!flag2 || num5 > zTop) { zTop = num5; } zLow = num3; flag2 = true; } } } } if (!flag2) { zLow = zTop = zStart; } else { if (zStart <= zTop) { return; } zTop = zStart; } } }
public static bool CheckMovement(int xStart, int yStart, int zStart, int dir, out int zNew) { Mobile player = World.Player; if (player == null) { zNew = 0; return(false); } int x = xStart; int y = yStart; Walking.Offset(dir, ref x, ref y); MapPackage cache = Map.GetCache(); int X = x - cache.CellX; int Y = y - cache.CellY; if (!Map.IsValid(X, Y)) { zNew = 0; return(false); } ArrayList tiles = cache.cells[X, Y]; LandTile landTile1 = World.Viewport.GetLandTile(x, y, Engine.m_World); LandTile landTile2 = World.Viewport.GetLandTile(xStart, yStart, Engine.m_World); try { if (player.Notoriety == Notoriety.Murderer) { if (landTile1.m_Guarded) { if (!Options.Current.SiegeRuleset) { if (!landTile2.m_Guarded) { if ((Control.ModifierKeys & (Keys.Shift | Keys.Control)) != (Keys.Shift | Keys.Control)) { zNew = 0; return(false); } } } } } } catch { } bool impassable = landTile1.Impassable; bool flag1 = (int)landTile1.m_ID != 2 && (int)landTile1.m_ID != 475 && ((int)landTile1.m_ID < 430 || (int)landTile1.m_ID > 437); int z1 = 0; int avg = 0; int top = 0; Map.GetAverageZ(x, y, ref z1, ref avg, ref top); int zLow; int zTop; Walking.GetStartZ(xStart, yStart, zStart, out zLow, out zTop); zNew = zLow; bool flag2 = false; int num1 = zTop + 2; int num2 = zLow + 16; bool ignoreDoors = player.Ghost || (int)player.Body == 987; bool ignoreMobs = ignoreDoors || player.CurrentStamina == player.MaximumStamina || Engine.m_World != 0; if (Engine.m_Stealth) { ignoreMobs = false; } for (int index = 0; index < tiles.Count; ++index) { ICell cell = (ICell)tiles[index]; if (cell is StaticItem) { StaticItem staticItem = (StaticItem)cell; TileFlags tileFlags = Map.m_ItemFlags[(int)staticItem.m_RealID]; if (tileFlags[(TileFlag)512L] && !tileFlags[(TileFlag)64L]) { int num3 = (int)staticItem.m_Z; int num4 = num3; int ourZ = num3 + (int)staticItem.CalcHeight; int ourTop = num2; if (flag2) { int num5 = Math.Abs(ourZ - player.Z) - Math.Abs(zNew - player.Z); if (num5 > 0 || num5 == 0 && ourZ > zNew) { continue; } } if (ourZ + 16 > ourTop) { ourTop = ourZ + 16; } if (!tileFlags[(TileFlag)1024L]) { num4 += (int)staticItem.Height; } if (num1 >= num4) { int num5 = num3; int num6 = (int)staticItem.Height < 2 ? num5 + (int)staticItem.Height : num5 + 2; if ((!flag1 || num6 >= avg || (avg <= ourZ || ourTop <= z1)) && Walking.IsOk(ignoreMobs, ignoreDoors, ourZ, ourTop, tiles)) { zNew = ourZ; flag2 = true; } } } } else if (cell is DynamicItem) { Item obj = ((DynamicItem)cell).m_Item; TileFlags tileFlags = Map.m_ItemFlags[obj.ID]; if (tileFlags[(TileFlag)512L] && !tileFlags[(TileFlag)64L]) { int z2 = obj.Z; int num3 = z2; int num4 = z2; int height = obj.Height; int ourZ = !tileFlags[(TileFlag)1024L] ? num4 + height : num4 + height / 2; if (flag2) { int num5 = Math.Abs(ourZ - player.Z) - Math.Abs(zNew - player.Z); if (num5 > 0 || num5 == 0 && ourZ > zNew) { continue; } } int ourTop = num2; if (ourZ + 16 > ourTop) { ourTop = ourZ + 16; } if (!tileFlags[(TileFlag)1024L]) { num3 += height; } if (num1 >= num3) { int num5 = z2; int num6 = height < 2 ? num5 + height : num5 + 2; if ((!flag1 || num6 >= avg || (avg <= ourZ || ourTop <= z1)) && Walking.IsOk(ignoreMobs, ignoreDoors, ourZ, ourTop, tiles)) { zNew = ourZ; flag2 = true; } } } } } if (flag1 && !impassable && num1 >= z1) { int ourZ = avg; int ourTop = num2; if (ourZ + 16 > ourTop) { ourTop = ourZ + 16; } bool flag3 = true; if (flag2) { int num3 = Math.Abs(ourZ - player.Z) - Math.Abs(zNew - player.Z); if (num3 > 0 || num3 == 0 && ourZ > zNew) { flag3 = false; } } if (flag3 && Walking.IsOk(ignoreMobs, ignoreDoors, ourZ, ourTop, tiles)) { zNew = ourZ; flag2 = true; } } return(flag2); }
public void Update(MapPackage map) { int count1 = this.m_Items.Count; if (count1 == 0) { return; } int length1 = map.cells.GetLength(0); int length2 = map.cells.GetLength(1); int num1 = map.CellX; int num2 = map.CellY; int num3 = num1 + length1; int num4 = num2 + length2; int houseLevel = Options.Current.HouseLevel; for (int index1 = 0; index1 < count1; ++index1) { Item obj = (Item)this.m_Items[index1]; if (obj.InWorld) { CustomMultiEntry customMulti = CustomMultiLoader.GetCustomMulti(obj.Serial, obj.Revision); Multi multi = (Multi)null; if (customMulti != null) { multi = customMulti.Multi; } if (multi == null) { multi = obj.Multi; } if (multi != null) { int xMin; int yMin; int xMax; int yMax; multi.GetBounds(out xMin, out yMin, out xMax, out yMax); xMin += obj.X; yMin += obj.Y; xMax += obj.X; yMax += obj.Y; if (xMin < num3 && xMax >= num1 && (yMin < num4 && yMax >= num2)) { ArrayList list = multi.List; int count2 = list.Count; int num5 = int.MinValue | index1; for (int index2 = 0; index2 < count2; ++index2) { MultiItem multiItem = (MultiItem)list[index2]; if (multiItem.Flags != 0 || index2 == 0) { int num6 = obj.X + (int)multiItem.X; int num7 = obj.Y + (int)multiItem.Y; int index3 = num6 - num1; int index4 = num7 - num2; if (index3 >= 0 && index3 < length1 && (index4 >= 0 && index4 < length2)) { bool flag = true; int num8 = (int)multiItem.ItemID; if (flag) { map.cells[index3, index4].Add((object)StaticItem.Instantiate((short)num8, multiItem.ItemID, (sbyte)(obj.Z + (int)multiItem.Z), num5 | index2 << 16)); } } } } } } } } }