示例#1
0
        //TODO: Completely rework this method... it currently sucks
        //A LOT... i mean it!
        public void CheckForRespawn()
        {
            Position pos     = new Position(CenterX, CenterY, CenterZ);
            Monster  monster = Monster.CreateMonster(MonsterName);

            if (monster != null && world.GetGameMap().GetTile(pos) != null)
            {
                world.AppendAddMonster(monster, pos);
            }
            return;

            Map      map  = world.GetGameMap();
            ThingSet tSet = map.GetThingsInVicinity(pos);

            //Monster monster = Monster.CreateMonster(MonsterName);
            if (monster == null)
            {
                return;
            }

            if (map.GetTile(pos) != null &&
                !map.TileContainsType(pos, Constants.TYPE_BLOCKS_AUTO_WALK))
            {
                bool canRespawn = true;
                foreach (Thing thing in tSet.GetThings())
                {
                    if (thing is Player)       //TODO: FIX this crap
                    {
                        canRespawn = false;
                    }
                }
                if (canRespawn)
                {
                    world.SendAddMonster(monster, pos);
                }
            }
            else
            {
                return;
            }

            //  if (map.GetTile(pos) != null &&
            // !map.TileContainsType(pos, Constants.TYPE_BLOCKS_AUTO_WALK)) {
            // Console.WriteLine("x: " + x++);
            //world.SendAddMonster(monster, pos);
            // }

            world.AddEventInCS(SpawnTime, CheckForRespawn);
        }
示例#2
0
        public bool GetPathTo(Creature creature, Position destPos,
                              List <byte> listDir, Int32 maxSearchDist, bool allowZChange, bool intendingToReachDes)
        {
            if (intendingToReachDes &&
                gameMap.TileContainsType(destPos, Constants.TYPE_BLOCKS_AUTO_WALK))
            {
                listDir.Clear();
                return(false);
            }

            listDir.Clear();

            Position startPos = creature.CurrentPosition;
            Position endPos   = destPos;

            if (endPos == null)
            {
                return(false);
            }

            if (startPos.z != endPos.z)
            {
                return(false);
            }

            AStarNodes nodes     = new AStarNodes();
            AStarNode  startNode = nodes.CreateOpenNode();

            startNode.x = startPos.x;
            startNode.y = startPos.y;

            startNode.g = 0;
            startNode.h = nodes.GetEstimatedDistance
                              (startPos.x, startPos.y, endPos.x, endPos.y);

            startNode.f      = startNode.g + startNode.h;
            startNode.parent = null;

            Position pos = new Position();

            pos.z = startPos.z;

            short[,] neighbourOrderList =
            {
                { -1,  0 },
                {  0,  1 },
                {  1,  0 },
                {  0, -1 },

                //diagonal
                { -1, -1 },
                {  1, -1 },
                {  1,  1 },
                { -1,  1 },
            };

            //MapTile tile = null;
            AStarNode found = null;

            while (nodes.CountClosedNodes() < 100)
            {
                AStarNode n = nodes.GetBestNode();
                if (n == null)
                {
                    listDir.Clear();
                    return(false); //No path found
                }

                if (n.x == endPos.x && n.y == endPos.y)
                {
                    found = n;
                    break;
                }
                else
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if (i > 3 && (allowZChange || intendingToReachDes))
                        {
                            continue;
                        }
                        //Console.WriteLine("neighbourhood["+i+", 1]" + neighbourOrderList[i, 0]);
                        pos.x = (ushort)(n.x + neighbourOrderList[i, 0]);
                        pos.y = (ushort)(n.y + neighbourOrderList[i, 1]);
                        int endPosX = endPos.x;
                        int endPosY = endPos.y;
                        int posX    = pos.x;
                        int posY    = pos.y;


                        bool outOfRange = false;
                        if (Math.Abs(endPosX - posX) > maxSearchDist ||
                            Math.Abs(endPosY - posY) > maxSearchDist)
                        {
                            outOfRange = true;
                        }

                        if ((!outOfRange) &&
                            (!gameMap.TileContainsType(pos, Constants.TYPE_BLOCKS_AUTO_WALK)) ||
                            (destPos.x == pos.x && destPos.y == pos.y))
                        {
                            if (i > 3 && !destPos.Equals(pos))
                            {
                                nodes.CloseNode(n);
                                continue;
                            }

                            int cost      = 0;
                            int extraCost = 0;
                            int newg      = n.g + cost + extraCost;

                            AStarNode neighbourNode = nodes.GetNodeInList(pos.x, pos.y);
                            if (neighbourNode != null)
                            {
                                if (neighbourNode.g <= newg)
                                {
                                    continue;
                                }
                                nodes.OpenNode(neighbourNode);
                            }
                            else
                            {
                                neighbourNode = nodes.CreateOpenNode();
                                if (neighbourNode == null)
                                {
                                    listDir.Clear();
                                    return(false);
                                }
                            }

                            neighbourNode.x      = pos.x;
                            neighbourNode.y      = pos.y;
                            neighbourNode.parent = n;
                            neighbourNode.g      = newg;
                            neighbourNode.h      = (nodes.GetEstimatedDistance((int)neighbourNode.x,
                                                                               (int)neighbourNode.y, (int)endPos.x, (int)endPos.y));
                            neighbourNode.f = neighbourNode.g + neighbourNode.h;
                        }
                    }
                    nodes.CloseNode(n);
                }
            }

            int prevX = endPos.x;
            int prevY = endPos.y;
            int dx, dy;

            while (found != null)
            {
                pos.x = (ushort)found.x;
                pos.y = (ushort)found.y;


                found = found.parent;

                dx = pos.x - prevX;
                dy = pos.y - prevY;

                prevX = pos.x;
                prevY = pos.y;

                if (dx == 1)
                {
                    listDir.Insert(0, (byte)Direction.WEST);
                }
                else if (dx == -1)
                {
                    listDir.Insert(0, (byte)Direction.EAST);
                }
                else if (dy == 1)
                {
                    listDir.Insert(0, (byte)Direction.NORTH);
                }
                else if (dy == -1)
                {
                    listDir.Insert(0, (byte)Direction.SOUTH);
                }
            }


            bool empty = true;

            if (listDir.Count == 0)
            {
                empty = false;
            }

            return(!empty);
        }
