Exemplo n.º 1
0
        public void ThrowItem(int character, int item, Position pos)
        {
            //UISystem.Message(DescriptionSystem.GetNameWithID(character) + " throws " + DescriptionSystem.GetNameWithID(item) + " at " + pos);
            UISystem.Message(DescriptionSystem.GetName(character) + " throws " + DescriptionSystem.GetName(item));

            if (Util.CurrentFloor.IsTileBlocked(pos))
            {
                UISystem.Message("You can't throw that there!");
                return;
            }

            int targetCharacter = Util.CurrentFloor.GetCharacter(pos);

            if (targetCharacter == 0)
            {
                Util.CurrentFloor.PlaceItem(pos, item);
            }
            else
            {
                UISystem.Message("It hits " + DescriptionSystem.GetName(targetCharacter) + "!");

                // TODO: actually calulate the modifier for effects of thrown items
                float modifier = 0.5f;

                ApplySubstance(targetCharacter, item, modifier);

                IdentifyItem(item);
                DecreaseItemCount(character, item);
                TryDeleteItem(item);
            }

            Util.TurnOver(character);
        }
Exemplo n.º 2
0
        void ResolveProperty(Property prop, int value, int target)
        {
            switch (prop)
            {
            // --- Resource --- //
            case Property.Health:
                if (value < 0)
                {
                    HealthLostEvent?.Invoke(target, -value);
                }
                else
                {
                    HealthGainedEvent?.Invoke(target, value);
                }
                break;

            // --- Stat --- //
            case Property.Str:
            case Property.Dex:
            case Property.Int:
            case Property.Fire:
            case Property.Nature:
            case Property.Water:
            case Property.Wind:
                Stat stat = prop.ToStat();
                StatChangedEvent?.Invoke(target, stat, value, Math.Abs(value * 2));
                break;

            default:
                UISystem.Message(String.Format("Item effect not implemented: {0} ({1})", prop.ToString(), value));
                break;
            }
        }
Exemplo n.º 3
0
        public void PickUpItem(int character)
        {
            Position position     = EntityManager.GetComponent <TransformComponent>(character).Position;
            int      pickupItemID = Util.CurrentFloor.GetFirstItem(position);

            if (pickupItemID == 0)
            {
                UISystem.Message("Nothing here to be picked up!");
                return;
            }

            bool success = AddItem(character, pickupItemID);

            if (!success)
            {
                return;
            }

            // post message to player
            UISystem.Message(DescriptionSystem.GetNameWithID(character) + " picked up " + DescriptionSystem.GetNameWithID(pickupItemID));

            Util.CurrentFloor.RemoveItem(position, pickupItemID);

            Util.TurnOver(character);
        }
Exemplo n.º 4
0
        public void UseItem(int character, int item, ItemUsage usage)
        {
            var usableItem = EntityManager.GetComponent <UsableItemComponent>(item);

            if (usableItem == null)
            {
                UISystem.Message("You can't use that!");
                return;
            }

            if (!usableItem.Usages.Contains(usage))
            {
                UISystem.Message("You can't use that like that!");
                return;
            }

            UISystem.Message(DescriptionSystem.GetNameWithID(character) + " uses " + DescriptionSystem.GetNameWithID(item) + " -> " + usage);

            switch (usage)
            {
            case ItemUsage.Consume:
                ConsumeItem(character, item);
                break;

            case ItemUsage.Throw:
                // TODO: throwing range
                InputManager.Instance.InitiateTargeting((pos) => ThrowItem(character, item, pos));
                break;
            }
        }
Exemplo n.º 5
0
        // This function tries to do the following things in order:
        // tries to use an item if inventory is open
        // tries to interact with terrain under player
        // tries to pick up Item
        private void HandleSpacePressed()
        {
            if (UI.InventoryOpen)
            {
                //Console.WriteLine("Space trigger item use!");
                //Console.WriteLine("UsedItemEvent null? " + UsedItemEvent == null);
                UsedItemEvent?.Invoke(Util.PlayerID, EntityManager.GetComponent <InventoryComponent>(Util.PlayerID).Items[UI.InventoryCursorPosition - 1], ItemUsage.Consume);
                return;
            }

            var playerPos = EntityManager.GetComponent <TransformComponent>(Util.PlayerID).Position;

            int terrain = Util.CurrentFloor.GetTerrain(playerPos);

            if (terrain != 0) // is there special terrain?
            {
                var terrainInteraction = EntityManager.GetComponent <InteractableComponent>(terrain);

                if (terrainInteraction != null) // is it interactable?
                {
                    InteractionEvent?.Invoke(Util.PlayerID, terrain);
                    return;
                }
            }

            bool itemsOnFloor = Util.CurrentFloor.GetItems(playerPos).Count() > 0; // are there items here?

            if (!itemsOnFloor)
            {
                UISystem.Message("No items here to be picked up!");
                return;
            }

            PickupItemEvent?.Invoke(Util.PlayerID);
        }
