public void AddRange( StaticTile[] tiles ) { if ( (m_Count + tiles.Length) > m_Tiles.Length ) { StaticTile[] old = m_Tiles; m_Tiles = new StaticTile[(m_Count + tiles.Length) * 2]; for ( int i = 0; i < old.Length; ++i ) m_Tiles[i] = old[i]; } for ( int i = 0; i < tiles.Length; ++i ) m_Tiles[m_Count++] = tiles[i]; }
public StaticTile[] ToArray() { if ( m_Count == 0 ) return m_EmptyTiles; StaticTile[] tiles = new StaticTile[m_Count]; for ( int i = 0; i < m_Count; ++i ) tiles[i] = m_Tiles[i]; m_Count = 0; return tiles; }
private bool IsOk(bool ignoreDoors, bool ignoreSpellFields, int ourZ, int ourTop, StaticTile[] tiles, List<Item> items) { for (int i = 0; i < tiles.Length; ++i) { StaticTile check = tiles[i]; ItemData itemData = TileData.ItemTable[check.ID & TileData.MaxItemValue]; if ((itemData.Flags & ImpassableSurface) != 0) // Impassable || Surface { int checkZ = check.Z; int checkTop = checkZ + itemData.CalcHeight; if (checkTop > ourZ && ourTop > checkZ) return false; } } for (int i = 0; i < items.Count; ++i) { Item item = items[i]; int itemID = item.ItemID & TileData.MaxItemValue; ItemData itemData = TileData.ItemTable[itemID]; TileFlag flags = itemData.Flags; if ((flags & ImpassableSurface) != 0) // Impassable || Surface { if (ignoreDoors && ((flags & TileFlag.Door) != 0 || itemID == 0x692 || itemID == 0x846 || itemID == 0x873 || (itemID >= 0x6F5 && itemID <= 0x6F6))) continue; if (ignoreSpellFields && (itemID == 0x82 || itemID == 0x3946 || itemID == 0x3956)) continue; int checkZ = item.Z; int checkTop = checkZ + itemData.CalcHeight; if (checkTop > ourZ && ourTop > checkZ) return false; } } return true; }
void moving() { counter -= Time.deltaTime; fireCounter -= Time.deltaTime; delay -= Time.deltaTime; if (delay >= 0) return; delay = delayVal; move (); if (counter <= 0) { counter = counterLimit; switchDirection(currentWall); } if (fireCounter <= 0) { fireCounter = fireCounterLimit; movementState = fire; } lastTile = currentTile; //=====color code===== currentTile = currentPath [currentWall] [(int)(position2D.x), (int)(position2D.y)]; //currentTile.renderer.material.color = activeColor; if (currentTile != lastTile) currentTileComp = currentTile.GetComponent<StaticTile>(); currentTileComp.changeColor (activeColor, 0.012f, false); }
public void RemoveStaticTile(StaticTile iStaticTile) { this.m_StaticTiles.Remove(iStaticTile); }
public static Map mergeInto(this Map t, Map map, Vector2 position, Microsoft.Xna.Framework.Rectangle?sourceArea = null, bool includeEmpty = true, bool properties = true) { Microsoft.Xna.Framework.Rectangle sourceRectangle = sourceArea.HasValue ? sourceArea.Value : new Microsoft.Xna.Framework.Rectangle(0, 0, t.DisplayWidth / Game1.tileSize, t.DisplayHeight / Game1.tileSize); foreach (TileSheet tilesheet in t.TileSheets) { if (!map.hasTileSheet(tilesheet)) { map.AddTileSheet(new TileSheet(tilesheet.Id, map, tilesheet.ImageSource, tilesheet.SheetSize, tilesheet.TileSize)); } } for (Vector2 _x = new Vector2(sourceRectangle.X, position.X); _x.X < sourceRectangle.Width; _x += new Vector2(1, 1)) { for (Vector2 _y = new Vector2(sourceRectangle.Y, position.Y); _y.X < sourceRectangle.Height; _y += new Vector2(1, 1)) { foreach (Layer layer in t.Layers) { Tile sourceTile = layer.Tiles[(int)_x.X, (int)_y.X]; Layer mapLayer = map.GetLayer(layer.Id); if (mapLayer == null) { map.InsertLayer(new Layer(layer.Id, map, map.Layers[0].LayerSize, map.Layers[0].TileSize), map.Layers.Count); mapLayer = map.GetLayer(layer.Id); } if (sourceTile == null) { if (includeEmpty) { try { mapLayer.Tiles[(int)_x.Y, (int)_y.Y] = null; } catch { } } continue; } TileSheet tilesheet = map.GetTileSheet(sourceTile.TileSheet.Id); Tile newTile = new StaticTile(mapLayer, tilesheet, BlendMode.Additive, sourceTile.TileIndex); if (sourceTile is AnimatedTile aniTile) { List <StaticTile> staticTiles = new List <StaticTile>(); foreach (StaticTile frame in aniTile.TileFrames) { staticTiles.Add(new StaticTile(mapLayer, tilesheet, BlendMode.Additive, frame.TileIndex)); } newTile = new AnimatedTile(mapLayer, staticTiles.ToArray(), aniTile.FrameInterval); } if (properties) { foreach (var prop in sourceTile.Properties) { newTile.Properties.Add(prop); } } try { mapLayer.Tiles[(int)_x.Y, (int)_y.Y] = newTile; }catch (Exception e) { Monitor.Log($"{e.Message} ({map.DisplayWidth} -> {layer.Id} -> {_x.Y}:{_y.Y})"); } } } } return(map); }
private void GetStartZ(Mobile m, Map map, Point3D loc, List <Item> itemList, out int zLow, out int zTop) { int xCheck = loc.X, yCheck = loc.Y; LandTile landTile = map.Tiles.GetLandTile(xCheck, yCheck); int landZ = 0, landCenter = 0, landTop = 0; bool landBlocks = (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Impassable) != 0; if (landBlocks && m.CanSwim && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Wet) != 0) { landBlocks = false; } else if (m.CantWalk && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Wet) == 0) { landBlocks = true; } map.GetAverageZ(xCheck, yCheck, ref landZ, ref landCenter, ref landTop); bool considerLand = !landTile.Ignored; int zCenter = zLow = zTop = 0; bool isSet = false; if (considerLand && !landBlocks && loc.Z >= landCenter) { zLow = landZ; zCenter = landCenter; if (!isSet || landTop > zTop) { zTop = landTop; } isSet = true; } StaticTile[] staticTiles = map.Tiles.GetStaticTiles(xCheck, yCheck, true); for (int i = 0; i < staticTiles.Length; ++i) { StaticTile tile = staticTiles[i]; ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; int calcTop = (tile.Z + id.CalcHeight); if ((!isSet || calcTop >= zCenter) && ((id.Flags & TileFlag.Surface) != 0 || (m.CanSwim && (id.Flags & TileFlag.Wet) != 0)) && loc.Z >= calcTop) { if (m.CantWalk && (id.Flags & TileFlag.Wet) == 0) { continue; } zLow = tile.Z; zCenter = calcTop; int top = tile.Z + id.Height; if (!isSet || top > zTop) { zTop = top; } isSet = true; } } for (int i = 0; i < itemList.Count; ++i) { Item item = itemList[i]; ItemData id = item.ItemData; int calcTop = item.Z + id.CalcHeight; if ((!isSet || calcTop >= zCenter) && ((id.Flags & TileFlag.Surface) != 0 || (m.CanSwim && (id.Flags & TileFlag.Wet) != 0)) && loc.Z >= calcTop) { if (m.CantWalk && (id.Flags & TileFlag.Wet) == 0) { continue; } zLow = item.Z; zCenter = calcTop; int top = item.Z + id.Height; if (!isSet || top > zTop) { zTop = top; } isSet = true; } } if (!isSet) { zLow = zTop = loc.Z; } else if (loc.Z > zTop) { zTop = loc.Z; } }
private void StaticImport(string filename) { StreamReader ip = new StreamReader(filename); string line; StaticTile newTile = new StaticTile { m_ID = 0xFFFF, m_Hue = 0 }; int blockY; int blockX = blockY = 0; while ((line = ip.ReadLine()) != null) { if ((line = line.Trim()).Length == 0 || line.StartsWith("#") || line.StartsWith("//")) { continue; } try { if (line.StartsWith("SECTION WORLDITEM")) { if (newTile.m_ID != 0xFFFF) { _currMap.Tiles.AddPendingStatic(blockX, blockY, newTile); blockX = blockY = 0; } newTile = new StaticTile { m_ID = 0xFFFF, m_Hue = 0 }; } else if (line.StartsWith("ID")) { line = line.Remove(0, 2); line = line.TrimStart(' '); line = line.TrimEnd(' '); newTile.m_ID = Art.GetLegalItemID(Convert.ToUInt16(line)); } else if (line.StartsWith("X")) { line = line.Remove(0, 1); line = line.TrimStart(' '); line = line.TrimEnd(' '); int x = Convert.ToInt32(line); blockX = x >> 3; x &= 0x7; newTile.m_X = (byte)x; } else if (line.StartsWith("Y")) { line = line.Remove(0, 1); line = line.TrimStart(' '); line = line.TrimEnd(' '); int y = Convert.ToInt32(line); blockY = y >> 3; y &= 0x7; newTile.m_Y = (byte)y; } else if (line.StartsWith("Z")) { line = line.Remove(0, 1); line = line.TrimStart(' '); line = line.TrimEnd(' '); newTile.m_Z = Convert.ToSByte(line); } else if (line.StartsWith("COLOR")) { line = line.Remove(0, 5); line = line.TrimStart(' '); line = line.TrimEnd(' '); newTile.m_Hue = Convert.ToInt16(line); } } catch { // ignored } } if (newTile.m_ID != 0xFFFF) { _currMap.Tiles.AddPendingStatic(blockX, blockY, newTile); } ip.Close(); MessageBox.Show("Done", "Freeze Static", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); _currMap.ResetCache(); pictureBox.Invalidate(); }
public static async Task InspectObjectAsync() { (TargetType targetType, TargetFlags _, int serial, int x, int y, int z, int itemID) = await GetTargetInfoAsync(Strings.Target_object___); if (targetType == TargetType.Object && serial != 0) { Entity entity = UOMath.IsMobile(serial) ? (Entity)Engine.Mobiles.GetMobile(serial) : Engine.Items.GetItem(serial); if (entity == null) { return; } Thread t = new Thread(() => { ObjectInspectorWindow window = new ObjectInspectorWindow { DataContext = new ObjectInspectorViewModel(entity) }; window.ShowDialog(); }) { IsBackground = true }; t.SetApartmentState(ApartmentState.STA); t.Start(); } else { if (itemID == 0) { if (x == 65535 && y == 65535) { return; } LandTile landTile = MapInfo.GetLandTile((int)Engine.Player.Map, x, y); Thread t = new Thread(() => { ObjectInspectorWindow window = new ObjectInspectorWindow { DataContext = new ObjectInspectorViewModel(landTile) }; window.ShowDialog(); }) { IsBackground = true }; t.SetApartmentState(ApartmentState.STA); t.Start(); } else { StaticTile[] statics = Statics.GetStatics((int)Engine.Player.Map, x, y); if (statics == null) { return; } StaticTile selectedStatic = statics.FirstOrDefault(i => i.ID == itemID); if (selectedStatic.ID == 0) { selectedStatic = TileData.GetStaticTile(itemID); selectedStatic.X = x; selectedStatic.Y = y; selectedStatic.Z = z; } Thread t = new Thread(() => { ObjectInspectorWindow window = new ObjectInspectorWindow { DataContext = new ObjectInspectorViewModel(selectedStatic) }; window.ShowDialog(); }) { IsBackground = true }; t.SetApartmentState(ApartmentState.STA); t.Start(); } } }
private void StoreStaticTile(Stream stream, StaticTile staticTile) { StoreInt32(stream, staticTile.TileIndex); stream.WriteByte((byte)staticTile.BlendMode); StoreProperties(stream, staticTile); }
public Map PatchMapArea(Map map, Map patch, Point position, Rectangle?sourceArea = null, bool patchProperties = true, bool removeEmpty = false) { Rectangle sourceRectangle = sourceArea.HasValue ? sourceArea.Value : new Microsoft.Xna.Framework.Rectangle(0, 0, patch.DisplayWidth / Game1.tileSize, patch.DisplayHeight / Game1.tileSize); //tilesheet normalizing taken with permission from Content Patcher // https://github.com/Pathoschild/StardewMods/blob/stable/ContentPatcher/Framework/Patches/EditMapPatch.cs foreach (TileSheet tilesheet in patch.TileSheets) { TileSheet mapSheet = map.GetTileSheet(tilesheet.Id); if (mapSheet == null || mapSheet.ImageSource != tilesheet.ImageSource) { // change ID if needed so new tilesheets are added after vanilla ones (to avoid errors in hardcoded game logic) string id = tilesheet.Id; if (!id.StartsWith("z_", StringComparison.InvariantCultureIgnoreCase)) { id = $"z_{id}"; } // change ID if it conflicts with an existing tilesheet if (map.GetTileSheet(id) != null) { int disambiguator = Enumerable.Range(2, int.MaxValue - 1).First(p => map.GetTileSheet($"{id}_{p}") == null); id = $"{id}_{disambiguator}"; } //add tilesheet if (!map.TileSheets.ToList().Exists(ts => ts.Id == tilesheet.Id)) { map.AddTileSheet(new TileSheet(tilesheet.Id, map, tilesheet.ImageSource, tilesheet.SheetSize, tilesheet.TileSize)); } } } if (patchProperties) { foreach (KeyValuePair <string, PropertyValue> p in patch.Properties) { if (map.Properties.ContainsKey(p.Key)) { /*if (p.Key == "EntryAction") * map.Properties[p.Key] = map.Properties[p.Key] + ";" + p.Value; * else*/ map.Properties[p.Key] = p.Value; } else { map.Properties.Add(p); } } } for (int x = 0; x < sourceRectangle.Width; x++) { for (int y = 0; y < sourceRectangle.Height; y++) { foreach (Layer layer in patch.Layers) { int px = (int)position.X + x; int py = (int)position.Y + y; int sx = (int)sourceRectangle.X + x; int sy = (int)sourceRectangle.Y + y; Tile sourceTile = layer.Tiles[(int)sx, (int)sy]; Layer mapLayer = map.GetLayer(layer.Id); if (mapLayer == null) { map.InsertLayer(new Layer(layer.Id, map, map.Layers[0].LayerSize, map.Layers[0].TileSize), map.Layers.Count); mapLayer = map.GetLayer(layer.Id); } /*if (mapLayer.IsImageLayer()) * mapLayer.SetupImageLayer();*/ if (patchProperties) { foreach (var prop in layer.Properties) { if (!mapLayer.Properties.ContainsKey(prop.Key)) { mapLayer.Properties.Add(prop); } else { mapLayer.Properties[prop.Key] = prop.Value; } } } if (sourceTile == null) { if (removeEmpty) { try { mapLayer.Tiles[(int)px, (int)py] = null; } catch { } } continue; } TileSheet tilesheet = map.GetTileSheet(sourceTile.TileSheet.Id); Tile newTile = new StaticTile(mapLayer, tilesheet, BlendMode.Additive, sourceTile.TileIndex); try { if (sourceTile.Properties.ContainsKey("NoTileMerge")) { newTile = mapLayer.Tiles[(int)px, (int)py]; } } catch { } if (sourceTile is AnimatedTile aniTile) { List <StaticTile> staticTiles = new List <StaticTile>(); foreach (StaticTile frame in aniTile.TileFrames) { staticTiles.Add(new StaticTile(mapLayer, tilesheet, BlendMode.Additive, frame.TileIndex)); } newTile = new AnimatedTile(mapLayer, staticTiles.ToArray(), aniTile.FrameInterval); } if (patchProperties) { foreach (var prop in sourceTile.Properties) { if (newTile.Properties.ContainsKey(prop.Key)) { newTile.Properties[prop.Key] = prop.Value; } else { newTile.Properties.Add(prop); } } foreach (var prop in sourceTile.TileIndexProperties) { if (newTile.TileIndexProperties.ContainsKey(prop.Key)) { newTile.TileIndexProperties[prop.Key] = prop.Value; } else { newTile.TileIndexProperties.Add(prop); } } } try { mapLayer.Tiles[(int)px, (int)py] = newTile; } catch { } } } } return(map); }
private void OnClickCopy(object sender, EventArgs e) { string path = textBox1.Text; if (!Directory.Exists(path)) { MessageBox.Show("Path not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if (!(comboBoxMapID.SelectedItem is SupportedMaps replaceMap)) { MessageBox.Show("Invalid Map ID!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } int x1 = (int)numericUpDownX1.Value; int x2 = (int)numericUpDownX2.Value; int y1 = (int)numericUpDownY1.Value; int y2 = (int)numericUpDownY2.Value; int tox = (int)numericUpDownToX1.Value; int toy = (int)numericUpDownToY1.Value; if (x1 < 0 || x1 > replaceMap.Width) { MessageBox.Show("Invalid X1 coordinate!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if (x2 < 0 || x2 > replaceMap.Width) { MessageBox.Show("Invalid X2 coordinate!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if (y1 < 0 || y1 > replaceMap.Height) { MessageBox.Show("Invalid Y1 coordinate!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if (y2 < 0 || y2 > replaceMap.Height) { MessageBox.Show("Invalid Y2 coordinate!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if (x1 > x2 || y1 > y2) { MessageBox.Show("X1 and Y1 cannot be bigger than X2 and Y2!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if (tox < 0 || tox > _workingMap.Width || tox + (x2 - x1) > _workingMap.Width) { MessageBox.Show("Invalid toX coordinate!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if (toy < 0 || toy > _workingMap.Height || toy + (y2 - y1) > _workingMap.Height) { MessageBox.Show("Invalid toX coordinate!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } x1 >>= 3; x2 >>= 3; y1 >>= 3; y2 >>= 3; tox >>= 3; toy >>= 3; int tox2 = x2 - x1 + tox; int toy2 = y2 - y1 + toy; int blockY = _workingMap.Height >> 3; int blockX = _workingMap.Width >> 3; int blockYReplace = replaceMap.Height >> 3; // int blockxreplace = replacemap.Width >> 3; // TODO: unused variable? progressBar1.Step = 1; progressBar1.Value = 0; progressBar1.Maximum = 0; if (checkBoxMap.Checked) { progressBar1.Maximum += blockY * blockX; } if (checkBoxStatics.Checked) { progressBar1.Maximum += blockY * blockX; } if (checkBoxMap.Checked) { string copyMap = Path.Combine(path, $"map{replaceMap.Id}.mul"); if (!File.Exists(copyMap)) { MessageBox.Show("Map file not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } FileStream mMapCopy = new FileStream(copyMap, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader mMapReaderCopy = new BinaryReader(mMapCopy); string mapPath = Files.GetFilePath($"map{_workingMap.FileIndex}.mul"); BinaryReader mMapReader; if (mapPath != null) { FileStream mMap = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.Read); mMapReader = new BinaryReader(mMap); } else { MessageBox.Show("Map file not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } string mul = Path.Combine(Options.OutputPath, $"map{_workingMap.FileIndex}.mul"); using (FileStream fsMul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write)) { using (BinaryWriter binMul = new BinaryWriter(fsMul)) { for (int x = 0; x < blockX; ++x) { for (int y = 0; y < blockY; ++y) { if (tox <= x && x <= tox2 && toy <= y && y <= toy2) { mMapReaderCopy.BaseStream.Seek((((x - tox + x1) * blockYReplace) + (y - toy) + y1) * 196, SeekOrigin.Begin); int header = mMapReaderCopy.ReadInt32(); binMul.Write(header); } else { mMapReader.BaseStream.Seek(((x * blockY) + y) * 196, SeekOrigin.Begin); int header = mMapReader.ReadInt32(); binMul.Write(header); } for (int i = 0; i < 64; ++i) { ushort tileId; sbyte z; if (tox <= x && x <= tox2 && toy <= y && y <= toy2) { tileId = mMapReaderCopy.ReadUInt16(); z = mMapReaderCopy.ReadSByte(); } else { tileId = mMapReader.ReadUInt16(); z = mMapReader.ReadSByte(); } tileId = Art.GetLegalItemID(tileId); if (z < -128) { z = -128; } if (z > 127) { z = 127; } binMul.Write(tileId); binMul.Write(z); } progressBar1.PerformStep(); } } } } mMapReader.Close(); mMapReaderCopy.Close(); } if (checkBoxStatics.Checked) { string indexPath = Files.GetFilePath($"staidx{_workingMap.FileIndex}.mul"); BinaryReader mIndexReader; if (indexPath != null) { FileStream mIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); mIndexReader = new BinaryReader(mIndex); } else { MessageBox.Show("Static file not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } string staticsPath = Files.GetFilePath($"statics{_workingMap.FileIndex}.mul"); FileStream mStatics; BinaryReader mStaticsReader; if (staticsPath != null) { mStatics = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.Read); mStaticsReader = new BinaryReader(mStatics); } else { MessageBox.Show("Static file not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } string copyIndexPath = Path.Combine(path, $"staidx{replaceMap.Id}.mul"); if (!File.Exists(copyIndexPath)) { MessageBox.Show("Static file not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } FileStream mIndexCopy = new FileStream(copyIndexPath, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader mIndexReaderCopy = new BinaryReader(mIndexCopy); string copyStaticsPath = Path.Combine(path, $"statics{replaceMap.Id}.mul"); if (!File.Exists(copyStaticsPath)) { MessageBox.Show("Static file not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } FileStream mStaticsCopy = new FileStream(copyStaticsPath, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader mStaticsReaderCopy = new BinaryReader(mStaticsCopy); string idx = Path.Combine(Options.OutputPath, $"staidx{_workingMap.FileIndex}.mul"); string mul = Path.Combine(Options.OutputPath, $"statics{_workingMap.FileIndex}.mul"); using (FileStream fsIdx = new FileStream(idx, FileMode.Create, FileAccess.Write, FileShare.Write), fsMul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write)) { using (BinaryWriter binidx = new BinaryWriter(fsIdx), binmul = new BinaryWriter(fsMul)) { for (int x = 0; x < blockX; ++x) { for (int y = 0; y < blockY; ++y) { int lookup, length, extra; if (tox <= x && x <= tox2 && toy <= y && y <= toy2) { mIndexReaderCopy.BaseStream.Seek((((x - tox + x1) * blockYReplace) + (y - toy) + y1) * 12, SeekOrigin.Begin); lookup = mIndexReaderCopy.ReadInt32(); length = mIndexReaderCopy.ReadInt32(); extra = mIndexReaderCopy.ReadInt32(); } else { mIndexReader.BaseStream.Seek(((x * blockY) + y) * 12, SeekOrigin.Begin); lookup = mIndexReader.ReadInt32(); length = mIndexReader.ReadInt32(); extra = mIndexReader.ReadInt32(); } if (lookup < 0 || length <= 0) { binidx.Write(-1); // lookup binidx.Write(-1); // length binidx.Write(-1); // extra } else { if (tox <= x && x <= tox2 && toy <= y && y <= toy2) { mStaticsCopy.Seek(lookup, SeekOrigin.Begin); } else { mStatics.Seek(lookup, SeekOrigin.Begin); } int fsMulLength = (int)fsMul.Position; int count = length / 7; if (RemoveDupl.Checked) { var tileList = new StaticTile[count]; int j = 0; for (int i = 0; i < count; ++i) { StaticTile tile = new StaticTile(); if (tox <= x && x <= tox2 && toy <= y && y <= toy2) { tile.Id = mStaticsReaderCopy.ReadUInt16(); tile.X = mStaticsReaderCopy.ReadByte(); tile.Y = mStaticsReaderCopy.ReadByte(); tile.Z = mStaticsReaderCopy.ReadSByte(); tile.Hue = mStaticsReaderCopy.ReadInt16(); } else { tile.Id = mStaticsReader.ReadUInt16(); tile.X = mStaticsReader.ReadByte(); tile.Y = mStaticsReader.ReadByte(); tile.Z = mStaticsReader.ReadSByte(); tile.Hue = mStaticsReader.ReadInt16(); } if (tile.Id > Art.GetMaxItemID()) { continue; } if (tile.Hue < 0) { tile.Hue = 0; } bool first = true; for (int k = 0; k < j; ++k) { if (tileList[k].Id == tile.Id && tileList[k].X == tile.X && tileList[k].Y == tile.Y && tileList[k].Z == tile.Z && tileList[k].Hue == tile.Hue) { first = false; break; } } if (first) { tileList[j++] = tile; } } if (j > 0) { binidx.Write((int)fsMul.Position); //lookup for (int i = 0; i < j; ++i) { binmul.Write(tileList[i].Id); binmul.Write(tileList[i].X); binmul.Write(tileList[i].Y); binmul.Write(tileList[i].Z); binmul.Write(tileList[i].Hue); } } } else { bool firstItem = true; for (int i = 0; i < count; ++i) { ushort graphic; short sHue; byte sx, sy; sbyte sz; if (tox <= x && x <= tox2 && toy <= y && y <= toy2) { graphic = mStaticsReaderCopy.ReadUInt16(); sx = mStaticsReaderCopy.ReadByte(); sy = mStaticsReaderCopy.ReadByte(); sz = mStaticsReaderCopy.ReadSByte(); sHue = mStaticsReaderCopy.ReadInt16(); } else { graphic = mStaticsReader.ReadUInt16(); sx = mStaticsReader.ReadByte(); sy = mStaticsReader.ReadByte(); sz = mStaticsReader.ReadSByte(); sHue = mStaticsReader.ReadInt16(); } if (graphic > Art.GetMaxItemID()) { continue; } if (sHue < 0) { sHue = 0; } if (firstItem) { binidx.Write((int)fsMul.Position); // lookup firstItem = false; } binmul.Write(graphic); binmul.Write(sx); binmul.Write(sy); binmul.Write(sz); binmul.Write(sHue); } } fsMulLength = (int)fsMul.Position - fsMulLength; if (fsMulLength > 0) { binidx.Write(fsMulLength); // length binidx.Write(extra); // extra } else { binidx.Write(-1); // lookup binidx.Write(-1); // length binidx.Write(-1); // extra } } progressBar1.PerformStep(); } } } } mIndexReader.Close(); mStaticsReader.Close(); mIndexCopy.Close(); mStaticsReaderCopy.Close(); } MessageBox.Show($"Files saved to {Options.OutputPath}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); }
public static void OnLoad() { Console.WriteLine("Loading Ultima Live map changes"); if (!Directory.Exists(UltimaLiveSettings.UltimaLiveMapChangesSavePath)) { Directory.CreateDirectory(UltimaLiveSettings.UltimaLiveMapChangesSavePath); } string[] filePaths = Directory.GetFiles(UltimaLiveSettings.UltimaLiveMapChangesSavePath, "*.live"); List <string> staticsPaths = new List <string>(); List <string> landPaths = new List <string>(); foreach (string s in filePaths) { if (s.Contains("map")) { landPaths.Add(s); } else if (s.Contains("statics")) { staticsPaths.Add(s); } } landPaths.Sort(); //read map blocks and apply them in order foreach (string s in landPaths) { BinaryReader reader = new BinaryReader(File.Open(Path.Combine(Core.BaseDirectory, s), FileMode.Open)); try { reader.BaseStream.Seek(0, SeekOrigin.Begin); int MapNumber = reader.ReadUInt16(); while (reader.BaseStream.Position < reader.BaseStream.Length) { int x = (int)reader.ReadInt16(); int y = (int)reader.ReadInt16(); LandTile[] blocktiles = new LandTile[64]; for (int j = 0; j < 64; j++) { short id = reader.ReadInt16(); sbyte z = reader.ReadSByte(); LandTile lt = new LandTile(id, z); blocktiles[j] = lt; } List <int> associated; MapRegistry.MapAssociations.TryGetValue(MapNumber, out associated); foreach (int integer in associated) { Map map = Map.Maps[integer]; TileMatrix tm = map.Tiles; tm.SetLandBlock(x, y, blocktiles); } } } catch { Console.WriteLine("An error occured reading land changes at " + reader.BaseStream.Position); } finally { reader.Close(); } } staticsPaths.Sort(); //read statics blocks and apply them in order foreach (string s in staticsPaths) { FileInfo mapFile = new FileInfo(Path.Combine(Core.BaseDirectory, s)); BinaryReader reader = new BinaryReader(File.Open(Path.Combine(Core.BaseDirectory, s), FileMode.Open)); try { reader.BaseStream.Seek(0, SeekOrigin.Begin); int MapNumber = reader.ReadUInt16(); while (reader.BaseStream.Position < reader.BaseStream.Length) { int blockX = (int)reader.ReadInt16(); int blockY = (int)reader.ReadInt16(); int staticCount = reader.ReadInt32(); Dictionary <Point2D, List <StaticTile> > blockStatics = new Dictionary <Point2D, List <StaticTile> >(); for (int staticIndex = 0; staticIndex < staticCount; staticIndex++) { UInt16 id = reader.ReadUInt16(); byte x = reader.ReadByte(); byte y = reader.ReadByte(); sbyte z = reader.ReadSByte(); Int16 hue = reader.ReadInt16(); StaticTile st = new StaticTile(id, x, y, z, hue); Point2D p = new Point2D(x, y); if (!(blockStatics.ContainsKey(p))) { blockStatics.Add(p, new List <StaticTile>()); } blockStatics[p].Add(st); } StaticTile[][][] newblockOfTiles = new StaticTile[8][][]; for (int i = 0; i < 8; i++) { newblockOfTiles[i] = new StaticTile[8][]; for (int j = 0; j < 8; j++) { Point2D p = new Point2D(i, j); int length = 0; if (blockStatics.ContainsKey(p)) { length = blockStatics[p].Count; } newblockOfTiles[i][j] = new StaticTile[length]; for (int k = 0; k < length; k++) { if (blockStatics.ContainsKey(p)) { newblockOfTiles[i][j][k] = blockStatics[p][k]; } } } } List <int> associated; MapRegistry.MapAssociations.TryGetValue(MapNumber, out associated); foreach (int integer in associated) { Map map = Map.Maps[integer]; TileMatrix tm = map.Tiles; tm.SetStaticBlock(blockX, blockY, newblockOfTiles); } } } catch { Console.WriteLine("An error occured reading land changes."); } finally { reader.Close(); } } }
public static void ApplyPatch(Map map, Stream patch) { var reader = new BinaryReader(patch); string signature = string.Join(null, reader.ReadBytes(5).Cast <char>()); if (!signature.Equals("TDIFF")) { throw new InvalidDataException("Input stream is not a TDIFF file."); } byte revision = reader.ReadByte(); switch (revision) { case 0: while (patch.Position < patch.Length) { Actions action = (Actions)reader.ReadByte(); switch (action) { case Actions.SetStaticTile: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); int tileIndex = reader.ReadInt32(); layer.Tiles[x, y] = new StaticTile(layer, sheet, BlendMode.Additive, tileIndex); } break; case Actions.SetAnimatedTile: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); long interval = reader.ReadInt64(); int frames = reader.ReadInt32(); var list = new StaticTile[frames]; for (int c = 0; c < frames; c++) { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); int tileIndex = reader.ReadInt32(); list[c] = new StaticTile(layer, sheet, BlendMode.Additive, tileIndex); } layer.Tiles[x, y] = new AnimatedTile(layer, list, interval); } break; case Actions.RemoveTile: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); layer.Tiles[x, y] = null; } break; case Actions.SetTileProperty: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (layer.Tiles[x, y] == null) { throw new NullReferenceException("Map does not contain a tile at the given position: " + layerId + "[" + x + "," + y + "]"); } if (layer.Tiles[x, y].Properties.ContainsKey(propertyKey)) { layer.Tiles[x, y].Properties[propertyKey] = propertyValue; } else { layer.Tiles[x, y].Properties.Add(propertyKey, propertyValue); } } break; case Actions.RemoveTileProperty: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); string propertyKey = reader.ReadTiny(); if (layer.Tiles[x, y] == null) { throw new NullReferenceException("Map does not contain a tile at the given position: " + layerId + "[" + x + "," + y + "]"); } if (layer.Tiles[x, y].Properties.ContainsKey(propertyKey)) { layer.Tiles[x, y].Properties.Remove(propertyKey); } } break; case Actions.SetTileIndexProperty: { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); int tileIndex = reader.ReadInt32(); string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (sheet.TileIndexProperties[tileIndex].ContainsKey(propertyKey)) { sheet.TileIndexProperties[tileIndex][propertyKey] = propertyValue; } else { sheet.TileIndexProperties[tileIndex].Add(propertyKey, propertyValue); } } break; case Actions.RemoveTileIndexProperty: { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); int tileIndex = reader.ReadInt32(); string propertyKey = reader.ReadTiny(); if (sheet.TileIndexProperties[tileIndex].ContainsKey(propertyKey)) { sheet.TileIndexProperties[tileIndex].Remove(propertyKey); } } break; case Actions.SetTilesheetProperty: { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (sheet.Properties.ContainsKey(propertyKey)) { sheet.Properties[propertyKey] = propertyValue; } else { sheet.Properties.Add(propertyKey, propertyValue); } } break; case Actions.RemoveTilesheetProperty: { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); string propertyKey = reader.ReadTiny(); if (sheet.Properties.ContainsKey(propertyKey)) { sheet.Properties.Remove(propertyKey); } } break; case Actions.SetLayerProperty: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (layer.Properties.ContainsKey(propertyKey)) { layer.Properties[propertyKey] = propertyValue; } else { layer.Properties.Add(propertyKey, propertyValue); } } break; case Actions.RemoveLayerProperty: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); string propertyKey = reader.ReadTiny(); if (layer.Properties.ContainsKey(propertyKey)) { layer.Properties.Remove(propertyKey); } } break; case Actions.SetMapProperty: { string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (map.Properties.ContainsKey(propertyKey)) { map.Properties[propertyKey] = propertyValue; } else { map.Properties.Add(propertyKey, propertyValue); } } break; case Actions.RemoveMapProperty: { string propertyKey = reader.ReadTiny(); if (map.Properties.ContainsKey(propertyKey)) { map.Properties.Remove(propertyKey); } } break; case Actions.AddLayer: { string layerId = reader.ReadTiny(); if (map.GetLayer(layerId) == null) { byte width = reader.ReadByte(); byte height = reader.ReadByte(); map.AddLayer(new xTile.Layers.Layer(layerId, map, new xTile.Dimensions.Size(width, height), new xTile.Dimensions.Size(16))); } } break; case Actions.RemoveLayer: { string layerId = reader.ReadTiny(); if (map.GetLayer(layerId) != null) { map.RemoveLayer(map.GetLayer(layerId)); } } break; case Actions.ResizeLayer: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte width = reader.ReadByte(); byte height = reader.ReadByte(); layer.LayerSize = new xTile.Dimensions.Size(width, height); } break; } } break; default: throw new InvalidDataException("Input stream uses a unsupported TDIFF revision:" + revision); } }
public static bool LookupStaticTile(Map map, Point3D staticLocation, int itemId, ref StaticTile tileResult) { bool found = false; foreach (StaticTile tile in map.Tiles.GetStaticTiles(staticLocation.X, staticLocation.Y)) { if (tile.Z >= staticLocation.Z - STATIC_TILE_SEARCH_Z_TOLERANCE && tile.Z <= staticLocation.Z + STATIC_TILE_SEARCH_Z_TOLERANCE) { if (tile.ID == itemId) { tileResult = tile; found = true; continue; } } } return(found); }
void Start() { StaticTile.AddTile(transform.position, this); }
private bool IsOk(Mobile m, bool ignoreDoors, bool ignoreSpellFields, int ourZ, int ourTop, StaticTile[] tiles, List <Item> items) { for (int i = 0; i < tiles.Length; ++i) { StaticTile check = tiles[i]; ItemData itemData = TileData.ItemTable[check.ID & TileData.MaxItemValue]; if ((itemData.Flags & ImpassableSurface) != 0) // Impassable || Surface { int checkZ = check.Z; int checkTop = checkZ + itemData.CalcHeight; if (checkTop > ourZ && ourTop > checkZ) { return(false); } } } for (int i = 0; i < items.Count; ++i) { Item item = items[i]; int itemID = item.ItemID & TileData.MaxItemValue; ItemData itemData = TileData.ItemTable[itemID]; TileFlag flags = itemData.Flags; if ((flags & ImpassableSurface) != 0) // Impassable || Surface { if (ignoreDoors && ((flags & TileFlag.Door) != 0 || itemID == 0x692 || itemID == 0x846 || itemID == 0x873 || (itemID >= 0x6F5 && itemID <= 0x6F6))) { if (item is BaseHouseDoor && m != null && !((BaseHouseDoor)item).CheckAccess(m)) { return(false); } else { continue; } } if (ignoreSpellFields && (itemID == 0x82 || itemID == 0x3946 || itemID == 0x3956)) { continue; } // hidden containers, per EA if ((flags & TileFlag.Container) != 0 && !item.Visible) { continue; } int checkZ = item.Z; int checkTop = checkZ + itemData.CalcHeight; if (checkTop > ourZ && ourTop > checkZ) { return(false); } } } return(true); }
// Merge the layers from a baseMap and several injectedMaps into a mergedMap private static void MergeLayers(Map mergedMap, Map baseMap, MapInformation[] injectedMaps) { // Find the largest layer size among all injecting maps, and use that value xTile.Dimensions.Size largestLayerSize = GetLargestLayerSize(baseMap, injectedMaps); // Luckily, when an index beyond the size of an xTile map layer is checked, it just returns null... which is already the indication that there's no tile there. Convenient! for (int l = 0; l < baseMap.Layers.Count; l++) { Layer baseLayer = baseMap.Layers[l]; Layer mergedLayer = new Layer(baseLayer.Id, mergedMap, largestLayerSize, baseLayer.TileSize); mergedLayer.Description = baseLayer.Description; mergedLayer.Visible = baseLayer.Visible; // Merge the tiles in this layer for (int i = 0; i < mergedLayer.LayerHeight; i++) { for (int j = 0; j < mergedLayer.LayerWidth; j++) { // check to make sure the base tile isn't null if (baseLayer.Tiles[j, i] != null) { // Identify the tilesheet for this tile TileSheet mergedTileSheet = GetMatchingTileSheetInList(baseLayer.Tiles[j, i].TileSheet, mergedMap.TileSheets, null); // Iterrate over all injected maps, if the injected tile is different than the base tile, inject it // Keep track of whether anything has injected this tile yet, if it has, throw a warning about the conflict Tile tileToUse = baseLayer.Tiles[j, i]; string modDidOverride = null; foreach (MapInformation injectedMapInfo in injectedMaps) { // Find the matching layer in this injected map that matches the merged layer we're working on Layer injectedLayer = GetMatchingLayerInList(mergedLayer, injectedMapInfo.Map.Layers, injectedMapInfo); // Check the map offset to get our injected map, if our local position is negative, we haven't reached it yet int injectedIndexX = j - injectedMapInfo.OffsetX; int injectedIndexY = i - injectedMapInfo.OffsetY; if (injectedIndexX < 0 || injectedIndexY < 0) { // Skip this injecting map for this index continue; } if (!CompareTiles(injectedLayer.Tiles[injectedIndexX, injectedIndexY], baseLayer.Tiles[j, i])) { if (modDidOverride == null) { // Only keep track of what map made the change if it wasn't a soft merging map if (injectedMapInfo.Override != MapOverride.SoftMerge) { modDidOverride = injectedMapInfo.Owner.ModSettings.Name; } tileToUse = injectedLayer.Tiles[injectedIndexX, injectedIndexY]; } else { Farmhand.Logging.Log.Warning($"Map merging conflict on map {baseMap.Id}, {modDidOverride} and {injectedMapInfo.Owner.ModSettings.Name} both attempted to alter {j},{i} on layer {baseLayer.Id}, using first."); } } if (tileToUse != null) { // Create either a new static or animated tile if (tileToUse is StaticTile) { StaticTile staticTileToUse = tileToUse as StaticTile; mergedLayer.Tiles[j, i] = new StaticTile(mergedLayer, mergedTileSheet, staticTileToUse.BlendMode, staticTileToUse.TileIndex); InjectComponentProperties(mergedLayer.Tiles[j, i], staticTileToUse); } else if (tileToUse is AnimatedTile) { AnimatedTile animatedTileToUse = tileToUse as AnimatedTile; // Get the frames as static tiles StaticTile[] mergedFrames = new StaticTile[animatedTileToUse.TileFrames.Length]; for (int f = 0; f < mergedFrames.Length; f++) { mergedFrames[f] = new StaticTile(mergedLayer, mergedTileSheet, animatedTileToUse.TileFrames[f].BlendMode, animatedTileToUse.TileFrames[f].TileIndex); InjectComponentProperties(mergedFrames[f], animatedTileToUse.TileFrames[f]); } mergedLayer.Tiles[j, i] = new AnimatedTile(mergedLayer, mergedFrames, animatedTileToUse.FrameInterval); InjectComponentProperties(mergedLayer.Tiles[j, i], animatedTileToUse); } else { throw new Exception($"Base tile type in layer {baseLayer.Id} at {j},{i} unknown!"); } } else { mergedLayer.Tiles[j, i] = tileToUse; } } } else { mergedLayer.Tiles[j, i] = null; TileSheet mergedTileSheet = null; // Iterrate over all injected maps, if the injected tile is different than the base tile, inject it // Keep track of whether anything has injected this tile yet, if it has, throw a warning about the conflict Tile tileToUse = baseLayer.Tiles[j, i]; string modDidOverride = null; foreach (MapInformation injectedMapInfo in injectedMaps) { // Find the matching layer in this injected map that matches the merged layer we're working on Layer injectedLayer = GetMatchingLayerInList(mergedLayer, injectedMapInfo.Map.Layers, injectedMapInfo); // If the base tile is null, then the only thing that makes them not equal is not being null if (injectedLayer.Tiles[j, i] != null) { if (modDidOverride == null) { // Only keep track of what map made the change if it wasn't a soft merging map if (injectedMapInfo.Override != MapOverride.SoftMerge) { modDidOverride = injectedMapInfo.Owner.ModSettings.Name; } tileToUse = injectedLayer.Tiles[j, i]; // Get the tilesheet from the injected tile if (tileToUse.TileSheet != null) { mergedTileSheet = GetMatchingTileSheetInList(tileToUse.TileSheet, mergedMap.TileSheets, injectedMapInfo); } } else { Farmhand.Logging.Log.Warning($"Map merging conflict on map {baseMap.Id}, {modDidOverride} and {injectedMapInfo.Owner.ModSettings.Name} both attempted to alter {j},{i} on layer {baseLayer.Id}, using first."); } } } if (tileToUse != null && mergedTileSheet != null) { // Create either a new static or animated tile if (tileToUse is StaticTile) { StaticTile staticTileToUse = tileToUse as StaticTile; mergedLayer.Tiles[j, i] = new StaticTile(mergedLayer, mergedTileSheet, staticTileToUse.BlendMode, staticTileToUse.TileIndex); InjectComponentProperties(mergedLayer.Tiles[j, i], staticTileToUse); } else if (tileToUse is AnimatedTile) { AnimatedTile animatedTileToUse = tileToUse as AnimatedTile; // Get the frames as static tiles StaticTile[] mergedFrames = new StaticTile[animatedTileToUse.TileFrames.Length]; for (int f = 0; f < mergedFrames.Length; f++) { mergedFrames[f] = new StaticTile(mergedLayer, mergedTileSheet, animatedTileToUse.TileFrames[f].BlendMode, animatedTileToUse.TileFrames[f].TileIndex); InjectComponentProperties(mergedFrames[f], animatedTileToUse.TileFrames[f]); } mergedLayer.Tiles[j, i] = new AnimatedTile(mergedLayer, mergedFrames, animatedTileToUse.FrameInterval); InjectComponentProperties(mergedLayer.Tiles[j, i], animatedTileToUse); } else { throw new Exception($"Base tile type in layer {baseLayer.Id} at {j},{i} unknown!"); } } else { mergedLayer.Tiles[j, i] = null; } } } } // Merge the layer properties into this layer List <IPropertyCollection> propertyInjectingLayers = new List <IPropertyCollection>(); foreach (var map in injectedMaps) { // Identify the layer in this injected map that matches the one currently being injected into the mergedMap propertyInjectingLayers.Add(GetMatchingLayerInList(mergedLayer, map.Map.Layers, map).Properties); } MergeProperties(mergedLayer, propertyInjectingLayers, baseLayer); // Add the merged layer to the merged map mergedMap.AddLayer(mergedLayer); } }
public static void CheckLos_OnCommand(Server.Commands.CommandEventArgs args) { try { DateTime start = DateTime.Now; ClearLOS_OnCommand(args); LOSItemPacket.Reset(); Mobile m = args.Mobile; Map map = m.Map; int range = 12; if (args.Length > 0) { range = args.GetInt32(0); } if (range > 20) { range = 20; } else if (range < 1) { range = 1; } m.SendMessage("Calculating..."); int minx, maxx; int miny, maxy; Point3D from = map.GetPoint(m, true); minx = m.Location.X - range; maxx = m.Location.X + range; miny = m.Location.Y - range; maxy = m.Location.Y + range; for (int x = minx; x <= maxx; x++) { for (int y = miny; y <= maxy; y++) { { LandTile tile = map.Tiles.GetLandTile(x, y); ItemData id = TileData.ItemTable[tile.ID & 0x3FFF]; if (!tile.Ignored && id.Surface) { int z = tile.Z + id.CalcHeight; Point3D loc = new Point3D(x, y, z); int hue; if (loc == m.Location) { hue = 0x35; // yellow } else if (map.LineOfSight(from, loc)) { hue = 0x3F; // green } else { hue = 0x26; // red } m.Send(new LOSItemPacket(hue, loc)); } } StaticTile[] tiles = map.Tiles.GetStaticTiles(x, y, true); for (int i = 0; i < tiles.Length; i++) { StaticTile tile = (StaticTile)tiles[i]; ItemData id = TileData.ItemTable[tile.ID & 0x3FFF]; if (id.Surface) // land doesnt use same flags, so just allow it { int z = tile.Z + id.CalcHeight; Point3D loc = new Point3D(x, y, z); int hue; if (loc == m.Location) { hue = 0x35; // yellow } else if (map.LineOfSight(from, loc)) { hue = 0x3F; // green } else { hue = 0x26; // red } m.Send(new LOSItemPacket(hue, loc)); } } } } m.SendAsciiMessage("Completed LOS check in {0}s", (DateTime.Now - start).TotalSeconds); } catch (Exception e) { args.Mobile.SendMessage("CRASHED : {0}", e.Message); } }
public static Map mergeInto(this Map t, Map map, Vector2 position, Microsoft.Xna.Framework.Rectangle?sourceArea = null, bool includeEmpty = true, bool properties = true) { Microsoft.Xna.Framework.Rectangle sourceRectangle = sourceArea.HasValue ? sourceArea.Value : new Microsoft.Xna.Framework.Rectangle(0, 0, t.DisplayWidth / Game1.tileSize, t.DisplayHeight / Game1.tileSize); //tilesheet normalizing taken with permission from Content Patcher // https://github.com/Pathoschild/StardewMods/blob/stable/ContentPatcher/Framework/Patches/EditMapPatch.cs foreach (TileSheet tilesheet in t.TileSheets) { TileSheet mapSheet = map.GetTileSheet(tilesheet.Id); if (mapSheet == null || mapSheet.ImageSource != tilesheet.ImageSource) { // change ID if needed so new tilesheets are added after vanilla ones (to avoid errors in hardcoded game logic) string id = tilesheet.Id; if (!id.StartsWith("z_", StringComparison.InvariantCultureIgnoreCase)) { id = $"z_{id}"; } // change ID if it conflicts with an existing tilesheet if (map.GetTileSheet(id) != null) { int disambiguator = Enumerable.Range(2, int.MaxValue - 1).First(p => map.GetTileSheet($"{id}_{p}") == null); id = $"{id}_{disambiguator}"; } //add tilesheet if (!map.TileSheets.ToList().Exists(ts => ts.Id == tilesheet.Id)) { map.AddTileSheet(new TileSheet(tilesheet.Id, map, tilesheet.ImageSource, tilesheet.SheetSize, tilesheet.TileSize)); } } } if (properties) { foreach (KeyValuePair <string, PropertyValue> p in t.Properties) { if (map.Properties.ContainsKey(p.Key)) { if (p.Key == "EntryAction") { map.Properties[p.Key] = map.Properties[p.Key] + ";" + p.Value; } else { map.Properties[p.Key] = p.Value; } } else { map.Properties.Add(p); } } } /* * int w = (int)position.X + sourceRectangle.Width; * int h = (int)position.Y + sourceRectangle.Height; * * foreach (Layer l in map.Layers.Where(ly => ly.LayerWidth < w || ly.LayerHeight < h)) * { * Monitor.Log("Expanding Map " + l.LayerWidth + "x" + l.LayerHeight + "->" + w + "x" + h, LogLevel.Warn); * * if (l.LayerWidth < w) * l.LayerWidth = w; * * if (l.LayerHeight < h) * l.LayerHeight = h; * * } */ for (int x = 0; x < sourceRectangle.Width; x++) { for (int y = 0; y < sourceRectangle.Height; y++) { foreach (Layer layer in t.Layers) { int px = (int)position.X + x; int py = (int)position.Y + y; int sx = (int)sourceRectangle.X + x; int sy = (int)sourceRectangle.Y + y; Tile sourceTile = layer.Tiles[(int)sx, (int)sy]; Layer mapLayer = map.GetLayer(layer.Id); if (mapLayer == null) { map.InsertLayer(new Layer(layer.Id, map, map.Layers[0].LayerSize, map.Layers[0].TileSize), map.Layers.Count); mapLayer = map.GetLayer(layer.Id); } if (mapLayer.IsImageLayer()) { mapLayer.SetupImageLayer(); } if (properties) { foreach (var prop in layer.Properties) { if (!mapLayer.Properties.ContainsKey(prop.Key)) { mapLayer.Properties.Add(prop); } else { mapLayer.Properties[prop.Key] = prop.Value; } } } if (sourceTile == null) { if (includeEmpty) { try { mapLayer.Tiles[(int)px, (int)py] = null; } catch { } } continue; } TileSheet tilesheet = map.GetTileSheet(sourceTile.TileSheet.Id); Tile newTile = new StaticTile(mapLayer, tilesheet, BlendMode.Additive, sourceTile.TileIndex); try { if (sourceTile.Properties.ContainsKey("NoTileMerge")) { newTile = mapLayer.Tiles[(int)px, (int)py]; } } catch { } if (sourceTile is AnimatedTile aniTile) { List <StaticTile> staticTiles = new List <StaticTile>(); foreach (StaticTile frame in aniTile.TileFrames) { staticTiles.Add(new StaticTile(mapLayer, tilesheet, BlendMode.Additive, frame.TileIndex)); } newTile = new AnimatedTile(mapLayer, staticTiles.ToArray(), aniTile.FrameInterval); } if (properties) { foreach (var prop in sourceTile.Properties) { if (newTile.Properties.ContainsKey(prop.Key)) { newTile.Properties[prop.Key] = prop.Value; } else { newTile.Properties.Add(prop); } } foreach (var prop in sourceTile.TileIndexProperties) { if (newTile.TileIndexProperties.ContainsKey(prop.Key)) { newTile.TileIndexProperties[prop.Key] = prop.Value; } else { newTile.TileIndexProperties.Add(prop); } } } try { mapLayer.Tiles[(int)px, (int)py] = newTile; } catch (Exception e) { Monitor.Log($"{e.Message} ({map.DisplayWidth} -> {layer.Id} -> {px}:{py})"); } } } } return(map); }
public static Map loadTmx(IModHelper modHelper, string mapName, string path) { var tmap = new TiledMap(Path.Combine(modHelper.DirectoryPath, path)); var xmap = new Map(mapName); addTiledPropertiesToXTile(tmap.Properties, xmap.Properties); var tileMapping = new Dictionary <int, TileMapping>(); var animMapping = new Dictionary <int, TileAnimation>(); foreach (var ttileSheet in tmap.Tilesets) { // xTile wants things like "Mines/mine", not "Mines/mine.png" string image = ttileSheet.Image.Source; if (image.EndsWith(".png")) { string dir = Path.GetDirectoryName(path); string tempKey = Path.Combine(dir, image); string actualKey = modHelper.Content.GetActualAssetKey(tempKey); Log.debug($"{dir} | {image} | {tempKey} | {actualKey} "); image = Path.Combine(Path.GetDirectoryName(path), image); //modHelper.Content.Load<Texture2D>(image); image = modHelper.Content.GetActualAssetKey(image); } var xtileSheet = new TileSheet(xmap, image, new Size(ttileSheet.Columns, ttileSheet.TileCount / ttileSheet.Columns), new Size(tmap.TileWidth, tmap.TileHeight)); addTiledPropertiesToXTile(ttileSheet.Properties, xtileSheet.Properties); xtileSheet.Id = ttileSheet.Name; xtileSheet.Spacing = new Size(ttileSheet.Spacing, ttileSheet.Spacing); xtileSheet.Margin = new Size(ttileSheet.Margin, ttileSheet.Margin); for (int i = 0; i < ttileSheet.TileCount; ++i) { tileMapping.Add(ttileSheet.FirstGlobalId + i, new TileMapping(xtileSheet, i)); } foreach (var ttile in ttileSheet.Tiles) { addTiledPropertiesToXTile(ttile.Properties, xtileSheet.TileIndexProperties[ttile.Id]); if (ttile.Animation != null && ttile.Animation.Count > 0) { List <int> tanimFrames = new List <int>(); foreach (var ttileAnim in ttile.Animation) { tanimFrames.Add(ttileSheet.FirstGlobalId + ttileAnim.TileId); } animMapping.Add(ttileSheet.FirstGlobalId + ttile.Id, new TileAnimation(tanimFrames.ToArray <int>(), ttile.Animation[0].Duration)); } } xmap.AddTileSheet(xtileSheet); } var tobjectGroups = new List <TiledObjectGroup>(); foreach (var tlayer_ in tmap.Layers) { if (tlayer_ is TiledTileLayer) { var tlayer = tlayer_ as TiledTileLayer; // Note that the tile size needs to be * 4. Otherwise, you will break collisions and many other things. // Yes, even if you don't use the loaded map. Creating the layer is enough. // For some reason vanilla has a tilesize of 16 for tilesheets, but 64 for the layers. // I mean, I knew the game was scaled up, but that's kinda odd. // Anyways, whenever you create a layer with a different tile size, it changes the tile size // of EVERY OTHER LAYER IN EXISTANCE to match. And guess what, that breaks things. // I spent hours figuring this out. I don't care about the underlying cause. I just want to mod. var xlayer = new Layer(tlayer.Name, xmap, new Size(tmap.Width, tmap.Height), new Size(tmap.TileWidth * 4, tmap.TileHeight * 4)); addTiledPropertiesToXTile(tlayer.Properties, xlayer.Properties); if (tlayer.Data.Compression != TiledData.CompressionType.NoCompression) { throw new InvalidDataException("Compressed tile data is not supported."); } if (tlayer.Data.Encoding == TiledData.EncodingType.NoEncoding || tlayer.Data.Encoding == TiledData.EncodingType.Xml) { for (int i = 0; i < tlayer.Data.Tiles.Count; ++i) { var ttile = tlayer.Data.Tiles[i]; int ix = i % tmap.Width; int iy = i / tmap.Width; var xtile = new StaticTile(xlayer, tileMapping[ttile.GlobalId].tileSheet, BlendMode.Alpha, tileMapping[ttile.GlobalId].tileId); xlayer.Tiles[ix, iy] = xtile; } } else if (tlayer.Data.Encoding == TiledData.EncodingType.Csv) { string[] ttiles = string.Join("", tlayer.Data.Data).Split(','); for (int i = 0; i < ttiles.Length; ++i) { var ttile = int.Parse(ttiles[i]); if (!tileMapping.ContainsKey(ttile)) { continue; } int ix = i % tmap.Width; int iy = i / tmap.Width; Tile xtile = null; if (animMapping.ContainsKey(ttile)) { TileAnimation tanim = animMapping[ttile]; var xanimTiles = new StaticTile[tanim.tileIds.Length]; for (int ia = 0; ia < xanimTiles.Length; ++ia) { xanimTiles[ia] = new StaticTile(xlayer, tileMapping[tanim.tileIds[ia]].tileSheet, BlendMode.Alpha, tileMapping[tanim.tileIds[ia]].tileId); } xtile = new AnimatedTile(xlayer, xanimTiles, tanim.duration); } else { xtile = new StaticTile(xlayer, tileMapping[ttile].tileSheet, BlendMode.Alpha, tileMapping[ttile].tileId); } xlayer.Tiles[ix, iy] = xtile; } } else { throw new InvalidDataException("Tile data encoding type " + tlayer.Data.Encoding + " not supported."); } xmap.AddLayer(xlayer); } else if (tlayer_ is TiledObjectGroup) { tobjectGroups.Add(tlayer_ as TiledObjectGroup); } } foreach (var tobjectGroup in tobjectGroups) { var xlayer = xmap.GetLayer(tobjectGroup.Name); if (xlayer == null) { continue; } foreach (var tobj in tobjectGroup.Objects) { if (tobj.Name != "TileData" || tobj.Width != tmap.TileWidth || tobj.Height != tmap.TileWidth || tobj.Properties.Count == 0) { continue; } int x = (int)tobj.X / tmap.TileWidth; int y = (int)tobj.Y / tmap.TileWidth; if (xlayer.Tiles[new Location(x, y)] == null) { Log.warn("Tile property for non-existant tile; skipping"); continue; } addTiledPropertiesToXTile(tobj.Properties, xlayer.Tiles[new Location(x, y)].Properties); } } return(xmap); }
public void OnTarget(Mobile from, object obj) { if (Deleted || m_InUse) { return; } IPoint3D p3D = obj as IPoint3D; if (p3D == null) { return; } Map map = from.Map; if (map == null || map == Map.Internal) { return; } int x = p3D.X, y = p3D.Y; LandTile landTile = map.Tiles.GetLandTile(x, y); StaticTile[] tiles = map.Tiles.GetStaticTiles(x, y, true); bool hasWater = false; if (landTile.Z == p3D.Z && Server.Misc.Worlds.IsWaterTile(landTile.ID, 0)) { hasWater = true; } for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; if (tile.Z == p3D.Z && Server.Misc.Worlds.IsWaterTile(tile.ID, 0)) { hasWater = true; } } if (!from.InRange(p3D, 6)) { from.SendLocalizedMessage(500976); // You need to be closer to the water to fish! } else if (hasWater) { Point3D p = new Point3D(x, y, map.GetAverageZ(x, y)); this.ItemID = 0x0DCA; m_InUse = true; Movable = false; MoveToWorld(p, map); from.Animate(12, 5, 1, true, false, 0); Timer.DelayCall(TimeSpan.FromSeconds(1.5), TimeSpan.FromSeconds(1.0), 20, new TimerStateCallback(DoEffect), new object[] { p, 0, from }); from.SendLocalizedMessage(1010487); // You plunge the net into the sea... } else { from.SendLocalizedMessage(1010485); // You can only use this net in deep water! } }
public static HousePlacementResult Check(Mobile from, int multiID, Point3D center, out ArrayList toMove) { // If this spot is considered valid, every item and mobile in this list will be moved under the house sign toMove = new ArrayList(); Map map = from.Map; if (map == null || map == Map.Internal) { return(HousePlacementResult.BadLand); // A house cannot go here } if (from.AccessLevel >= AccessLevel.GameMaster) { return(HousePlacementResult.Valid); // Staff can place anywhere } if (map == Map.Ilshenar || SpellHelper.IsFeluccaT2A(map, center)) { return(HousePlacementResult.BadRegion); // No houses in Ilshenar/T2A } if (map == Map.Malas && (multiID == 0x007C || multiID == 0x007E)) { return(HousePlacementResult.InvalidCastleKeep); } var noHousingRegion = (NoHousingRegion)Region.Find(center, map).GetRegion(typeof(NoHousingRegion)); if (noHousingRegion != null) { return(HousePlacementResult.BadRegion); } // This holds data describing the internal structure of the house MultiComponentList mcl = MultiData.GetComponents(multiID); if (multiID >= 0x13EC && multiID < 0x1D00) { HouseFoundation.AddStairsTo(ref mcl); // this is a AOS house, add the stairs } // Location of the nortwest-most corner of the house Point3D start = new Point3D(center.X + mcl.Min.X, center.Y + mcl.Min.Y, center.Z); // These are storage lists. They hold items and mobiles found in the map for further processing List <Item> items = new List <Item>(); List <Mobile> mobiles = new List <Mobile>(); // These are also storage lists. They hold location values indicating the yard and border locations. List <Point2D> yard = new List <Point2D>(), borders = new List <Point2D>(); /* RULES: * * 1) All tiles which are around the -outside- of the foundation must not have anything impassable. * 2) No impassable object or land tile may come in direct contact with any part of the house. * 3) Five tiles from the front and back of the house must be completely clear of all house tiles. * 4) The foundation must rest flatly on a surface. Any bumps around the foundation are not allowed. * 5) No foundation tile may reside over terrain which is viewed as a road. */ for (int x = 0; x < mcl.Width; ++x) { for (int y = 0; y < mcl.Height; ++y) { int tileX = start.X + x; int tileY = start.Y + y; StaticTile[] addTiles = mcl.Tiles[x][y]; if (addTiles.Length == 0) { continue; // There are no tiles here, continue checking somewhere else } Point3D testPoint = new Point3D(tileX, tileY, center.Z); Region reg = Region.Find(testPoint, map); if (!reg.AllowHousing(from, testPoint)) // Cannot place houses in dungeons, towns, treasure map areas etc { if (reg.IsPartOf(typeof(TempNoHousingRegion))) { return(HousePlacementResult.BadRegionTemp); } if (reg.IsPartOf(typeof(TreasureRegion)) || reg.IsPartOf(typeof(HouseRegion))) { return(HousePlacementResult.BadRegionHidden); } if (reg.IsPartOf(typeof(HouseRaffleRegion))) { return(HousePlacementResult.BadRegionRaffle); } return(HousePlacementResult.BadRegion); } LandTile landTile = map.Tiles.GetLandTile(tileX, tileY); int landID = landTile.ID & TileData.MaxLandValue; StaticTile[] oldTiles = map.Tiles.GetStaticTiles(tileX, tileY, true); Sector sector = map.GetSector(tileX, tileY); items.Clear(); for (int i = 0; i < sector.Items.Count; ++i) { Item item = sector.Items[i]; if (item.Visible && item.X == tileX && item.Y == tileY) { items.Add(item); } } mobiles.Clear(); for (int i = 0; i < sector.Mobiles.Count; ++i) { Mobile m = sector.Mobiles[i]; if (m.X == tileX && m.Y == tileY) { mobiles.Add(m); } } int landStartZ = 0, landAvgZ = 0, landTopZ = 0; map.GetAverageZ(tileX, tileY, ref landStartZ, ref landAvgZ, ref landTopZ); bool hasFoundation = false; for (int i = 0; i < addTiles.Length; ++i) { StaticTile addTile = addTiles[i]; if (addTile.ID == 0x1) // Nodraw { continue; } TileFlag addTileFlags = TileData.ItemTable[addTile.ID & TileData.MaxItemValue].Flags; bool isFoundation = (addTile.Z == 0 && (addTileFlags & TileFlag.Wall) != 0); bool hasSurface = false; if (isFoundation) { hasFoundation = true; } int addTileZ = center.Z + addTile.Z; int addTileTop = addTileZ + addTile.Height; if ((addTileFlags & TileFlag.Surface) != 0) { addTileTop += 16; } if (addTileTop > landStartZ && landAvgZ > addTileZ) { return(HousePlacementResult.BadLand); // Broke rule #2 } if (isFoundation && ((TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Impassable) == 0) && landAvgZ == center.Z) { hasSurface = true; } for (int j = 0; j < oldTiles.Length; ++j) { StaticTile oldTile = oldTiles[j]; ItemData id = TileData.ItemTable[oldTile.ID & TileData.MaxItemValue]; if ((id.Impassable || (id.Surface && (id.Flags & TileFlag.Background) == 0)) && addTileTop > oldTile.Z && (oldTile.Z + id.CalcHeight) > addTileZ) { return(HousePlacementResult.BadStatic); // Broke rule #2 } /*else if ( isFoundation && !hasSurface && (id.Flags & TileFlag.Surface) != 0 && (oldTile.Z + id.CalcHeight) == center.Z ) * hasSurface = true;*/ } for (int j = 0; j < items.Count; ++j) { Item item = items[j]; ItemData id = item.ItemData; if (addTileTop > item.Z && (item.Z + id.CalcHeight) > addTileZ) { if (item.Movable) { toMove.Add(item); } else if ((id.Impassable || (id.Surface && (id.Flags & TileFlag.Background) == 0))) { return(HousePlacementResult.BadItem); // Broke rule #2 } } /*else if ( isFoundation && !hasSurface && (id.Flags & TileFlag.Surface) != 0 && (item.Z + id.CalcHeight) == center.Z ) * { * hasSurface = true; * }*/ } if (isFoundation && !hasSurface) { return(HousePlacementResult.NoSurface); // Broke rule #4 } for (int j = 0; j < mobiles.Count; ++j) { Mobile m = mobiles[j]; if (addTileTop > m.Z && (m.Z + 16) > addTileZ) { toMove.Add(m); } } } for (int i = 0; i < m_RoadIDs.Length; i += 2) { if (landID >= m_RoadIDs[i] && landID <= m_RoadIDs[i + 1]) { return(HousePlacementResult.BadLand); // Broke rule #5 } } if (hasFoundation) { for (int xOffset = -1; xOffset <= 1; ++xOffset) { for (int yOffset = -YardSize; yOffset <= YardSize; ++yOffset) { Point2D yardPoint = new Point2D(tileX + xOffset, tileY + yOffset); if (!yard.Contains(yardPoint)) { yard.Add(yardPoint); } } } for (int xOffset = -1; xOffset <= 1; ++xOffset) { for (int yOffset = -1; yOffset <= 1; ++yOffset) { if (xOffset == 0 && yOffset == 0) { continue; } // To ease this rule, we will not add to the border list if the tile here is under a base floor (z<=8) int vx = x + xOffset; int vy = y + yOffset; if (vx >= 0 && vx < mcl.Width && vy >= 0 && vy < mcl.Height) { StaticTile[] breakTiles = mcl.Tiles[vx][vy]; bool shouldBreak = false; for (int i = 0; !shouldBreak && i < breakTiles.Length; ++i) { StaticTile breakTile = breakTiles[i]; if (breakTile.Height == 0 && breakTile.Z <= 8 && TileData.ItemTable[breakTile.ID & TileData.MaxItemValue].Surface) { shouldBreak = true; } } if (shouldBreak) { continue; } } Point2D borderPoint = new Point2D(tileX + xOffset, tileY + yOffset); if (!borders.Contains(borderPoint)) { borders.Add(borderPoint); } } } } } } for (int i = 0; i < borders.Count; ++i) { Point2D borderPoint = borders[i]; LandTile landTile = map.Tiles.GetLandTile(borderPoint.X, borderPoint.Y); int landID = landTile.ID & TileData.MaxLandValue; if ((TileData.LandTable[landID].Flags & TileFlag.Impassable) != 0) { return(HousePlacementResult.BadLand); } for (int j = 0; j < m_RoadIDs.Length; j += 2) { if (landID >= m_RoadIDs[j] && landID <= m_RoadIDs[j + 1]) { return(HousePlacementResult.BadLand); // Broke rule #5 } } StaticTile[] tiles = map.Tiles.GetStaticTiles(borderPoint.X, borderPoint.Y, true); for (int j = 0; j < tiles.Length; ++j) { StaticTile tile = tiles[j]; ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; if (id.Impassable || (id.Surface && (id.Flags & TileFlag.Background) == 0 && (tile.Z + id.CalcHeight) > (center.Z + 2))) { return(HousePlacementResult.BadStatic); // Broke rule #1 } } Sector sector = map.GetSector(borderPoint.X, borderPoint.Y); List <Item> sectorItems = sector.Items; for (int j = 0; j < sectorItems.Count; ++j) { Item item = sectorItems[j]; if (item.X != borderPoint.X || item.Y != borderPoint.Y || item.Movable) { continue; } ItemData id = item.ItemData; if (id.Impassable || (id.Surface && (id.Flags & TileFlag.Background) == 0 && (item.Z + id.CalcHeight) > (center.Z + 2))) { return(HousePlacementResult.BadItem); // Broke rule #1 } } } List <Sector> _sectors = new List <Sector>(); List <BaseHouse> _houses = new List <BaseHouse>(); for (int i = 0; i < yard.Count; i++) { Sector sector = map.GetSector(yard[i]); if (!_sectors.Contains(sector)) { _sectors.Add(sector); if (sector.Multis != null) { for (int j = 0; j < sector.Multis.Count; j++) { if (sector.Multis[j] is BaseHouse) { BaseHouse _house = (BaseHouse)sector.Multis[j]; if (!_houses.Contains(_house)) { _houses.Add(_house); } } } } } } for (int i = 0; i < yard.Count; ++i) { foreach (BaseHouse b in _houses) { if (b.Contains(yard[i])) { return(HousePlacementResult.BadStatic); // Broke rule #3 } } /*Point2D yardPoint = yard[i]; * IPooledEnumerable eable = map.GetMultiTilesAt( yardPoint.X, yardPoint.Y ); * foreach ( StaticTile[] tile in eable ) * { * for ( int j = 0; j < tile.Length; ++j ) * { * if ( (TileData.ItemTable[tile[j].ID & TileData.MaxItemValue].Flags & (TileFlag.Impassable | TileFlag.Surface)) != 0 ) * { * eable.Free(); * return HousePlacementResult.BadStatic; // Broke rule #3 * } * } * } * eable.Free();*/ } return(HousePlacementResult.Valid); }
/// <summary>Copy the tiles from one map onto another. This assumes the input arguments have already been validated for correctness.</summary> /// <param name="source">The map from which to copy tiles.</param> /// <param name="sourceArea">The tile area within the source map to copy.</param> /// <param name="targetMap">The map onto which to copy tiles.</param> /// <param name="targetArea">The tile area within the target map to overwrite.</param> /// <remarks>Derived from <see cref="GameLocation.ApplyMapOverride"/> with a few changes: /// - added support for source/target areas; /// - added disambiguation if source has a modified version of the same tilesheet, instead of copying tiles into the target tilesheet; /// - changed to always overwrite tiles within the target area (to avoid edge cases where some tiles are only partly applied); /// - fixed copying tilesheets (avoid "The specified TileSheet was not created for use with this map" error); /// - fixed tilesheets not added at the end (via z_ prefix), which can cause crashes in game code which depends on hardcoded tilesheet indexes; /// - fixed issue where different tilesheets are linked by ID. /// </remarks> private void ApplyMapOverride(Map source, Rectangle sourceArea, Map targetMap, Rectangle targetArea) { // apply tilesheets IDictionary <TileSheet, TileSheet> tilesheetMap = new Dictionary <TileSheet, TileSheet>(); foreach (TileSheet sourceSheet in source.TileSheets) { // copy tilesheets TileSheet targetSheet = targetMap.GetTileSheet(sourceSheet.Id); if (targetSheet == null || targetSheet.ImageSource != sourceSheet.ImageSource) { // change ID if needed so new tilesheets are added after vanilla ones (to avoid errors in hardcoded game logic) string id = sourceSheet.Id; if (!id.StartsWith("z_", StringComparison.InvariantCultureIgnoreCase)) { id = $"z_{id}"; } // change ID if it conflicts with an existing tilesheet if (targetMap.GetTileSheet(id) != null) { int disambiguator = Enumerable.Range(2, int.MaxValue - 1).First(p => targetMap.GetTileSheet($"{id}_{p}") == null); id = $"{id}_{disambiguator}"; } // add tilesheet targetSheet = new TileSheet(id, targetMap, sourceSheet.ImageSource, sourceSheet.SheetSize, sourceSheet.TileSize); for (int i = 0, tileCount = sourceSheet.TileCount; i < tileCount; ++i) { targetSheet.TileIndexProperties[i].CopyFrom(sourceSheet.TileIndexProperties[i]); } targetMap.AddTileSheet(targetSheet); } tilesheetMap[sourceSheet] = targetSheet; } // get layer map IDictionary <Layer, Layer> layerMap = source.Layers.ToDictionary(p => p, p => targetMap.GetLayer(p.Id)); // apply tiles for (int x = 0; x < sourceArea.Width; x++) { for (int y = 0; y < sourceArea.Height; y++) { // calculate tile positions Point sourcePos = new Point(sourceArea.X + x, sourceArea.Y + y); Point targetPos = new Point(targetArea.X + x, targetArea.Y + y); // copy tiles foreach (Layer sourceLayer in source.Layers) { Layer targetLayer = layerMap[sourceLayer]; if (targetLayer == null) { continue; } Tile sourceTile = sourceLayer.Tiles[sourcePos.X, sourcePos.Y]; Tile targetTile; switch (sourceTile) { case StaticTile _: targetTile = new StaticTile(targetLayer, tilesheetMap[sourceTile.TileSheet], sourceTile.BlendMode, sourceTile.TileIndex); break; case AnimatedTile animatedTile: { StaticTile[] tileFrames = new StaticTile[animatedTile.TileFrames.Length]; for (int frame = 0; frame < animatedTile.TileFrames.Length; ++frame) { StaticTile frameTile = animatedTile.TileFrames[frame]; tileFrames[frame] = new StaticTile(targetLayer, tilesheetMap[frameTile.TileSheet], frameTile.BlendMode, frameTile.TileIndex); } targetTile = new AnimatedTile(targetLayer, tileFrames, animatedTile.FrameInterval); } break; default: // null or unhandled type targetTile = null; break; } targetTile?.Properties.CopyFrom(sourceTile.Properties); targetLayer.Tiles[targetPos.X, targetPos.Y] = targetTile; } } } }
private static bool IsOk(StaticTile tile, int ourZ, int ourTop) { var itemData = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; return(tile.Z + itemData.CalcHeight <= ourZ || ourTop <= tile.Z || (itemData.Flags & ImpassableSurface) == 0); }
public static void EventSink_Login(LoginEventArgs e) { Mobile from = e.Mobile; Map map = from.Map; if (map == null) { return; } if (map.CanFit(from.X, from.Y, from.Z, 16, false, false)) { return; } bool isStranded = false; LandTile landTile = map.Tiles.GetLandTile(from.X, from.Y); if ((landTile.ID >= 168 && landTile.ID <= 171) || (landTile.ID >= 310 && landTile.ID <= 311)) { isStranded = true; } else { StaticTile[] tiles = map.Tiles.GetStaticTiles(from.X, from.Y); for (int i = 0; !isStranded && i < tiles.Length; ++i) { StaticTile tile = tiles[i]; if (tile.ID >= 0x5797 && tile.ID <= 0x57B2) { isStranded = true; } } } if (!isStranded) { return; } Point2D[] list; if (map == Map.Felucca) { list = m_Felucca; } else if (map == Map.Trammel) { list = m_Trammel; } else if (map == Map.Ilshenar) { list = m_Ilshenar; } else { return; } Point2D p = Point2D.Zero; double pdist = double.MaxValue; for (int i = 0; i < list.Length; ++i) { double dist = from.GetDistanceToSqrt(list[i]); if (dist < pdist) { p = list[i]; pdist = dist; } } int x = p.X, y = p.Y; int z; bool canFit = false; z = map.GetAverageZ(x, y); canFit = map.CanSpawnMobile(x, y, z); for (int i = 1; !canFit && i <= 40; i += 2) { for (int xo = -1; !canFit && xo <= 1; ++xo) { for (int yo = -1; !canFit && yo <= 1; ++yo) { if (xo == 0 && yo == 0) { continue; } x = p.X + (xo * i); y = p.Y + (yo * i); z = map.GetAverageZ(x, y); canFit = map.CanSpawnMobile(x, y, z); } } } if (canFit) { from.Location = new Point3D(x, y, z); } }
private bool Check(Map map, Mobile m, List <Item> items, List <Mobile> mobiles, int x, int y, int startTop, int startZ, bool canSwim, bool cantWalk, out int newZ) { newZ = 0; StaticTile[] tiles = map.Tiles.GetStaticTiles(x, y, true); LandTile landTile = map.Tiles.GetLandTile(x, y); bool landBlocks = (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Impassable) != 0; bool considerLand = !landTile.Ignored; if (landBlocks && canSwim && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Wet) != 0) //Impassable, Can Swim, and Is water. Don't block it. { landBlocks = false; } else if (cantWalk && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Wet) == 0) //Can't walk and it's not water { landBlocks = true; } int landZ = 0, landCenter = 0, landTop = 0; map.GetAverageZ(x, y, ref landZ, ref landCenter, ref landTop); bool moveIsOk = false; int stepTop = startTop + StepHeight; int checkTop = startZ + PersonHeight; bool ignoreDoors = (m_AlwaysIgnoreDoors || !m.Alive || m.Body.BodyID == 0x3DB || m.IsDeadBondedPet); bool ignoreSpellFields = m is PlayerMobile && map != Map.Felucca; #region Tiles for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; ItemData itemData = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; TileFlag flags = itemData.Flags; if ((flags & ImpassableSurface) == TileFlag.Surface || (canSwim && (flags & TileFlag.Wet) != 0)) // Surface && !Impassable { if (cantWalk && (flags & TileFlag.Wet) == 0) { continue; } int itemZ = tile.Z; int itemTop = itemZ; int ourZ = itemZ + itemData.CalcHeight; int ourTop = ourZ + PersonHeight; int testTop = checkTop; if (moveIsOk) { int cmp = Math.Abs(ourZ - m.Z) - Math.Abs(newZ - m.Z); if (cmp > 0 || (cmp == 0 && ourZ > newZ)) { continue; } } if (ourZ + PersonHeight > testTop) { testTop = ourZ + PersonHeight; } if (!itemData.Bridge) { itemTop += itemData.Height; } if (stepTop >= itemTop) { int landCheck = itemZ; if (itemData.Height >= StepHeight) { landCheck += StepHeight; } else { landCheck += itemData.Height; } if (considerLand && landCheck < landCenter && landCenter > ourZ && testTop > landZ) { continue; } if (IsOk(ignoreDoors, ignoreSpellFields, ourZ, testTop, tiles, items)) { newZ = ourZ; moveIsOk = true; } } } } #endregion #region Items for (int i = 0; i < items.Count; ++i) { Item item = items[i]; ItemData itemData = item.ItemData; TileFlag flags = itemData.Flags; if (!item.Movable && ((flags & ImpassableSurface) == TileFlag.Surface || (m.CanSwim && (flags & TileFlag.Wet) != 0))) // Surface && !Impassable && !Movable { if (cantWalk && (flags & TileFlag.Wet) == 0) { continue; } int itemZ = item.Z; int itemTop = itemZ; int ourZ = itemZ + itemData.CalcHeight; int ourTop = ourZ + PersonHeight; int testTop = checkTop; if (moveIsOk) { int cmp = Math.Abs(ourZ - m.Z) - Math.Abs(newZ - m.Z); if (cmp > 0 || (cmp == 0 && ourZ > newZ)) { continue; } } if (ourZ + PersonHeight > testTop) { testTop = ourZ + PersonHeight; } if (!itemData.Bridge) { itemTop += itemData.Height; } if (stepTop >= itemTop) { int landCheck = itemZ; if (itemData.Height >= StepHeight) { landCheck += StepHeight; } else { landCheck += itemData.Height; } if (considerLand && landCheck < landCenter && landCenter > ourZ && testTop > landZ) { continue; } if (IsOk(ignoreDoors, ignoreSpellFields, ourZ, testTop, tiles, items)) { newZ = ourZ; moveIsOk = true; } } } } #endregion if (considerLand && !landBlocks && stepTop >= landZ) { int ourZ = landCenter; int ourTop = ourZ + PersonHeight; int testTop = checkTop; if (ourZ + PersonHeight > testTop) { testTop = ourZ + PersonHeight; } bool shouldCheck = true; if (moveIsOk) { int cmp = Math.Abs(ourZ - m.Z) - Math.Abs(newZ - m.Z); if (cmp > 0 || (cmp == 0 && ourZ > newZ)) { shouldCheck = false; } } if (shouldCheck && IsOk(ignoreDoors, ignoreSpellFields, ourZ, testTop, tiles, items)) { newZ = ourZ; moveIsOk = true; } } #region Mobiles if (moveIsOk) { for (int i = 0; moveIsOk && i < mobiles.Count; ++i) { Mobile mob = mobiles[i]; if (mob != m && (mob.Z + 15) > newZ && (newZ + 15) > mob.Z && !CanMoveOver(m, mob)) { moveIsOk = false; } } } #endregion return(moveIsOk); }
private void OnClickCopy(object sender, EventArgs e) { int x1 = (int)numericUpDownX1.Value; int x2 = (int)numericUpDownX2.Value; int y1 = (int)numericUpDownY1.Value; int y2 = (int)numericUpDownY2.Value; if ((x1 < 0) || (x1 > workingmap.Width)) { MessageBox.Show("Invalid X1 coordinate!", "Map Diff Insert", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if ((x2 < 0) || (x2 > workingmap.Width)) { MessageBox.Show("Invalid X2 coordinate!", "Map Diff Insert", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if ((y1 < 0) || (y1 > workingmap.Height)) { MessageBox.Show("Invalid Y1 coordinate!", "Map Diff Insert", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if ((y2 < 0) || (y2 > workingmap.Height)) { MessageBox.Show("Invalid Y2 coordinate!", "Map Diff Insert", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } if ((x1 > x2) || (y1 > y2)) { MessageBox.Show("X1 and Y1 cannot be bigger than X2 and Y2!", "Map Diff Insert", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } x1 >>= 3; x2 >>= 3; y1 >>= 3; y2 >>= 3; int blocky = workingmap.Height >> 3; int blockx = workingmap.Width >> 3; progressBar1.Step = 1; progressBar1.Value = 0; progressBar1.Maximum = 0; if (checkBoxMap.Checked) { progressBar1.Maximum += blocky * blockx; } if (checkBoxStatics.Checked) { progressBar1.Maximum += blocky * blockx; } if (checkBoxMap.Checked) { string mapPath = Ultima.Files.GetFilePath(String.Format("map{0}.mul", workingmap.FileIndex)); FileStream m_map; BinaryReader m_mapReader; if (mapPath != null) { m_map = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_mapReader = new BinaryReader(m_map); } else { MessageBox.Show("Map file not found!", "Map Diff Insert", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } string mul = Path.Combine(FiddlerControls.Options.OutputPath, String.Format("map{0}.mul", workingmap.FileIndex)); using (FileStream fsmul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write)) { using (BinaryWriter binmul = new BinaryWriter(fsmul)) { for (int x = 0; x < blockx; ++x) { for (int y = 0; y < blocky; ++y) { m_mapReader.BaseStream.Seek(((x * blocky) + y) * 196, SeekOrigin.Begin); int header = m_mapReader.ReadInt32(); binmul.Write(header); ushort tileid; sbyte z; bool patched = false; if ((x1 <= x) && (x <= x2) && (y1 <= y) && (y <= y2)) { if (workingmap.Tiles.Patch.IsLandBlockPatched(x, y)) { patched = true; Tile[] patchtile = workingmap.Tiles.Patch.GetLandBlock(x, y); for (int i = 0; i < 64; ++i) { tileid = patchtile[i].ID; z = (sbyte)patchtile[i].Z; tileid = Art.GetLegalItemID(tileid); if (z < -128) { z = -128; } if (z > 127) { z = 127; } binmul.Write(tileid); binmul.Write(z); } } } if (!patched) { for (int i = 0; i < 64; ++i) { tileid = m_mapReader.ReadUInt16(); z = m_mapReader.ReadSByte(); tileid = Art.GetLegalItemID(tileid); if (z < -128) { z = -128; } if (z > 127) { z = 127; } binmul.Write(tileid); binmul.Write(z); } } progressBar1.PerformStep(); } } } } m_mapReader.Close(); } if (checkBoxStatics.Checked) { string indexPath = Files.GetFilePath(String.Format("staidx{0}.mul", workingmap.FileIndex)); FileStream m_Index; BinaryReader m_IndexReader; if (indexPath != null) { m_Index = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_IndexReader = new BinaryReader(m_Index); } else { MessageBox.Show("Static file not found!", "Map Diff Insert", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } string staticsPath = Files.GetFilePath(String.Format("statics{0}.mul", workingmap.FileIndex)); FileStream m_Statics; BinaryReader m_StaticsReader; if (staticsPath != null) { m_Statics = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_StaticsReader = new BinaryReader(m_Statics); } else { MessageBox.Show("Static file not found!", "Map Diff Insert", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } string idx = Path.Combine(FiddlerControls.Options.OutputPath, String.Format("staidx{0}.mul", workingmap.FileIndex)); string mul = Path.Combine(FiddlerControls.Options.OutputPath, String.Format("statics{0}.mul", workingmap.FileIndex)); using (FileStream fsidx = new FileStream(idx, FileMode.Create, FileAccess.Write, FileShare.Write), fsmul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write)) { using (BinaryWriter binidx = new BinaryWriter(fsidx), binmul = new BinaryWriter(fsmul)) { for (int x = 0; x < blockx; ++x) { for (int y = 0; y < blocky; ++y) { int lookup, length, extra; m_IndexReader.BaseStream.Seek(((x * blocky) + y) * 12, SeekOrigin.Begin); lookup = m_IndexReader.ReadInt32(); length = m_IndexReader.ReadInt32(); extra = m_IndexReader.ReadInt32(); bool patched = false; if ((x1 <= x) && (x <= x2) && (y1 <= y) && (y <= y2)) { if (workingmap.Tiles.Patch.IsStaticBlockPatched(x, y)) { patched = true; } } if (patched) { HuedTile[][][] patchstat = workingmap.Tiles.Patch.GetStaticBlock(x, y); int count = 0; for (int i = 0; i < 8; ++i) { for (int j = 0; j < 8; ++j) { if (patchstat[i][j] != null) { count += patchstat[i][j].Length; } } } if (count == 0) { binidx.Write((int)-1); // lookup binidx.Write((int)-1); // length binidx.Write((int)-1); // extra } else { int fsmullength = (int)fsmul.Position; if (RemoveDupl.Checked) { StaticTile[] tilelist = new StaticTile[count]; int m = 0; for (int i = 0; i < 8; ++i) { for (int j = 0; j < 8; ++j) { foreach (HuedTile htile in patchstat[i][j]) { StaticTile tile = new StaticTile(); tile.m_ID = (ushort)(htile.ID); tile.m_Z = (sbyte)htile.Z; tile.m_X = (byte)i; tile.m_Y = (byte)j; tile.m_Hue = (short)htile.Hue; if ((tile.m_ID >= 0) && (tile.m_ID <= Art.GetMaxItemID())) { if (tile.m_Hue < 0) { tile.m_Hue = 0; } bool first = true; for (int k = 0; k < m; ++k) { if ((tilelist[k].m_ID == tile.m_ID) && ((tilelist[k].m_X == tile.m_X) && (tilelist[k].m_Y == tile.m_Y)) && (tilelist[k].m_Z == tile.m_Z) && (tilelist[k].m_Hue == tile.m_Hue)) { first = false; break; } } if (first) { tilelist[m] = tile; ++m; } } } } } if (m > 0) { binidx.Write((int)fsmul.Position); //lookup for (int i = 0; i < m; ++i) { binmul.Write(tilelist[i].m_ID); binmul.Write(tilelist[i].m_X); binmul.Write(tilelist[i].m_Y); binmul.Write(tilelist[i].m_Z); binmul.Write(tilelist[i].m_Hue); } } } else { ushort graphic; short shue; sbyte sz; bool firstitem = true; for (int i = 0; i < 8; ++i) { for (int j = 0; j < 8; ++j) { foreach (HuedTile tile in patchstat[i][j]) { graphic = tile.ID; sz = (sbyte)tile.Z; shue = (short)tile.Hue; if ((graphic >= 0) && (graphic <= Art.GetMaxItemID())) { if (shue < 0) { shue = 0; } if (firstitem) { binidx.Write((int)fsmul.Position); //lookup firstitem = false; } binmul.Write(graphic); binmul.Write((byte)i); //x binmul.Write((byte)j); //y binmul.Write(sz); binmul.Write(shue); } } } } } fsmullength = (int)fsmul.Position - fsmullength; if (fsmullength > 0) { binidx.Write(fsmullength); //length binidx.Write(extra); //extra } else { binidx.Write((int)-1); //lookup binidx.Write((int)-1); //length binidx.Write((int)-1); //extra } } } else { if (lookup < 0 || length <= 0) { binidx.Write((int)-1); // lookup binidx.Write((int)-1); // length binidx.Write((int)-1); // extra } else { m_Statics.Seek(lookup, SeekOrigin.Begin); int fsmullength = (int)fsmul.Position; int count = length / 7; if (RemoveDupl.Checked) { StaticTile[] tilelist = new StaticTile[count]; int j = 0; for (int i = 0; i < count; ++i) { StaticTile tile = new StaticTile(); tile.m_ID = m_StaticsReader.ReadUInt16(); tile.m_X = m_StaticsReader.ReadByte(); tile.m_Y = m_StaticsReader.ReadByte(); tile.m_Z = m_StaticsReader.ReadSByte(); tile.m_Hue = m_StaticsReader.ReadInt16(); if ((tile.m_ID >= 0) && (tile.m_ID <= Art.GetMaxItemID())) { if (tile.m_Hue < 0) { tile.m_Hue = 0; } bool first = true; for (int k = 0; k < j; ++k) { if ((tilelist[k].m_ID == tile.m_ID) && ((tilelist[k].m_X == tile.m_X) && (tilelist[k].m_Y == tile.m_Y)) && (tilelist[k].m_Z == tile.m_Z) && (tilelist[k].m_Hue == tile.m_Hue)) { first = false; break; } } if (first) { tilelist[j++] = tile; } } } if (j > 0) { binidx.Write((int)fsmul.Position); //lookup for (int i = 0; i < j; ++i) { binmul.Write(tilelist[i].m_ID); binmul.Write(tilelist[i].m_X); binmul.Write(tilelist[i].m_Y); binmul.Write(tilelist[i].m_Z); binmul.Write(tilelist[i].m_Hue); } } } else { bool firstitem = true; for (int i = 0; i < count; ++i) { ushort graphic; short shue; byte sx, sy; sbyte sz; graphic = m_StaticsReader.ReadUInt16(); sx = m_StaticsReader.ReadByte(); sy = m_StaticsReader.ReadByte(); sz = m_StaticsReader.ReadSByte(); shue = m_StaticsReader.ReadInt16(); if ((graphic >= 0) && (graphic <= Art.GetMaxItemID())) { if (shue < 0) { shue = 0; } if (firstitem) { binidx.Write((int)fsmul.Position); //lookup firstitem = false; } binmul.Write(graphic); binmul.Write(sx); binmul.Write(sy); binmul.Write(sz); binmul.Write(shue); } } } fsmullength = (int)fsmul.Position - fsmullength; if (fsmullength > 0) { binidx.Write(fsmullength); //length binidx.Write(extra); //extra } else { binidx.Write((int)-1); //lookup binidx.Write((int)-1); //length binidx.Write((int)-1); //extra } } } progressBar1.PerformStep(); } } } } m_IndexReader.Close(); m_StaticsReader.Close(); } MessageBox.Show(String.Format("Files saved to {0}", FiddlerControls.Options.OutputPath), "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); }
public Point3D RandomSpawnLocation(int spawnHeight, bool land, bool water, Point3D home, int range) { Map map = this.Map; if (map == Map.Internal) { return(Point3D.Zero); } InitRectangles(); if (m_TotalWeight <= 0) { return(Point3D.Zero); } for (int i = 0; i < 10; i++) // Try 10 times { int x, y, minZ, maxZ; if (home == Point3D.Zero) { int rand = Utility.Random(m_TotalWeight); x = int.MinValue; y = int.MinValue; minZ = int.MaxValue; maxZ = int.MinValue; for (int j = 0; j < m_RectangleWeights.Length; j++) { int curWeight = m_RectangleWeights[j]; if (rand < curWeight) { Rectangle3D rect = m_Rectangles[j]; x = rect.Start.X + rand % rect.Width; y = rect.Start.Y + rand / rect.Width; minZ = rect.Start.Z; maxZ = rect.End.Z; break; } rand -= curWeight; } } else { x = Utility.RandomMinMax(home.X - range, home.X + range); y = Utility.RandomMinMax(home.Y - range, home.Y + range); minZ = int.MaxValue; maxZ = int.MinValue; for (int j = 0; j < this.Area.Length; j++) { Rectangle3D rect = this.Area[j]; if (x >= rect.Start.X && x < rect.End.X && y >= rect.Start.Y && y < rect.End.Y) { minZ = rect.Start.Z; maxZ = rect.End.Z; break; } } if (minZ == int.MaxValue) { continue; } } if (x < 0 || y < 0 || x >= map.Width || y >= map.Height) { continue; } LandTile lt = map.Tiles.GetLandTile(x, y); int ltLowZ = 0, ltAvgZ = 0, ltTopZ = 0; map.GetAverageZ(x, y, ref ltLowZ, ref ltAvgZ, ref ltTopZ); TileFlag ltFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags; bool ltImpassable = ((ltFlags & TileFlag.Impassable) != 0); if (!lt.Ignored && ltAvgZ >= minZ && ltAvgZ < maxZ) { if ((ltFlags & TileFlag.Wet) != 0) { if (water) { m_SpawnBuffer1.Add(ltAvgZ); } } else if (land && !ltImpassable) { m_SpawnBuffer1.Add(ltAvgZ); } } StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y, true); for (int j = 0; j < staticTiles.Length; j++) { StaticTile tile = staticTiles[j]; ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; int tileZ = tile.Z + id.CalcHeight; if (tileZ >= minZ && tileZ < maxZ) { if ((id.Flags & TileFlag.Wet) != 0) { if (water) { m_SpawnBuffer1.Add(tileZ); } } else if (land && id.Surface && !id.Impassable) { m_SpawnBuffer1.Add(tileZ); } } } Sector sector = map.GetSector(x, y); for (int j = 0; j < sector.Items.Count; j++) { Item item = sector.Items[j]; if (!(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y)) { m_SpawnBuffer2.Add(item); if (!item.Movable) { ItemData id = item.ItemData; int itemZ = item.Z + id.CalcHeight; if (itemZ >= minZ && itemZ < maxZ) { if ((id.Flags & TileFlag.Wet) != 0) { if (water) { m_SpawnBuffer1.Add(itemZ); } } else if (land && id.Surface && !id.Impassable) { m_SpawnBuffer1.Add(itemZ); } } } } } if (m_SpawnBuffer1.Count == 0) { m_SpawnBuffer1.Clear(); m_SpawnBuffer2.Clear(); continue; } int z; switch (m_SpawnZLevel) { case SpawnZLevel.Lowest: { z = int.MaxValue; for (int j = 0; j < m_SpawnBuffer1.Count; j++) { int l = m_SpawnBuffer1[j]; if (l < z) { z = l; } } break; } case SpawnZLevel.Highest: { z = int.MinValue; for (int j = 0; j < m_SpawnBuffer1.Count; j++) { int l = m_SpawnBuffer1[j]; if (l > z) { z = l; } } break; } default: // SpawnZLevel.Random { int index = Utility.Random(m_SpawnBuffer1.Count); z = m_SpawnBuffer1[index]; break; } } m_SpawnBuffer1.Clear(); if (!Region.Find(new Point3D(x, y, z), map).AcceptsSpawnsFrom(this)) { m_SpawnBuffer2.Clear(); continue; } int top = z + spawnHeight; bool ok = true; for (int j = 0; j < m_SpawnBuffer2.Count; j++) { Item item = m_SpawnBuffer2[j]; ItemData id = item.ItemData; if ((id.Surface || id.Impassable) && item.Z + id.CalcHeight > z && item.Z < top) { ok = false; break; } } m_SpawnBuffer2.Clear(); if (!ok) { continue; } if (ltImpassable && ltAvgZ > z && ltLowZ < top) { continue; } for (int j = 0; j < staticTiles.Length; j++) { StaticTile tile = staticTiles[j]; ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; if ((id.Surface || id.Impassable) && tile.Z + id.CalcHeight > z && tile.Z < top) { ok = false; break; } } if (!ok) { continue; } for (int j = 0; j < sector.Mobiles.Count; j++) { Mobile m = sector.Mobiles[j]; if (m.X == x && m.Y == y && (m.AccessLevel == AccessLevel.Player || !m.Hidden)) { if (m.Z + 16 > z && m.Z < top) { ok = false; break; } } } if (ok) { return(new Point3D(x, y, z)); } } return(Point3D.Zero); }
public static void CheckStatic(BaseCreature fbc) { if (NullCheck(fbc)) { return; } const int a = -1; const int b = 1; const int c = 0; int xx = 0; int yy = 0; if (fbc.CDirection == 1) { xx = c; yy = a; } if (fbc.CDirection == 2) { xx = b; yy = a; } if (fbc.CDirection == 3) { xx = b; yy = c; } if (fbc.CDirection == 4) { xx = b; yy = b; } if (fbc.CDirection == 5) { xx = c; yy = b; } if (fbc.CDirection == 6) { xx = a; yy = b; } if (fbc.CDirection == 7) { xx = a; yy = c; } if (fbc.CDirection == 8) { xx = a; yy = a; } StaticTile[] tiles = fbc.Map.Tiles.GetStaticTiles((fbc.X + xx), (fbc.Y + yy), true); if (tiles == null) { return; } for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; if (fbc.Z <= tile.Z) { ChangeDirection(fbc); } } }
public StaticTile[] ToArray() { if (m_Count == 0) { return m_EmptyTiles; } StaticTile[] staticTiles = new StaticTile[m_Count]; for (int i = 0; i < m_Count; ++i) { staticTiles[i] = m_StaticTiles[i]; } m_Count = 0; return staticTiles; }
private static bool IsOk(StaticTile tile, int ourZ, int ourTop) { var itemData = TileData.ItemTable[tile.ID & TileData.MaxItemValue]; return tile.Z + itemData.CalcHeight <= ourZ || ourTop <= tile.Z || (itemData.Flags & ImpassableSurface) == 0; }
public MultiComponentList(BinaryReader reader, int count) { int streamStart = (int)reader.BaseStream.Position; m_Min = m_Max = Point.Empty; MultiTileEntry[] allTiles = new MultiTileEntry[count]; for (int i = 0; i < count; ++i) { allTiles[i].m_ItemID = reader.ReadInt16(); allTiles[i].m_OffsetX = reader.ReadInt16(); allTiles[i].m_OffsetY = reader.ReadInt16(); allTiles[i].m_OffsetZ = reader.ReadInt16(); allTiles[i].m_Flags = reader.ReadInt32(); MultiTileEntry e = allTiles[i]; if (e.m_OffsetX < m_Min.X) m_Min.X = e.m_OffsetX; if (e.m_OffsetY < m_Min.Y) m_Min.Y = e.m_OffsetY; if (e.m_OffsetX > m_Max.X) m_Max.X = e.m_OffsetX; if (e.m_OffsetY > m_Max.Y) m_Max.Y = e.m_OffsetY; } m_Center = new Point(-m_Min.X, -m_Min.Y); m_Width = (m_Max.X - m_Min.X) + 1; m_Height = (m_Max.Y - m_Min.Y) + 1; StaticTileList[][] tiles = new StaticTileList[m_Width][]; m_Tiles = new StaticTile[m_Width][][]; for (int x = 0; x < m_Width; ++x) { tiles[x] = new StaticTileList[m_Height]; m_Tiles[x] = new StaticTile[m_Height][]; for (int y = 0; y < m_Height; ++y) tiles[x][y] = new StaticTileList(); } for (int i = 0; i < allTiles.Length; ++i) { int xOffset = allTiles[i].m_OffsetX + m_Center.X; int yOffset = allTiles[i].m_OffsetY + m_Center.Y; tiles[xOffset][yOffset].Add((short)((allTiles[i].m_ItemID & 0x3FFF) + 0x4000), (sbyte)allTiles[i].m_OffsetZ); } for (int x = 0; x < m_Width; ++x) { for (int y = 0; y < m_Height; ++y) { m_Tiles[x][y] = tiles[x][y].ToArray(); // // This is unnecessary, since TileEngine has to sort/resort anyways. // // if (m_Tiles[x][y].Length > 1) // { // Array.Sort(m_Tiles[x][y]); // } } } ClientVars.Metrics.ReportDataRead((int)reader.BaseStream.Position - streamStart); }
private unsafe int PatchStatics(TileMatrix tileMatrix, string dataPath, string indexPath, string lookupPath) { using (FileStream fsData = FileManager.GetFile(dataPath)) { using (FileStream fsIndex = FileManager.GetFile(indexPath)) { using (FileStream fsLookup = FileManager.GetFile(lookupPath)) { BinaryReader indexReader = new BinaryReader(fsIndex); BinaryReader lookupReader = new BinaryReader(fsLookup); int count = (int)(indexReader.BaseStream.Length / 4); StaticTileList[][] lists = new StaticTileList[8][]; for (int x = 0; x < 8; ++x) { lists[x] = new StaticTileList[8]; for (int y = 0; y < 8; ++y) { lists[x][y] = new StaticTileList(); } } for (int i = 0; i < count; ++i) { int blockID = indexReader.ReadInt32(); int blockX = blockID / tileMatrix.BlockHeight; int blockY = blockID % tileMatrix.BlockHeight; int offset = lookupReader.ReadInt32(); int length = lookupReader.ReadInt32(); lookupReader.ReadInt32(); if (offset < 0 || length <= 0) { tileMatrix.SetStaticBlock(blockX, blockY, tileMatrix.EmptyStaticsBlock); continue; } fsData.Seek(offset, SeekOrigin.Begin); int tileCount = length / 7; if (m_TileBuffer.Length < tileCount) { m_TileBuffer = new StaticTile[tileCount]; } StaticTile[] staticTiles = m_TileBuffer; fixed (StaticTile* pStaticTiles = staticTiles) { SharedMethods.Read(fsData.SafeFileHandle, pStaticTiles, length); StaticTile* pCur = pStaticTiles, pEnd = pStaticTiles + tileCount; while (pCur < pEnd) { lists[pCur->X & 0x07][pCur->Y & 0x07].Add((short)((pCur->ID & 0x3FFF) + 0x4000), pCur->Z); pCur = pCur + 1; } StaticTile[][][] tiles = new StaticTile[8][][]; for (int x = 0; x < 8; ++x) { tiles[x] = new StaticTile[8][]; for (int y = 0; y < 8; ++y) { tiles[x][y] = lists[x][y].ToArray(); } } tileMatrix.SetStaticBlock(blockX, blockY, tiles); } } indexReader.Close(); lookupReader.Close(); return count; } } } }
public static void ApplyPatch(Map map, Stream patch, Action <string> logger = null) { using (var stream = new GZipInputStream(patch)) using (var reader = new BinaryReader(stream)) { logger?.Invoke("Verifying input as TDIFF file..."); string signature = new string(reader.ReadChars(5)); if (!signature.Equals("TDIFF")) { throw new InvalidDataException("Input stream is not a TDIFF file."); } logger?.Invoke("Checking TDIFF revision of file..."); byte revision = reader.ReadByte(); switch (revision) { case 0: logger?.Invoke("File is revision 0, parsing file..."); while (true) { Actions action = (Actions)reader.ReadByte(); logger?.Invoke("Current instruction: " + action); if (action == Actions.EOF) { break; } switch (action) { case Actions.SetStaticTile: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); int tileIndex = reader.ReadInt32(); layer.Tiles[x, y] = new StaticTile(layer, sheet, BlendMode.Additive, tileIndex); } break; case Actions.SetAnimatedTile: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); long interval = reader.ReadInt64(); int frames = reader.ReadInt32(); var list = new StaticTile[frames]; for (int c = 0; c < frames; c++) { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); int tileIndex = reader.ReadInt32(); list[c] = new StaticTile(layer, sheet, BlendMode.Additive, tileIndex); } layer.Tiles[x, y] = new AnimatedTile(layer, list, interval); } break; case Actions.RemoveTile: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); layer.Tiles[x, y] = null; } break; case Actions.SetTileProperty: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (layer.Tiles[x, y] == null) { throw new NullReferenceException("Map does not contain a tile at the given position: " + layerId + "[" + x + "," + y + "]"); } if (layer.Tiles[x, y].Properties.ContainsKey(propertyKey)) { layer.Tiles[x, y].Properties[propertyKey] = propertyValue; } else { layer.Tiles[x, y].Properties.Add(propertyKey, propertyValue); } } break; case Actions.RemoveTileProperty: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte x = reader.ReadByte(); byte y = reader.ReadByte(); string propertyKey = reader.ReadTiny(); if (layer.Tiles[x, y] == null) { throw new NullReferenceException("Map does not contain a tile at the given position: " + layerId + "[" + x + "," + y + "]"); } if (layer.Tiles[x, y].Properties.ContainsKey(propertyKey)) { layer.Tiles[x, y].Properties.Remove(propertyKey); } } break; case Actions.SetTileIndexProperty: { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); int tileIndex = reader.ReadInt32(); string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (sheet.TileIndexProperties[tileIndex].ContainsKey(propertyKey)) { sheet.TileIndexProperties[tileIndex][propertyKey] = propertyValue; } else { sheet.TileIndexProperties[tileIndex].Add(propertyKey, propertyValue); } } break; case Actions.RemoveTileIndexProperty: { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); int tileIndex = reader.ReadInt32(); string propertyKey = reader.ReadTiny(); if (sheet.TileIndexProperties[tileIndex].ContainsKey(propertyKey)) { sheet.TileIndexProperties[tileIndex].Remove(propertyKey); } } break; case Actions.SetTilesheetProperty: { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (sheet.Properties.ContainsKey(propertyKey)) { sheet.Properties[propertyKey] = propertyValue; } else { sheet.Properties.Add(propertyKey, propertyValue); } } break; case Actions.RemoveTilesheetProperty: { string sheetId = reader.ReadTiny(); var sheet = map.GetTileSheet(sheetId) ?? throw new NullReferenceException("Map does not contain a tilesheet with given Id: " + sheetId); string propertyKey = reader.ReadTiny(); if (sheet.Properties.ContainsKey(propertyKey)) { sheet.Properties.Remove(propertyKey); } } break; case Actions.SetLayerProperty: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (layer.Properties.ContainsKey(propertyKey)) { layer.Properties[propertyKey] = propertyValue; } else { layer.Properties.Add(propertyKey, propertyValue); } } break; case Actions.RemoveLayerProperty: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); string propertyKey = reader.ReadTiny(); if (layer.Properties.ContainsKey(propertyKey)) { layer.Properties.Remove(propertyKey); } } break; case Actions.SetMapProperty: { string propertyKey = reader.ReadTiny(); string propertyValue = reader.ReadString(); if (map.Properties.ContainsKey(propertyKey)) { map.Properties[propertyKey] = propertyValue; } else { map.Properties.Add(propertyKey, propertyValue); } } break; case Actions.RemoveMapProperty: { string propertyKey = reader.ReadTiny(); if (map.Properties.ContainsKey(propertyKey)) { map.Properties.Remove(propertyKey); } } break; case Actions.AddLayer: { string layerId = reader.ReadTiny(); if (map.GetLayer(layerId) == null) { byte width = reader.ReadByte(); byte height = reader.ReadByte(); map.AddLayer(new xTile.Layers.Layer(layerId, map, new xTile.Dimensions.Size(width, height), new xTile.Dimensions.Size(16))); } } break; case Actions.RemoveLayer: { string layerId = reader.ReadTiny(); if (map.GetLayer(layerId) != null) { map.RemoveLayer(map.GetLayer(layerId)); } } break; case Actions.ResizeLayer: { string layerId = reader.ReadTiny(); var layer = map.GetLayer(layerId) ?? throw new NullReferenceException("Map does not contain a layer with given Id: " + layerId); byte width = reader.ReadByte(); byte height = reader.ReadByte(); layer.LayerSize = new xTile.Dimensions.Size(width, height); } break; default: throw new InvalidDataException("Possibly corrupt TDIFF file, action is unknown:" + action); } } break; default: throw new InvalidDataException("Input stream uses a unsupported TDIFF revision:" + revision); } logger?.Invoke("Patching process has completed."); } }
public static Map mergeInto(this Map t, Map map, Vector2 position, Microsoft.Xna.Framework.Rectangle?sourceArea = null, bool includeEmpty = true, bool properties = true) { Microsoft.Xna.Framework.Rectangle sourceRectangle = sourceArea.HasValue ? sourceArea.Value : new Microsoft.Xna.Framework.Rectangle(0, 0, t.DisplayWidth / Game1.tileSize, t.DisplayHeight / Game1.tileSize); foreach (TileSheet tilesheet in t.TileSheets) { if (!map.hasTileSheet(tilesheet)) { map.AddTileSheet(new TileSheet(tilesheet.Id, map, tilesheet.ImageSource, tilesheet.SheetSize, tilesheet.TileSize)); } } if (properties) { foreach (KeyValuePair <string, PropertyValue> p in t.Properties) { if (map.Properties.ContainsKey(p.Key)) { if (p.Key == "EntryAction") { map.Properties[p.Key] = map.Properties[p.Key] + ";" + p.Value; } else { map.Properties[p.Key] = p.Value; } } else { map.Properties.Add(p); } } } for (int x = 0; x < sourceRectangle.Width; x++) { for (int y = 0; y < sourceRectangle.Height; y++) { foreach (Layer layer in t.Layers) { int px = (int)position.X + x; int py = (int)position.Y + y; int sx = (int)sourceRectangle.X + x; int sy = (int)sourceRectangle.Y + y; Tile sourceTile = layer.Tiles[(int)sx, (int)sy]; Layer mapLayer = map.GetLayer(layer.Id); if (mapLayer == null) { map.InsertLayer(new Layer(layer.Id, map, map.Layers[0].LayerSize, map.Layers[0].TileSize), map.Layers.Count); mapLayer = map.GetLayer(layer.Id); } if (properties) { foreach (var prop in layer.Properties) { if (!mapLayer.Properties.ContainsKey(prop.Key)) { mapLayer.Properties.Add(prop); } else { mapLayer.Properties[prop.Key] = prop.Value; } } } if (sourceTile == null) { if (includeEmpty) { try { mapLayer.Tiles[(int)px, (int)py] = null; } catch { } } continue; } TileSheet tilesheet = map.GetTileSheet(sourceTile.TileSheet.Id); Tile newTile = new StaticTile(mapLayer, tilesheet, BlendMode.Additive, sourceTile.TileIndex); try { if (sourceTile.Properties.ContainsKey("NoTileMerge")) { newTile = mapLayer.Tiles[(int)px, (int)py]; } } catch { } if (sourceTile is AnimatedTile aniTile) { List <StaticTile> staticTiles = new List <StaticTile>(); foreach (StaticTile frame in aniTile.TileFrames) { staticTiles.Add(new StaticTile(mapLayer, tilesheet, BlendMode.Additive, frame.TileIndex)); } newTile = new AnimatedTile(mapLayer, staticTiles.ToArray(), aniTile.FrameInterval); } if (properties) { foreach (var prop in sourceTile.Properties) { if (newTile.Properties.ContainsKey(prop.Key)) { newTile.Properties[prop.Key] = prop.Value; } else { newTile.Properties.Add(prop); } } foreach (var prop in sourceTile.TileIndexProperties) { if (newTile.TileIndexProperties.ContainsKey(prop.Key)) { newTile.TileIndexProperties[prop.Key] = prop.Value; } else { newTile.TileIndexProperties.Add(prop); } } } try { mapLayer.Tiles[(int)px, (int)py] = newTile; } catch (Exception e) { Monitor.Log($"{e.Message} ({map.DisplayWidth} -> {layer.Id} -> {px}:{py})"); } } } } return(map); }
public static Container Mobile_CreateCorpseHandler(Mobile owner, HairInfo hair, FacialHairInfo facialhair, List <Item> initialContent, List <Item> equipItems) { bool shouldFillCorpse = true; Corpse c = null; if (owner == null) { return(c); } c = new Corpse(owner, hair, facialhair, shouldFillCorpse ? equipItems : new List <Item>()); if (c == null) { return(c); } owner.Corpse = c; if (shouldFillCorpse) { for (int i = 0; i < initialContent.Count; ++i) { Item item = initialContent[i]; if (item == null) { continue; } c.DropItem(item); } } else { c.Carved = true; } Point3D loc = owner.Location; Map map = owner.Map; if (map == null || map == Map.Internal) { loc = owner.LogoutLocation; map = owner.LogoutMap; } c.MoveToWorld(loc, map); //Creature or Player Ocean Corpse Advanced Decay Rate if (!(c.Map == null || c.Map == Map.Internal)) { if (c.Map.Tiles != null) { LandTile landTile = c.Map.Tiles.GetLandTile(c.X, c.Y); StaticTile[] tiles = c.Map.Tiles.GetStaticTiles(c.X, c.Y, true); bool landHasWater = false; bool staticHasWater = false; if ((landTile.ID >= 168 && landTile.ID <= 171) || (landTile.ID >= 310 && landTile.ID <= 311)) { landHasWater = true; } for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; bool isWater = (tile.ID >= 0x1796 && tile.ID <= 0x17B2); if (isWater) { staticHasWater = true; } } if ((landHasWater || staticHasWater) && c.TotalItems == 0) { if (c.m_DecayTimer != null) { c.m_DecayTimer.Stop(); } //Empty PlayerMobile is 30 Seconds Decay if (c.Owner is PlayerMobile) { c.BeginDecay(TimeSpan.FromSeconds(30)); } //Empty Creature is 10 Seconds Decay else { c.BeginDecay(TimeSpan.FromSeconds(10)); } } } } return(c); }
public override void OnItemLifted(Mobile from, Item item) { base.OnItemLifted(from, item); if (item != this && from != m_Owner) { from.RevealingAction(); } if (item != this && IsCriminalAction(from)) { from.CriminalAction(true); } if (from.AccessLevel == AccessLevel.Player && !m_Looters.Contains(from)) { m_Looters.Add(from); } //Ocean Creature Advanced Decay Rate LandTile landTile = this.Map.Tiles.GetLandTile(this.X, this.Y); StaticTile[] tiles = this.Map.Tiles.GetStaticTiles(this.X, this.Y, true); bool landHasWater = false; bool staticHasWater = false; if ((landTile.ID >= 168 && landTile.ID <= 171) || (landTile.ID >= 310 && landTile.ID <= 311)) { landHasWater = true; } for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; bool isWater = (tile.ID >= 0x1796 && tile.ID <= 0x17B2); if (isWater) { staticHasWater = true; } } //Last Item Lifted if ((landHasWater || staticHasWater) && this.TotalItems <= 1) { if (m_DecayTimer != null) { m_DecayTimer.Stop(); } //Empty PlayerMobile is 30 Seconds Decay if (this.Owner is PlayerMobile) { BeginDecay(TimeSpan.FromSeconds(30)); } //Empty Creature is 10 Seconds Decay else { BeginDecay(TimeSpan.FromSeconds(10)); } } }
public StaticTile[] GetStatics(int width, int height) { List<StaticTile> statics = new List<StaticTile>(); // Custom Houses are sent in 'planes' of four different types. We determine which type we're looking at the index and the size. int sizeFloor = ((width - 1) * (height - 1)); int sizeWalls = (width * height); // There is no z data for most planes, so we have to determine their z by their relative position to preceeding planes of the same type. int numTilesInLastPlane = 0; int zIndex = 0; for (int plane = 0; plane < m_planeCount; plane++) { int numTiles = m_planes[plane].ItemData.Length >> 1; if ((plane == m_planeCount - 1) && (numTiles != sizeFloor) && (numTiles != sizeWalls)) { numTiles = m_planes[plane].ItemData.Length / 5; int index = 0; for (int j = 0; j < numTiles; j++) { StaticTile s = new StaticTile(); s.ID = (short)((m_planes[plane].ItemData[index++] << 8) + m_planes[plane].ItemData[index++]); int x = (sbyte)m_planes[plane].ItemData[index++]; int y = (sbyte)m_planes[plane].ItemData[index++]; int z = (sbyte)m_planes[plane].ItemData[index++]; s.X = (byte)((width >> 1) + x - 1); s.Y = (byte)((height >> 1) + y); s.Z = (sbyte)z; statics.Add(s); } } else { int iWidth = width, iHeight = height; int iX = 0, iY = 0; int x = 0, y = 0, z = 0; if (plane == 0) { zIndex = 0; iWidth += 1; iHeight += 1; } else if (numTiles == sizeFloor) { if (numTilesInLastPlane != sizeFloor) zIndex = 1; else zIndex++; iWidth -= 1; iHeight -= 1; iX = 1; iY = 1; } else if (numTiles == sizeWalls) { if (numTilesInLastPlane != sizeWalls) zIndex = 1; else zIndex++; } switch (zIndex) { case 0: z = 0; break; case 1: z = 7; break; case 2: z = 27; break; case 3: z = 47; break; case 4: z = 67; break; default: continue; } int index = 0; for (int j = 0; j < numTiles; j++) { StaticTile s = new StaticTile(); s.ID = (short)((m_planes[plane].ItemData[index++] << 8) + m_planes[plane].ItemData[index++]); s.X = (byte)(x + iX); s.Y = (byte)(y + iY); s.Z = (sbyte)z; y++; if (y >= iHeight) { y = 0; x++; } statics.Add(s); } numTilesInLastPlane = numTiles; } } return statics.ToArray(); }
public override void OnClick() { Race race = ((Player)pm).Race; switch (race) { case Race.Ogre: { pm.Target = new OgreTarget(); pm.SendMessage("Target a creature to bash!"); break; } case Race.Terathan: { mobList = new List <Mobile>(); foreach (Mobile mobile in pm.GetMobilesInRange(8)) { if (mobile.AccessLevel > pm.AccessLevel) { continue; } else if (mobile.Blessed || !mobile.Alive) { continue; } else if (mobile == pm) { continue; } else { mobList.Add(mobile); } } if (mobList != null) { Timer.DelayCall(TimeSpan.FromSeconds(8.0), new TimerCallback(FinishWebs)); pm.PublicOverheadMessage(MessageType.Regular, pm.EmoteHue, false, "*Begins hurling webs at nearby creatures*"); for (int i = 0; i < mobList.Count; i++) { Mobile m = mobList[i]; if (m is PlayerMobile && 0.51 > Utility.RandomDouble()) { m.SendMessage("You've been struck by a terathan web!"); } m.CantWalk = true; Effects.SendMovingEffect(pm, m, 4308, 0, 10, false, false); } Effects.PlaySound(pm.Location, pm.Map, 0x027); pm.NextRaceAbility = TimeSpan.FromMinutes(1); } break; } case Race.Lich: { if (pm.Followers >= pm.FollowersMax) { pm.SendMessage("You already have too many followers to summon more."); } else { do { BaseCreature bc = null; switch (Utility.Random(3)) { case 0: bc = new Skeleton(); break; case 1: bc = new Zombie(); break; case 2: bc = new Wraith(); break; } if (bc != null && BaseCreature.Summon(bc, true, pm, Point3D.Zero, 0x1E2, TimeSpan.FromMinutes(1.5))) { bc.MoveToWorld(new Point3D(pm.X + Utility.RandomMinMax(1, 3), pm.Y - Utility.RandomMinMax(0, 3), pm.Z), pm.Map); Effects.SendLocationEffect(pm.Location, pm.Map, 0x3709, 15, 945, 0); } }while (pm.Followers < pm.FollowersMax); pm.NextRaceAbility = TimeSpan.FromMinutes(2.0); } break; } case Race.HalfDaemon: { if (pm.AbilityActive) { pm.RaceBody = 0; pm.BodyDamageBonus = 0; pm.AdjustBody(); pm.Str -= 40; pm.Dex -= 20; pm.Int += 60; pm.AbilityActive = false; pm.PublicOverheadMessage(MessageType.Regular, pm.EmoteHue, false, String.Format("*{0} begins to shrink, taking the form of a human*", pm.Name)); } else { for (int x = 1; x <= 2; x++) { Item toDisarm = pm.FindItemOnLayer(Layer.OneHanded); if (toDisarm == null || !toDisarm.Movable) { toDisarm = pm.FindItemOnLayer(Layer.TwoHanded); } Container pack = pm.Backpack; pack.DropItem(toDisarm); } pm.RaceBody = 792; pm.AdjustBody(); pm.BodyDamageBonus = 36; pm.Str += 40; pm.Dex += 20; pm.Int -= 60; pm.AbilityActive = true; pm.PublicOverheadMessage(MessageType.Regular, pm.EmoteHue, false, String.Format("*{0}'s flesh begins to buldge and tear as something emerges from within*", pm.Name)); } break; } case Race.Shapeshifter: { pm.Target = new ShapeshifterTarget(); pm.SendMessage("Select a creature to assume their form."); break; } case Race.Marid: { if (pm.AbilityActive) { pm.AbilityActive = false; pm.CanSwim = false; Effects.SendLocationParticles(EffectItem.Create(pm.Location, pm.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023); try { IMount mount = pm.Mount; mount.Rider = null; ((EtherealMount)mount).Delete(); } catch { } } else { for (int x = 1; x <= 2; x++) { Item toDisarm = pm.FindItemOnLayer(Layer.OneHanded); if (toDisarm == null || !toDisarm.Movable) { toDisarm = pm.FindItemOnLayer(Layer.TwoHanded); } Container pack = pm.Backpack; pack.DropItem(toDisarm); } pm.AbilityActive = true; pm.PublicOverheadMessage(MessageType.Regular, pm.EmoteHue, false, String.Format("*A mass of vapors condenses under {0}, forming a steed*", pm.Name)); pm.CanSwim = true; bool isWater = false; Map map = pm.Map; LandTile land = map.Tiles.GetLandTile(pm.X, pm.Y); StaticTile[] tiles = map.Tiles.GetStaticTiles(pm.X, pm.Y); isWater = (land.Z == pm.Z && ((land.ID >= 168 && land.ID <= 171) || (land.ID >= 310 && land.ID <= 311))); for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; isWater = (tile.ID >= 0x1796 && tile.ID <= 0x17B2); } try { if (isWater) { EtherealMount seaHorse = new EtherealSeaHorse(); seaHorse.MoveToWorld(pm.Location); seaHorse.Rider = pm; } else { EtherealMount horse = new EtherealHorse(); horse.MoveToWorld(pm.Location); horse.Rider = pm; } } catch { } } break; } default: break; } }