/// <summary> /// tries to add an item to the character's inventory /// </summary> /// <param name="character"></param> /// <param name="item"></param> /// <returns>true on success</returns> public bool AddItem(int character, int item) { var inventory = EntityManager.GetComponent <InventoryComponent>(character); if (inventory == null) { Log.Warning("Character does not have an inventory! -> " + DescriptionSystem.GetNameWithID(character)); return(false); } var itemInfo = EntityManager.GetComponent <ItemComponent>(item); if (itemInfo == null) { Log.Error("Trying to add item entity to character that's not an item!"); Log.Data(DescriptionSystem.GetDescription(item)); return(false); } if (itemInfo.Count == 0) // happens if item comes back from e.g. crafting reset { itemInfo.Count = 1; } // "Re-Stacking" - item gets handed back from e.g. crafting reset if (inventory.Items.Contains(item)) { itemInfo.Count++; return(true); } #region ItemStacking IEnumerable <IComponent> newItem = EntityManager.GetComponents(item); foreach (var inventoryItemID in inventory.Items) { var inventoryItem = EntityManager.GetComponents(inventoryItemID); bool itemMatch = true; foreach (var newItemComponent in newItem) { bool componentMatch = false; if (newItemComponent.TypeID == Component <TransformComponent> .TypeID) { continue; } foreach (var inventoryItemComponent in inventoryItem) { if (newItemComponent.Equals(inventoryItemComponent)) { componentMatch = true; break; } } if (!componentMatch) { itemMatch = false; break; } } if (itemMatch == true) { var invItemInfo = EntityManager.GetComponent <ItemComponent>(inventoryItemID); int newCount = invItemInfo.Count + itemInfo.Count; invItemInfo.Count = Math.Min(newCount, invItemInfo.MaxCount); int itemsLeft = Math.Max(0, newCount - invItemInfo.MaxCount); // TODO: implement overflow if (itemsLeft > 0) { UISystem.Message(String.Format("{0} x{1} was lost in the void...", DescriptionSystem.GetName(item), itemsLeft)); } EntityManager.RemoveEntity(item); return(true); } } // at this point, no matching item was found if (inventory.Full) { UISystem.Message("Inventory is full! -> " + DescriptionSystem.GetNameWithID(character)); return(false); } inventory.Items.Add(item); return(true); #endregion /* * var pickupComponentTypeIDs = EntityManager.GetComponentTypeIDs(item); * * bool match = false; // can item can be stacked here * * // start looking through every item in inventory * // to find out if picked up item can be stacked * foreach (var invItemID in inventory.Items) * { * var invItemInfo = EntityManager.GetComponent<ItemComponent>(invItemID); * * // if already stacked to max, jump straight to next * if (invItemInfo.Count == invItemInfo.MaxCount) * { * match = false; * continue; * } * * var invItemComponentIDs = EntityManager.GetComponentTypeIDs(invItemID); * * // check if both items have the exact same components attached * match = invItemComponentIDs.All(pickupComponentTypeIDs.Contains) && invItemComponentIDs.Count() == pickupComponentTypeIDs.Count(); * * if (match) * { * var pickedUpItemInfo = EntityManager.GetComponent<ItemComponent>(item); * * // cumulative count doesnt exceed max -> just increase count * // in inventory and remove picked up item * if (invItemInfo.Count + pickedUpItemInfo.Count <= invItemInfo.MaxCount) * { * invItemInfo.Count += pickedUpItemInfo.Count; * EntityManager.RemoveEntity(item); * } * * // cumulative count exceeds max -> * // stack up to max, rest becomes new stack * else * { * pickedUpItemInfo.Count -= invItemInfo.MaxCount - invItemInfo.Count; // remove difference used to max out inventory item * invItemInfo.Count = invItemInfo.MaxCount; * inventory.Items.Add(item); * } * break; * } * } */ //if (!match) //{ //} }
/// <summary> /// checks if moving onto newPos is possible /// and triggers any interaction otherwise /// </summary> /// <param name="entity">ID of entity to move</param> /// <param name="newPos">new Position to move to</param> /// <returns>wether movement is possible</returns> private bool TryMove(int entity, Position newPos) { var floor = Util.CurrentFloor; if (floor.IsOutOfBounds(newPos)) { return(false); } int otherCharacter = floor.GetCharacter(newPos); //check if someone's already there if (otherCharacter != 0 && otherCharacter != entity) { // check if collidable if (EntityManager.GetComponent <ColliderComponent>(otherCharacter) != null) { //TODO: talk to npcs? RaiseBasicAttackEvent(entity, otherCharacter); return(false); } else { Log.Warning("Character without collider:"); Log.Data(DescriptionSystem.GetDebugInfoEntity(otherCharacter)); UISystem.Message("Something seems to be there..."); return(false); } } int structure = floor.GetStructure(newPos); if (structure != 0 && EntityManager.GetComponent <ColliderComponent>(structure) != null) { bool solid = RaiseCollisionEvent(entity, structure); // check if interactable var interactable = EntityManager.GetComponent <InteractableComponent>(structure); // only interact with structures right away if they're solid ("bumping" into them) if (solid) { if (interactable != null) { RaiseInteractionEvent(entity, structure); } return(false); } } int terrain = floor.GetTerrain(newPos); // check if collidable with if (terrain != 0 && EntityManager.GetComponent <ColliderComponent>(terrain) != null) { // check if terrain is solid before possible interaction // this is because solidity might be changed by interaction (e.g. door gets opened) bool solid = RaiseCollisionEvent(entity, terrain); // check if interactable var interactable = EntityManager.GetComponent <InteractableComponent>(terrain); if (interactable != null) { RaiseInteractionEvent(entity, terrain); } // check if terrain is solid if (solid) { return(false); } } //trigger special Message on step on if (entity == Util.PlayerID && terrain != 0) { string message = (DescriptionSystem.GetSpecialMessage(terrain, DescriptionComponent.MessageType.StepOn)); if (message.Length > 0) { UISystem.Message(message); } } return(true); }