/// <summary> /// Determines if a new carpet can be placed at the given point. If a carpet cannot fit because /// of Z-index clashes, the Z-index is modified until the carpet can fit. /// </summary> public bool CanFit(ref Point3D p) { if (Map == null || Map == Map.Internal || Deleted || Carpet == null || Carpet.Deleted) { return(false); } MultiComponentList mcl = MultiData.GetComponents(Carpet.ItemID); int topZ = p.Z; for (int x = 0; x < mcl.Width; x++) { for (int y = 0; y < mcl.Height; y++) { int tx = (p.X + mcl.Min.X + x); int ty = (p.Y + mcl.Min.Y + y); LandTile landTile = Map.Tiles.GetLandTile(tx, ty); StaticTile[] statics = Map.Tiles.GetStaticTiles(tx, ty, true); topZ = Math.Max(topZ, Map.GetAverageZ(tx, ty)); for (int i = 0; i < statics.Length; i++) { StaticTile t = statics[i]; if (t.Z > p.Z && (p.Z + 12) > t.Z) //if it's above, and our top would hit its bottom { return(false); } else if (t.Z < p.Z && (t.Z + t.Height) > p.Z) //if it's below, and its top would hit our bottom { return(false); } } object obj = Map.GetTopSurface(p); if (obj is LandTile) { LandTile t = (LandTile)obj; if (t.Z > p.Z) { return(false); } } else if (obj is StaticTile) { StaticTile t = (StaticTile)obj; if (t.Z > p.Z) { return(false); } } else if (obj is Item) { Item i = obj as Item; if (i.GetWorldTop().Z > p.Z) { return(false); } } if (mcl.Tiles[x][y].Length == 0 || Carpet.Contains(tx, ty)) { continue; } if (!Map.CanFit(tx, ty, Z, 12, false, true, false)) { return(false); } } } IPooledEnumerable eable = Map.GetItemsInBounds(new Rectangle2D((p.X + mcl.Min.X), (p.Y + mcl.Min.Y), mcl.Width, mcl.Height)); foreach (Item i in eable) { if (i.ItemID >= 0x4000 || i.Z < p.Z || !i.Visible) { continue; } int x = (i.X - p.X + mcl.Min.X); int y = (i.Y - p.Y + mcl.Min.Y); if (x >= 0 && x < mcl.Width && y >= 0 && y < mcl.Height && mcl.Tiles[x][y].Length == 0) { continue; } else if (Carpet.Contains(i)) { continue; } eable.Free(); return(false); } eable.Free(); p.Z = topZ + 1; return(true); }