public static bool DrawItemChangeInfo(ItemChangeInfo info) { if (info.item != null) { int max = info.item.maxAmount; if (max == -1) { info.amountToAdd = EditorGUILayout.IntField("Amount to add ", info.amountToAdd); } else { info.amountToAdd = EditorGUILayout.IntSlider(info.amountToAdd, -info.item.maxAmount, info.item.maxAmount); } info.newDescription = EditorGUILayout.TextField("New Description", info.newDescription); info.historyString = EditorGUILayout.TextField("History String", info.historyString); } if (GUILayout.Button("X")) { return(true); } else { return(false); } }
/// <summary> /// 修改道具数量 /// </summary> /// <param name="uid"></param> /// <param name="count"></param> public void ChangeStackCount(ulong uid, long count) { if (m_Items.TryGetValue(uid, out ItemContainer item)) { long oldCount = item.Count; item.Count = count; if (item.MainType == Category.Currency) { SendNotification(NotificationName.MSG_CURRENCY_CHANGED); } if (oldCount != count) { ItemChangeInfo info = new ItemChangeInfo() { Category = item.MainType, UID = item.UID, TID = item.TID, ItemPos = item.Position, ParentUID = item.ParentUID, ChangeType = ItemChangeInfo.Type.CountChange, CountChangeDelta = count - oldCount }; SendNotification(NotificationName.MSG_PACKAGE_ITEM_CHANGE, info); } } }
/// <summary> /// Swaps items between two containers and preserves the item indicies. /// </summary> /// <returns>True on success, false otherwise</returns> public static bool InterManagerSwapPreserveIndex( IItemContainer containerA, int idxA, IItemContainer containerB, int idxB) { // validate indicies if (IsNotInRange(idxA, containerA.Provider.Count)) { return(false); } if (IsNotInRange(idxB, containerB.Provider.Count)) { return(false); } // get items var itemA = containerA.Provider[idxA]; var itemB = containerB.Provider[idxB]; // check ids if (itemA.Id == itemB.Id) { // calc stacking A into B long uncheckedOverflow = itemB.Amount + itemA.Amount; var overflow = itemB.Id.GetOverflow(uncheckedOverflow); if (!SafeDoubleInfoExecute( // stack A into B containerB, new ItemChangeInfo(idxB, new ItemStack(itemB.Id, Convert.ToInt32(uncheckedOverflow - overflow)), 0), // leave overflow for A containerA, new ItemChangeInfo(idxA, new ItemStack(itemA.Id, Convert.ToInt32(overflow)), 0))) { return(false); } } else { // remove A and B if (!SafeDoubleInfoExecute( containerA, ItemChangeInfo.Remove(idxA), containerB, ItemChangeInfo.Remove(idxB))) { return(false); } // exec swap if (!SafeDoubleInfoExecute( containerA, new ItemChangeInfo(idxA, itemB, 0), containerB, new ItemChangeInfo(idxB, itemA, 0))) { // reverse removal GuaranteedExecuteInfo(containerA, new ItemChangeInfo(idxA, itemA, 0)); GuaranteedExecuteInfo(containerB, new ItemChangeInfo(idxB, itemB, 0)); } } return(true); }
public void ClearInv(CommandContext ctx) { var inv = ctx.Callee.Parent.AssertGetInventory(); for (var i = 0; i < inv.Inventory.Provider.Count; i++) { inv.Inventory.ExecuteChangeInfo(ItemChangeInfo.Remove(i)); } }
/* * public static bool RemoveFromA_AddToB( * IItemContainer containerA, int idxA, * IItemContainer containerB) * { * // verify idxA * if (IsNotInRange(idxA, containerA.Size)) return false; * var id = containerA.Provider.GetId(idxA); * * // calc changes * var remFromA = ItemChangeInfo.Remove(idxA); * var addToB = containerB.CalcChangeInfo(id, * containerA.Provider.GetAmount(idxA)); * * // verify add to b * if (!addToB.IsValid && addToB.OverflowAmount != 0) return false; * * // execute * if (!SafeDoubleInfoExecute( * containerA, remFromA, * containerB, addToB)) return false; * * return true; * } */ // TODO : write tests for InterManagerSwap /// <summary> /// Swaps items between two containers without preserving the item indicies. /// </summary> /// <returns>True on success, false otherwise</returns> public static bool InterManagerSwap( IItemContainer containerA, int idxA, IItemContainer containerB, int idxB) { // if idxB is null, find either an item idx with the same id or an empty slot. // validate indicies if (IsNotInRange(idxA, containerA.Provider.Count)) { return(false); } if (IsNotInRange(idxB, containerB.Provider.Count)) { return(false); } // get items var itemA = containerA.Provider[idxA]; var itemB = containerB.Provider[idxB]; // calc change info // add A to containerB var cAtoB = containerB.CalcChangeInfo(itemA); // add B to containerA var cBtoA = containerA.CalcChangeInfo(itemB); // operation is undefinied if any changeInfo's are invalid or have overflow, return false bool IsInvalidChangeInfo(ref ItemChangeInfo info) => !info.IsValid || info.OverflowAmount != 0; if (IsInvalidChangeInfo(ref cAtoB)) { return(false); } if (IsInvalidChangeInfo(ref cBtoA)) { return(false); } // managed remove A and B if (!SafeDoubleInfoExecute( containerA, ItemChangeInfo.Remove(idxA), containerB, ItemChangeInfo.Remove(idxB))) { return(false); } // execute change infos we calculated earlier if (!SafeDoubleInfoExecute( containerA, cBtoA, containerB, cAtoB)) { return(false); } return(true); }
private static void GuaranteedExecuteInfo( IItemContainer container, ItemChangeInfo info) { // make sure we're in range. if (0 > info.Index || info.Index >= container.Provider.Count) { return; } // try managed if (!container.ExecuteChangeInfo(info)) { // it failed, force it container.Provider[info.Index] = info.NewItem; } }
/// <summary> /// 添加条目 /// </summary> /// <param name="itemGetting">条目数据</param> private void OnGettingItem(ItemChangeInfo itemGetting) { if (itemGetting.CountChangeDelta > 0 && itemGetting.TID > 0) { if (itemGetting.Category != 0 && itemGetting.Category != Category.Package) { ItemData data = new ItemData(); data.Name = TableUtil.GetItemName(itemGetting.TID); data.Quality = TableUtil.GetItemQuality(itemGetting.TID); data.Count = itemGetting.CountChangeDelta; data.IconBundle = TableUtil.GetItemIconBundle(itemGetting.TID); data.IconName = TableUtil.GetItemSquareIconImage(itemGetting.TID); m_WaitingQueue.Add(data); } } }
public bool ExecuteChangeInfo(ItemChangeInfo info) { if (!info.IsValid) { return(false); } if (info.Index < 0 || info.Index >= Provider.Count) { return(false); } Provider[info.Index] = info.NewItem; Parent.SendMessage(ItemChangeMessage.InventoryChange(this, info)); return(true); }
public static IEntityHandle PlayerDropItem(this IItemContainer container, int itemIndex, [NotNull] IPlayerComponent player) { if (player == null) { throw new ArgumentNullException(nameof(player)); } var item = container.GetItem(itemIndex); if (item == null) { return(null); } var itemFactory = (IGroundItemFactory)player.Parent.Server.Services.GetService(typeof(IGroundItemFactory)); if (itemFactory == null) { return(null); } var itemEntityHandle = itemFactory.CreatePlayerDrop(item, player, $"Dropped item {item.Id.Name}x{item.Amount}"); if (itemEntityHandle.IsDead()) { return(null); } var itemEntity = itemEntityHandle.Get(); var itemTransform = itemEntity.GetTransform(); var playerTransform = player.Parent.GetTransform(); itemTransform.SwitchPoE(playerTransform.PoE); itemTransform.Teleport(playerTransform); container.ExecuteChangeInfo(ItemChangeInfo.Remove(itemIndex)); return(itemEntityHandle); }
/// <summary> /// 添加道具 /// </summary> /// <param name="holdInit"></param> /// <param name="uid"></param> /// <param name="tid"></param> /// <param name="parentUid"></param> /// <param name="pos"></param> /// <param name="count"></param> /// <param name="capacity"></param> public Category AddItem(bool holdInit, ulong uid, uint tid, ulong parentUid, int pos, long count, uint capacity, ulong reference, ulong createTime) { ItemContainer item = CreateItem(uid, tid, parentUid, pos, count, capacity, reference, createTime); m_Items.Add(uid, item); if (m_PlayerItem == null && item.MainType == Category.Player) { m_PlayerItem = item; return(Category.Player); } else if (m_HeroItem == null && item.MainType == Category.Hero) { m_HeroItem = item; return(Category.Hero); } else if (m_SpaceStation == null && item.MainType == Category.WarehousePackage) { m_SpaceStation = item; } if (!holdInit) { LinkData(uid, parentUid); } if (item.MainType != Category.Skill) { ItemChangeInfo info = new ItemChangeInfo(); info.ChangeType = ItemChangeInfo.Type.Add; info.Category = item.MainType; info.UID = uid; info.TID = item.TID; info.ParentUID = parentUid; info.ItemPos = pos; info.CountChangeDelta = count; SendNotification(NotificationName.MSG_PACKAGE_ITEM_CHANGE, info); } return(item.MainType); }
/// <summary> /// Executes two ItemChangeInfo's in such a way that change will only occur if the two of them are successful. /// </summary> /// <returns>True if both infos were executed succesfully, false otherwise.</returns> private static bool SafeDoubleInfoExecute( IItemContainer managerA, ItemChangeInfo infoA, IItemContainer managerB, ItemChangeInfo infoB) { // cache state of A. var idx = infoA.Index; var cacheA = new ItemChangeInfo(idx, managerA.Provider[idx], 0); // execute if (!managerA.ExecuteChangeInfo(infoA)) { return(false); } if (!managerB.ExecuteChangeInfo(infoB)) { // A succeeded, B didn't. Revert changes to A. GuaranteedExecuteInfo(managerA, cacheA); return(false); } return(true); }
/// <summary> /// 删除道具 /// </summary> /// <param name="uid"></param> public void RemoveItem(ulong uid) { if (m_Items.TryGetValue(uid, out ItemContainer item)) { ItemChangeInfo info = new ItemChangeInfo(); info.ChangeType = ItemChangeInfo.Type.Del; info.Category = item.MainType; info.UID = uid; info.ParentUID = item.ParentUID; info.ItemPos = item.Position; info.TID = item.TID; if (item.Reference != 0 && m_Items.TryGetValue(item.Reference, out ItemContainer original)) { original.Replicas.Remove(uid); } DeLinkData(uid); m_Items.Remove(uid); if (item.MainType != Category.Skill) { SendNotification(NotificationName.MSG_PACKAGE_ITEM_CHANGE, info); } } }
private ItemChangeMessage([NotNull] IItemContainer container, ItemChangeInfo info, MessageId id) { Container = container ?? throw new ArgumentNullException(nameof(container)); Info = info; EventId = (int)id; }
int toInt(ItemChangeInfo pItemChangeInfo) { var lBitData = new zz.IntBitIO(); lBitData.write(pItemChangeInfo.count, 14); lBitData.write(pItemChangeInfo.itemId, 14); lBitData.write(pItemChangeInfo.index, 4); return lBitData.date; }
public ItemChangeInfo CalcChangeInfo(ItemStack delta) { if (delta.IsEmpty()) { return(ItemChangeInfo.Invalid); } // figure out whether an item of the same id exists in provider. // if we find an empty slot during this, store it just in case we don't find an existing item. var(nullExistingIdx, emptySlotIdx) = this.GetExistingOrEmptyIdx(delta.Id.ItemId); // we've either found an existing item idx OR have an empty slot id OR have neither of those. // no existing item found, must operation will result in an new item. if (nullExistingIdx == null) { // because we need to add a new item, inputs that result in a remove operation cannot proceed. // filter out remove operations if (delta.Amount <= 0) { return(ItemChangeInfo.Invalid); } // check if we found an empty slot during our iteration. if (emptySlotIdx != null) { // we did, generate a new item var overflow = delta.Id.GetOverflow(delta.Amount); return(new ItemChangeInfo( emptySlotIdx.Value, new ItemStack(delta.Id, (int)(delta.Amount - overflow)), overflow)); } else // we found no empty slots. in this case, it means that the container is full. { return(ItemChangeInfo.Invalid); } } else // we found an item with the same id. { // attempt to add the given amount of the item to this slot. var existingItem = Provider[nullExistingIdx.Value]; var finalNewAmount = existingItem.Amount + delta.Amount; var overflow = delta.Id.GetOverflow(finalNewAmount); // no carry remove item if (finalNewAmount == 0) { return(ItemChangeInfo.Remove(nullExistingIdx.Value)); } // remove with carry if (finalNewAmount < 0) { return(new ItemChangeInfo( nullExistingIdx.Value, ItemStack.Empty, overflow)); } // add with carry if (finalNewAmount > 0) { return(new ItemChangeInfo( nullExistingIdx.Value, new ItemStack(existingItem.Id, (int)(finalNewAmount - overflow)), overflow)); } // crap return(ItemChangeInfo.Invalid); } }
public static ItemChangeMessage EquipmentChange([NotNull] IItemContainer container, ItemChangeInfo info) => new ItemChangeMessage(container, info, MessageId.EquipmentChange);
public static ItemChangeMessage InventoryChange([NotNull] IItemContainer container, ItemChangeInfo info) => new ItemChangeMessage(container, info, MessageId.ItemChange);
private void HandleItemChange(ItemChangeInfo info) { _dirtyBuffer.Add(info.Index); }
public void ItemBagChange(ItemChangeInfo[] pItemChangeInfo) { if (Network.isClient) { switch (pItemChangeInfo.Length) { case 1: networkView.RPC("ItemBagChange", RPCMode.Server, toInt(pItemChangeInfo[0])); break; case 2: networkView.RPC("ItemBagChange2", RPCMode.Server, toInt(pItemChangeInfo[0]), toInt(pItemChangeInfo[1])); break; case 3: networkView.RPC("ItemBagChange3", RPCMode.Server, toInt(pItemChangeInfo[0]), toInt(pItemChangeInfo[1]), toInt(pItemChangeInfo[2])); break; case 4: networkView.RPC("ItemBagChange4", RPCMode.Server, toInt(pItemChangeInfo[0]), toInt(pItemChangeInfo[1]), toInt(pItemChangeInfo[2]), toInt(pItemChangeInfo[3])); break; case 5: networkView.RPC("ItemBagChange5", RPCMode.Server, toInt(pItemChangeInfo[0]), toInt(pItemChangeInfo[1]), toInt(pItemChangeInfo[2]), toInt(pItemChangeInfo[3]), toInt(pItemChangeInfo[4])); break; default: Debug.LogError("error pItemChangeInfo.Length:" + pItemChangeInfo.Length); break; } } else { foreach (var lInfo in pItemChangeInfo) { ItemBagChange(lInfo.index, lInfo.itemId, lInfo.count); } } }