Esempio n. 1
0
        internal static List <Assistant.Point3D> CoordsToMobile(Assistant.Mobile mobile)
        {
            List <Assistant.Point3D> coords = new List <Assistant.Point3D>();

            Assistant.Point3D playerPosition = World.Player.Position;
            Assistant.Point3D mobPosition    = mobile.Position;

            // player is x0 mob is x1 in m = (y1?y0)/(x1?x0)
            float slope = (float)((float)mobPosition.Y - playerPosition.Y) / ((float)mobPosition.X - playerPosition.X);

            // for every x compute the y
            for (int x = Math.Min(playerPosition.X, mobPosition.X); x <= Math.Max(playerPosition.X, mobPosition.X); x++)
            {
                // formula for y is y = m* (x-x0) + y0
                if (x != playerPosition.X)
                {
                    int y = (int)(slope * ((float)x - playerPosition.X) + playerPosition.Y);
                    coords.Add(new Assistant.Point3D(x, y, Statics.GetLandZ(x, y, Player.Map)));
                }
            }

            // for every y compute the x
            for (int y = Math.Min(playerPosition.Y, mobPosition.Y); y <= Math.Max(playerPosition.Y, mobPosition.Y); y++)
            {
                // formula for x is  x = ((y?y0)/m) + x0
                if (y != playerPosition.Y)
                {
                    int x = (int)((((float)y - playerPosition.Y) / slope) + playerPosition.X);
                    coords.Add(new Assistant.Point3D(x, y, Statics.GetLandZ(x, y, Player.Map)));
                }
            }

            //coords.Add(new Assistant.Point3D(playerPosition.X, playerPosition.Y, Statics.GetLandZ(playerPosition.X, playerPosition.Y, Player.Map)));

            return(coords);
        }
        private static bool Check(Map map, IEnumerable <Assistant.Item> items, int x, int y, int startTop, int startZ, bool ignoremob, out int newZ)
        {
            newZ = 0;

            var tiles        = map.Tiles.GetStaticTiles(x, y, true);
            var landTile     = map.Tiles.GetLandTile(x, y);
            var landData     = TileData.LandTable[landTile.ID & (TileData.LandTable.Length - 1)];
            var landBlocks   = (landData.Flags & TileFlag.Impassable) != 0;
            var considerLand = !landTile.Ignored();

            int landZ = 0, landCenter = 0, landTop = 0;

            GetAverageZ(map, x, y, ref landZ, ref landCenter, ref landTop);

            var moveIsOk = false;

            var stepTop  = startTop + StepHeight;
            var checkTop = startZ + PersonHeight;

            var ignoreDoors = false;

            if (Player.IsGhost || Engine.MainWindow.AutoOpenDoors.Checked)
            {
                ignoreDoors = true;
            }

            const bool ignoreSpellFields = true;

            int      itemZ, itemTop, ourZ, ourTop, testTop;
            ItemData itemData;
            TileFlag flags;

            // Check For mobiles
            if (!ignoremob)
            {
                var mobs = World.Mobiles.Values;
                List <Assistant.Mobile> result = new List <Assistant.Mobile>();
                foreach (Assistant.Mobile m in mobs)
                {
                    if (m.Position.X == x && m.Position.Y == y && m.Serial != Player.Serial)
                    {
                        result.Add(m);
                    }
                }
                if (result.Count > 0)                             // mob present at this spot.
                {
                    if (World.Player.Stam < World.Player.StamMax) // no max stam, avoid this location
                    {
                        return(false);
                    }
                }
            }
            // Check for deed player house
            if (Statics.CheckDeedHouse(x, y))
            {
                return(false);
            }

            #region Tiles
            foreach (var tile in tiles)
            {
                itemData = TileData.ItemTable[tile.ID & (TileData.ItemTable.Length - 1)];

                flags = itemData.Flags;

                if ((flags & ImpassableSurface) != TileFlag.Surface)
                {
                    continue;
                }

                itemZ   = tile.Z;
                itemTop = itemZ;
                ourZ    = itemZ + itemData.CalcHeight;
                ourTop  = ourZ + PersonHeight;
                testTop = checkTop;

                if (moveIsOk)
                {
                    var cmp = Math.Abs(ourZ - Player.Position.Z) - Math.Abs(newZ - Player.Position.Z); // TODO: Check this

                    if (cmp > 0 || (cmp == 0 && ourZ > newZ))
                    {
                        continue;
                    }
                }

                if (ourTop > testTop)
                {
                    testTop = ourTop;
                }

                if (!itemData.Bridge)
                {
                    itemTop += itemData.Height;
                }

                if (stepTop < itemTop)
                {
                    continue;
                }

                var 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))
                {
                    continue;
                }

                newZ     = ourZ;
                moveIsOk = true;
            }
            #endregion

            #region Items

            foreach (var item in items)
            {
                itemData = TileData.ItemTable[item.ItemID & (TileData.ItemTable.Length - 1)];
                flags    = itemData.Flags;

                if (item.Movable)
                {
                    continue;
                }

                if ((flags & ImpassableSurface) != TileFlag.Surface)
                {
                    continue;
                }

                itemZ   = item.Position.Z;
                itemTop = itemZ;
                ourZ    = itemZ + itemData.CalcHeight;
                ourTop  = ourZ + PersonHeight;
                testTop = checkTop;

                if (moveIsOk)
                {
                    var cmp = Math.Abs(ourZ - Player.Position.Z) - Math.Abs(newZ - Player.Position.Z);

                    if (cmp > 0 || (cmp == 0 && ourZ > newZ))
                    {
                        continue;
                    }
                }

                if (ourTop > testTop)
                {
                    testTop = ourTop;
                }

                if (!itemData.Bridge)
                {
                    itemTop += itemData.Height;
                }

                if (stepTop < itemTop)
                {
                    continue;
                }

                var 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))
                {
                    continue;
                }

                newZ     = ourZ;
                moveIsOk = true;
            }

            #endregion

            if (!considerLand || landBlocks || stepTop < landZ)
            {
                return(moveIsOk);
            }

            ourZ    = landCenter;
            ourTop  = ourZ + PersonHeight;
            testTop = checkTop;

            if (ourTop > testTop)
            {
                testTop = ourTop;
            }

            var shouldCheck = true;

            if (moveIsOk)
            {
                var cmp = Math.Abs(ourZ - Player.Position.Z) - Math.Abs(newZ - Player.Position.Z);

                if (cmp > 0 || (cmp == 0 && ourZ > newZ))
                {
                    shouldCheck = false;
                }
            }

            if (!shouldCheck || !IsOk(ignoreDoors, ignoreSpellFields, ourZ, testTop, tiles, items))
            {
                return(moveIsOk);
            }

            newZ = ourZ;
            return(true);
        }