/// <summary> /// Move the specified thing to container. /// </summary> /// <param name="thingToMove">Thing to move.</param> private void MoveItemToContainer() { int containerIndex = posTo.y - CONTAINER_HEADER; int itemIndex = posTo.z; Container container = player.GetContainerByIndex(containerIndex); Item containerItem = container.GetItemByIndex(itemIndex); bool addItem = true; if (containerItem != null && containerItem.IsOfType(Constants. TYPE_STACKABLE) && containerItem.ItemID == itemToMove.ItemID) { if (containerItem.Count + itemToMove.Count > MAX_STACK_COUNT) { byte countRemainder = (byte)(MAX_STACK_COUNT - containerItem.Count); containerItem.Count += countRemainder; itemToMove.Count -= countRemainder; } else { containerItem.Count += itemToMove.Count; addItem = false; } } if (containerItem != null && containerItem.IsOfType(Constants.TYPE_CONTAINER)) { List <Player> affected = containerItem.AddItem(itemToMove); } else { if (addItem) { container.AddItem(itemToMove); } else { container.UpdateContainerToViewers(); } } }
/// <summary> /// Gets the thing with the specified parameters or /// null if such a thing can't be found. Note: The thing /// must be visible for the player. /// </summary> /// <param name="player">The player for whom to get the item.</param> /// <param name="pos">The position of the item.</param> /// <param name="stackpos">The stackposition of the thing.</param> /// <param name="usePosZ">Use position.z for index instead of stackpos.</param> /// <returns>The thing or null if can't be found.</returns> public Thing GetThing(Player player, Position pos, byte stackpos, bool usePosZ) { //container/inventory if (CarryingPos(pos)) { if (ContainerPos(pos)) //From container { int containerIndex = pos.y - CONTAINER_HEADER; int itemIndex = usePosZ ? pos.z : stackpos; Container container = player.GetContainerByIndex(containerIndex); if (container == null) { return(null); } return(container.GetItemByIndex(itemIndex)); } else //inventory { return(player.GetInventoryItem((byte)pos.y)); } } else if (player.CanSee(pos)) //ground { if (stackpos == Constants.STACKPOS_TOP_ITEM) { return(map.GetTopThing(pos)); } else { Tile tile = map.GetTile(pos); if (tile == null) { return(null); } return(tile.GetThing(stackpos)); } } return(null); }
/// <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); }