//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); }
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); }
/// <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); }