예제 #1
0
		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];
		}
예제 #2
0
		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;
		}
예제 #3
0
파일: Movement.cs 프로젝트: Crome696/ServUO
        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;
        }
예제 #4
0
    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);
 }
예제 #6
0
        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);
        }
예제 #7
0
        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;
            }
        }
예제 #8
0
        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();
        }
예제 #9
0
        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();
                }
            }
        }
예제 #10
0
 private void StoreStaticTile(Stream stream, StaticTile staticTile)
 {
     StoreInt32(stream, staticTile.TileIndex);
     stream.WriteByte((byte)staticTile.BlendMode);
     StoreProperties(stream, staticTile);
 }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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();
                }
            }
        }
예제 #14
0
        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);
            }
        }
예제 #15
0
        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);
        }
예제 #16
0
 void Start()
 {
     StaticTile.AddTile(transform.position, this);
 }
예제 #17
0
        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);
            }
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
        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);
        }
예제 #21
0
        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);
        }
예제 #22
0
        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!
            }
        }
예제 #23
0
        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);
        }
예제 #24
0
        /// <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;
                    }
                }
            }
        }
예제 #25
0
        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);
        }
예제 #26
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);
            }
        }
예제 #27
0
        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);
        }
예제 #28
0
        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);
        }
예제 #29
0
        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);
        }
예제 #30
0
        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);
                }
            }
        }
예제 #31
0
        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;
        }
예제 #32
0
		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;
		}
예제 #33
0
파일: Multis.cs 프로젝트: Crwth/UltimaXNA
        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);
        }
예제 #34
0
        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;
                    }
                }
            }
        }
예제 #35
0
        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.");
                }
        }
예제 #36
0
        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);
        }
예제 #37
0
파일: Corpse.cs 프로젝트: Pumpk1ns/outlands
        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);
        }
예제 #38
0
파일: Corpse.cs 프로젝트: Pumpk1ns/outlands
        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));
                }
            }
        }
예제 #39
0
        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();
        }
예제 #40
0
        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;
            }
        }