/// <summary> /// Register a new item /// </summary> /// <param name="guid"></param> /// <param name="val"></param> public static void Register(System.Guid guid, IItemInstance val) { if (val != null) { _dict[guid] = val; OnAddedItem?.Invoke(guid, val); } }
/// <summary> /// /// </summary> /// <param name="xml"></param> /// <returns></returns> public bool Load(XmlNode xml) { if (xml == null) { return(false); } Decoration = int.Parse(xml.Attributes["deco"].Value); HideItems = bool.Parse(xml.Attributes["hide"].Value); AcceptBigItems = bool.Parse(xml.Attributes["bigitems"].Value); //ItemLocation = new Point(int.Parse(xml.Attributes["x"].Value), // int.Parse(xml.Attributes["y"].Value)); foreach (XmlNode node in xml) { switch (node.Name.ToLower()) { case "onaddeditem": { foreach (XmlNode sub in node) { AlcoveScript script = new AlcoveScript(); script.Load(sub); OnAddedItem.Add(script); } } break; case "onremoveditem": { foreach (XmlNode sub in node) { AlcoveScript script = new AlcoveScript(); script.Load(sub); OnRemovedItem.Add(script); } } break; default: { } break; } } return(true); }
public virtual Result <bool> Set(int index, TElementType item, int amount, CollectionContext context) { var canSet = CanSet(index, item, amount, context); if (canSet.result == false) { return(canSet); } // Slot is empty and item is empty, ignore call if (slots[index].isOccupied == false && IsNull(item)) { return(true); } if (AreEqual(slots[index].item, item) && GetAmount(index) == amount) { // Still set for *SpecificInstance SetInternal(index, item, amount, context); return(true); } var currentAmount = GetAmount(index); if (AreEqual(slots[index].item, item)) { SetInternal(index, item, amount, context); var diff = Math.Abs(amount - currentAmount); if (amount < currentAmount) { if (context.HasFlag(CollectionContext.Events.Remove)) { OnRemovedItem?.Invoke(this, new CollectionRemoveResult(new SlotAmount[] { new SlotAmount(index, diff) })); } } else if (amount > currentAmount) { if (context.HasFlag(CollectionContext.Events.Add)) { OnAddedItem?.Invoke(this, new CollectionAddResult(new SlotAmount[] { new SlotAmount(index, diff) })); } } } else { if (IsNull(item)) { SetInternal(index, item, 0, context); if (context.HasFlag(CollectionContext.Events.Remove)) { OnRemovedItem?.Invoke(this, new CollectionRemoveResult(new [] { new SlotAmount(index, currentAmount) })); } } else { if (IsNull(slots[index].item) == false) { SetInternal(index, default(TElementType), 0, context); if (context.HasFlag(CollectionContext.Events.Remove)) { OnRemovedItem?.Invoke(this, new CollectionRemoveResult(new [] { new SlotAmount(index, currentAmount) })); } } // Add the item SetInternal(index, item, amount, context); if (context.HasFlag(CollectionContext.Events.Add)) { OnAddedItem?.Invoke(this, new CollectionAddResult(new [] { new SlotAmount(index, amount) })); } } } if (context.HasFlag(CollectionContext.Events.SlotChanged)) { OnSlotsChanged?.Invoke(this, new CollectionSlotsChangedResult(new int[] { index })); } return(true); }
public virtual Result <CollectionAddResult> Add(TElementType item, int amount, CollectionContext context) { var canAdd = CanAdd(item, amount, context); if (canAdd.result == false) { return(new Result <CollectionAddResult>(null, canAdd.error)); } var totalAddAmount = amount; var affectedSlots = new List <SlotAmount>(); // Can Add already checks all restrictions and requirements. var contextClone = context.Clone(); contextClone.validationFlags &= ~CollectionContext.Validations.Restrictions; contextClone.validationFlags &= ~CollectionContext.Validations.SpecificInstance; // We'll handle events ourselves and bundle them contextClone.fireEventFlags = 0; var enumerator = GetAddItemEnumerator(item, amount, contextClone); while (enumerator.MoveNext()) { var index = enumerator.Current; // Slot is occupied by other slot. if (slots[index].isOccupied && IsNull(slots[index].item)) { continue; } var isEmptySlot = this[index] == null; var canAddToStackAmount = Math.Min(item.maxStackSize - GetAmount(index), totalAddAmount); totalAddAmount -= canAddToStackAmount; affectedSlots.Add(new SlotAmount(index, canAddToStackAmount)); if (totalAddAmount > 0) { // Need to do another stack placement after this one. if (isEmptySlot) { // Empty slot, so set the reference (and make a clone later if we need to place more). SetInternal(index, item, GetAmount(index) + canAddToStackAmount, contextClone); } else { // If we're adding to an existing stack and still have to place more keep the existing item in the slot and just increase the amount. SetInternal(index, this[index], GetAmount(index) + canAddToStackAmount, contextClone); } } else { // We don't want to place any more after this iteration. SetInternal(index, item, GetAmount(index) + canAddToStackAmount, contextClone); } if (totalAddAmount <= 0) { break; } if (isEmptySlot) { item = CreateElementClone(item); // The next item we're placing needs to be a new instance. } } logger.LogVerbose($"Added {item} x {amount} to collection", this); var response = new Result <CollectionAddResult>(new CollectionAddResult(affectedSlots.ToArray())); if (context.HasFlag(CollectionContext.Events.Add)) { OnAddedItem?.Invoke(this, response.result); } if (context.HasFlag(CollectionContext.Events.SlotChanged)) { OnSlotsChanged?.Invoke(this, new CollectionSlotsChangedResult(response.result.affectedSlots.Select(o => o.slot).ToArray())); } return(response); }
/// <summary> /// Add new value to registry /// </summary> /// <param name="identifier"></param> /// <param name="val"></param> public void Register(TKey identifier, TValue val) { _dict[identifier] = val; OnAddedItem?.Invoke(identifier, val); }
protected void InvokeOnAddedItem(CollectionAddResult addResult) { OnAddedItem?.Invoke(this, addResult); }