Exemplo n.º 6
0
        void HandleAttackMessage(int attacker, int defender, Dictionary <DamageType, int> damages)
        {
            var posAttacker = EntityManager.GetComponent <TransformComponent>(attacker).Position;
            var posDefender = EntityManager.GetComponent <TransformComponent>(defender).Position;

            var seenPositions = Util.CurrentFloor.GetSeenPositions();

            bool attackerVisible = seenPositions.Contains(posAttacker);
            bool defenderVisible = seenPositions.Contains(posDefender);

            if (!(attackerVisible || defenderVisible))
            {
                return;
            }

            StringBuilder sb = new StringBuilder();

            if (attackerVisible)
            {
                sb.Append(DescriptionSystem.GetName(attacker));
            }
            else
            {
                sb.Append("Something");
            }

            sb.Append(" attacks ");

            if (defenderVisible)
            {
                sb.Append(DescriptionSystem.GetName(defender));
            }
            else
            {
                sb.Append("Something");
            }

            sb.Append("!");

            // e.g. "(69 fire, 42 water, ...)"
            sb.Append(" (");
            for (int i = 0; i < damages.Count; i++)
            {
                if (i > 0)
                {
                    sb.Append(", ");
                }
                sb.AppendFormat("{0} {1}",
                                damages.ElementAt(i).Value,
                                damages.ElementAt(i).Key);
            }

            sb.Append(")");

            UISystem.Message(sb.ToString());
        }
Exemplo n.º 7
0
        public void ConsumeItem(int character, int item)
        {
            UISystem.Message(String.Format("{0} consumes {1}", DescriptionSystem.GetNameWithID(character), DescriptionSystem.GetNameWithID(item)));

            ApplySubstance(character, item, 1f);

            IdentifyItem(item);
            DecreaseItemCount(character, item);
            TryDeleteItem(item);
            Util.TurnOver(character);
        }
Exemplo n.º 8
0
        public void ChangeStat(int entity, Stat stat, int amount, int duration)
        {
            var stats = EntityManager.GetComponent <StatComponent>(entity);

            if (stats == null)
            {
                Log.Warning("This entity doesn't have stats!");
                return;
            }

            var baseStats = stats.Values;

            if (duration < 0)
            {
                Log.Warning("Stat modification duration can't be smaller than zero!");
                return;
            }

            if (duration == 0) // permanent!
            {
                baseStats[stat] += amount;
                UISystem.Message("Some attributes of " + DescriptionSystem.GetName(entity) + " have changed! (permanent)");
                return;
            }

            // add modifications to stats and add to dict for tracking

            baseStats[stat] += amount;

            var mod = new StatModification(stat, amount, duration + 1); // add one to duration to compensate for turn of use

            modifications.TryGetValue(entity, out List <StatModification> modsOfEntity);

            if (modsOfEntity == null)
            {
                //Console.WriteLine("No mod list for this entiy yet");
                modsOfEntity = new List <StatModification>()
                {
                    mod
                };
                modifications.Add(entity, modsOfEntity);
            }
            else
            {
                modsOfEntity.Add(mod);
            }

            UISystem.Message("Some attributes of " + DescriptionSystem.GetName(entity) + " have changed! (" + duration + " turns)");
        }
Exemplo n.º 9
0
        public void HandleLostHealth(int entity, float amountLost)
        {
            var healthComponent = EntityManager.GetComponent <HealthComponent>(entity);

            healthComponent.Amount -= amountLost;

            // ded
            if (healthComponent.Amount <= 0)
            {
                UISystem.Message(DescriptionSystem.GetNameWithID(entity) + " dies!");
                Util.CurrentFloor.RemoveCharacter(LocationSystem.GetPosition(entity));
                EntityManager.RemoveEntity(entity); // mark entity for deletion
            }

            //Log.Message("Entity " + entity + " HP: " + healthComponent.Amount + "|" + healthComponent.Max + " (-" + amountLost + ")");
        }