示例#3
0
        /// <summary>
        /// Gets whether a given move is valid. Note:
        /// this method attemps to make a move valid such as a stackable being
        /// moved to inventory.
        /// </summary>
        /// <returns>True if the move is valid, false otherwise.</returns>
        private bool IsItemMoveValid()
        {
            /* This Method is a bit of a mess and hence is probably very
             * prone to bugs if not careful. However, I'm being extra careful
             * to ensure proper validation to avoid item dupe bugs. */
            if (!itemToMove.IsOfType(Constants.TYPE_MOVEABLE) ||
                itemToMove.Count < count)
            {
                return(false);
            }

            double weightToSubtract = 0;

            if (ContainerPos(posFrom))   //From container
            {
            }
            else if (InventoryPos(posFrom))     //From inventory
            {
                weightToSubtract += itemToMove.GetWeight();
            }
            else     //From ground
            {
                Tile tile = map.GetTile(posFrom);
                if (tile == null)
                {
                    return(false);
                }

                if (!player.IsNextTo(posFrom))
                {
                    player.CurrentWalkSettings.Destination         = posFrom;
                    player.CurrentWalkSettings.IntendingToReachDes = false;
                    player.CurrentDelayedAction = new MoveItemDelayed
                                                      (player, posFrom, thingID, stackpos, posTo, count);
                    return(false);
                }
            }


            if (ContainerPos(posTo))   //To container
            {
                int       containerIndex = posTo.y - CONTAINER_HEADER;
                Container container      = player.GetContainerByIndex(containerIndex);
                if (container == null)
                {
                    return(false);
                }

                if (player.HasSpecificThing(container) &&
                    itemToMove.GetWeight() > player.GetCurrentCap())
                {
                    SendErrorMessage(MSG_NOT_ENOUGH_CAP);
                    return(false);
                }

                if (itemToMove == container || container.HasAnyParent(itemToMove))
                {
                    SendErrorMessage(MSG_THIS_IS_IMPOSSIBLE);
                    return(false);
                }
                Item item = container.GetItemByIndex(posTo.z);
                if (item != null && item.IsOfType(Constants.TYPE_CONTAINER))
                {
                    if (!item.HasRoom())
                    {
                        SendErrorMessage(MSG_NOT_ENOUGH_ROOM);
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                }

                if (!container.HasRoom())
                {
                    SendErrorMessage(MSG_NOT_ENOUGH_ROOM);
                    return(false);
                }
            }
            else if (InventoryPos(posTo))     //To inventory
            {
                byte toIndex = (byte)posTo.y;

                if (itemToMove.GetWeight() - weightToSubtract > player.GetCurrentCap())
                {
                    SendErrorMessage(MSG_NOT_ENOUGH_CAP);
                    return(false);
                }

                if (player.GetInventoryItem(toIndex) != null)
                {
                    Item invItem = player.GetInventoryItem(toIndex);
                    if (invItem.ItemID == itemToMove.ItemID)
                    {
                        if (invItem.Count + itemToMove.Count > MAX_STACK_COUNT)
                        {
                            count = (byte)(MAX_STACK_COUNT - invItem.Count);
                        }
                    }
                    if (invItem.IsOfType(Constants.TYPE_CONTAINER))
                    {
                        if (!invItem.HasRoom())
                        {
                            SendErrorMessage(MSG_NOT_ENOUGH_ROOM);
                            return(false);
                        }
                        else
                        {
                            return(true);
                        }
                    }
                    if (InventoryPos(posFrom))
                    {
                        return(false);
                    }
                }

                if (!IsToInventoryValid(toIndex, itemToMove))
                {
                    return(false);
                }
            }
            else     //Moving to ground
            {
                if (!player.CanSee(posTo))
                {
                    return(false);
                }
                return(!map.TileContainsType(posTo, Constants.TYPE_BLOCKS_ITEM));
            }
            return(true);
        }