Exemplo n.º 10
0
        /// <summary>
        /// Crafts an item from the added ingredients
        /// </summary>
        /// <returns>true if item was succesfully created</returns>
        public bool CraftItem()
        {
            if (items.Count < 2)
            {
                UISystem.Message("You need to put in at least two items!");
                ResetCrafting();
                return(false);
            }

            ExtractSubstances();

            // TODO: other crafting than alchemy
            int newItem = Alchemy();

            if (newItem == 0)
            {
                // something went wrong before and
                // should have already been handled
                ResetCrafting();
                return(false);
            }

            UISystem.Message("You just crafted something!");

            substances.Clear();

            foreach (var itemID in items)
            {
                ItemSystem.TryDeleteItem(itemID);
            }

            items.Clear();

            //var description = EntityManager.GetComponent<DescriptionComponent>(newItem);
            //description.Name = "Crafted " + description.Name;
            ItemAddedEvent?.Invoke(Util.PlayerID, newItem);

            string info = DescriptionSystem.GetDebugInfoEntity(newItem);

            Log.Message("Crafting successful:");
            Log.Data(info);

            Util.TurnOver(Util.PlayerID);
            return(true);
        }
Exemplo n.º 11
0
        public void TurnOver(int entity)
        {
            modifications.TryGetValue(entity, out List <StatModification> modsOfEntity);

            if (modsOfEntity == null)
            {
                return;
            }

            // unless the entity got its stat component removed this should never be null
            var statsOfEntity = EntityManager.GetComponent <StatComponent>(entity);

            var stats = statsOfEntity.Values;

            bool effectRemoved = false;
            List <StatModification> toBeRemoved = new List <StatModification>();

            for (int i = 0; i < modsOfEntity.Count; i++)
            {
                var mod = modsOfEntity[i];

                mod.Duration -= 1;

                //Console.WriteLine(mod.Duration + " left");

                if (mod.Duration == 0)
                {
                    // reverse modification and mark for removal
                    stats[mod.Stat] -= mod.Amount;
                    toBeRemoved.Add(mod);
                    effectRemoved = true;
                }
            }

            foreach (var mod in toBeRemoved)
            {
                modsOfEntity.Remove(mod);
            }

            if (effectRemoved)
            {
                UISystem.Message("Some attributes of " + DescriptionSystem.GetName(entity) + " return to normal.");
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// try to craft something using alchemy
        /// assumes all the substances are already extracted
        /// </summary>
        /// <returns> ID of newly crafted item (or 0 on fail) </returns>
        public int Alchemy()
        {
            // TODO: check if there's at least some liquid in the recipe or something

            if (!substances.Any(s => s.MaterialType == Components.MaterialType.Potion))
            {
                UISystem.Message("You need at least one Potion!");
                return(0);
            }

            Dictionary <Property, int> accumulatedProperties = new Dictionary <Property, int>();

            foreach (var substance in substances)
            {
                foreach (var prop in substance.Properties)
                {
                    if (accumulatedProperties.ContainsKey(prop.Key))
                    {
                        accumulatedProperties[prop.Key] += prop.Value; // TODO: reduce weight of ingredients?
                    }
                    else
                    {
                        accumulatedProperties[prop.Key] = prop.Value;
                    }
                }
            }

            int potion = CreatePotion(accumulatedProperties);

            // let the player learn about the created potion's properties
            var knowledge = EntityManager.GetComponent <SubstanceKnowledgeComponent>(Util.PlayerID);

            foreach (var prop in accumulatedProperties.Keys)
            {
                knowledge.PropertyKnowledge[prop]           += 10;
                knowledge.TypeKnowledge[prop.GetPropType()] += 5;
            }

            // make sure the properties of the created potion aren't displayed by default
            EntityManager.GetComponent <SubstanceComponent>(potion).PropertiesKnown = false;

            return(potion);
        }
Exemplo n.º 13
0
        public void AddIngredient(int item)
        {
            if (items.Count >= maxSlots)
            {
                UISystem.Message("You can't use that many ingredients at once! (max. " + maxSlots + ")");
                return;
            }

            var substance = EntityManager.GetComponent <SubstanceComponent>(item);

            if (substance == null)
            {
                UISystem.Message("This item can not be used for crafting!");
                return;
            }

            // remember item and remove it from player inventory
            items.Add(item);
            ItemSystem.DecreaseItemCount(Util.PlayerID, item);
        }
Exemplo n.º 14
0
        void ApplySubstance(int target, int item, float modifier)
        {
            var substance = EntityManager.GetComponent <SubstanceComponent>(item);

            if (substance == null)
            {
                Log.Warning("Usable Item does not have SubstanceComponent attached!");
                return;
            }

            Dictionary <Property, int> properties = substance.Properties;

            if (properties == null || properties.Count == 0)
            {
                UISystem.Message("That had no effect...");
                return;
            }

            foreach (var prop in properties)
            {
                ResolveProperty(prop.Key, (int)Math.Round(prop.Value * modifier), target);
            }
        }
Exemplo n.º 15
0
        public bool HandleInteraction(int actor, int other)
        {
            var interactable = EntityManager.GetComponent <InteractableComponent>(other);

            if (interactable == null)
            {
                Log.Error("HandleInteraction called on non-interactable object!");
                Log.Data(DescriptionSystem.GetDebugInfoEntity(other));
                return(false);
            }

            //Log.Message("Interaction between " + DescriptionSystem.GetNameWithID(actor) + " and " + DescriptionSystem.GetNameWithID(other));
            //Log.Data(DescriptionSystem.GetDebugInfoEntity(other));

            if (interactable.ChangeSolidity)
            {
                var collider = EntityManager.GetComponent <ColliderComponent>(other);

                if (collider == null)
                {
                    Log.Warning("Interactable has ChangeSolidity set but has no collider attached! " + DescriptionSystem.GetNameWithID(other));
                    Log.Data(DescriptionSystem.GetDebugInfoEntity(other));
                }
                else if (collider.Solid == false)
                {
                    //TODO: make it solid again? ( ._.)?
                }
                else
                {
                    collider.Solid = false;
                }
            }

            if (interactable.ChangeTexture)
            {
                var renderable = EntityManager.GetComponent <RenderableSpriteComponent>(other);

                if (renderable == null)
                {
                    Log.Error("Interactable has ChangeTexture set but does not have RenderableSprite attached! " + DescriptionSystem.GetNameWithID(other));
                    Log.Data(DescriptionSystem.GetDebugInfoEntity(other));
                    return(false);
                }

                if (interactable.AlternateTexture == "")
                {
                    Log.Warning("Interactable has ChangeTexture set but does not define AlternateTexture! " + DescriptionSystem.GetNameWithID(other));
                    Log.Data(DescriptionSystem.GetDebugInfoEntity(other));
                    renderable.Texture = "square"; // placholder; something's not right
                }
                else
                {
                    renderable.Texture = interactable.AlternateTexture;
                }
            }

            if (interactable.GrantsItems)
            {
                if (interactable.Items == null)
                {
                    Log.Warning("Interactable has GrantItems set but does not define Items! " + DescriptionSystem.GetNameWithID(other));
                    Log.Data(DescriptionSystem.GetDebugInfoEntity(other));
                }
                else if (interactable.Items.Count == 0)
                {
                    UISystem.Message("Nothing here to be picked up!");
                    return(false);
                }
                else
                {
                    var inventory = EntityManager.GetComponent <InventoryComponent>(actor);
                    if (inventory == null)
                    {
                        Log.Warning("Pick up failed. Character has no inventory! " + DescriptionSystem.GetNameWithID(actor));
                        return(false);
                    }
                    else
                    {
                        if (ItemAddedEvent == null)
                        {
                            Log.Error("InteractionSystem->ItemAddedEvent is null!");
                            return(false);
                        }

                        bool success = ItemAddedEvent.Invoke(actor, interactable.Items[0]);

                        if (success)
                        {
                            interactable.Items.RemoveAt(0);
                        }
                        else
                        {
                            // Failed to add to inventory (should already be handled)
                            return(false);
                        }
                    }
                }
            }

            Util.TurnOver(actor);
            return(true);
        }
Exemplo n.º 16
0
        /// <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)
            //{

            //}
        }
Exemplo n.º 17
0
        /// <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);
        }