Esempio n. 1
0
        public void Execute(List <string> extraWords, Character interactingCharacter)
        {
            var useableLocationItems = interactingCharacter.GetLocation().GetUseableItems()
                                       .Select(i => new KeyValuePair <Item, string>(
                                                   i.Key,
                                                   i.Key.GetDescription(i.Value).UppercaseFirstChar()
                                                   ));

            var useableCharacterItems = interactingCharacter.GetUseableInventoryItems()
                                        .Select(i => new KeyValuePair <Item, string>(
                                                    i.Key,
                                                    i.Key.GetDescription(i.Value).UppercaseFirstChar()
                                                    ));

            // This represents all items that can be used (either directory or indirectly)
            var allUseableItems = useableLocationItems
                                  .Union(useableCharacterItems)
                                  .ToDictionary(i => i.Key, i => i.Value); // This also removes duplicates

            // This represnts only primary interaction items
            var allPrimaryItems = allUseableItems
                                  .Where(i => i.Key.IsInteractionPrimary)
                                  .ToDictionary(i => i.Key, i => i.Value); // This also removes duplicates

            // The end goal of interact is to interact with a primary item,
            // so if none of those exist here, we are done.
            if (!allPrimaryItems.Any())
            {
                interactingCharacter.SendDescriptiveTextDtoMessage("There is nothing available to interact with.");
                interactingCharacter.GetLocation().SendDescriptiveTextDtoMessage($"{interactingCharacter.Name} is looking around for something.", interactingCharacter);
                return;
            }

            Item primaryItem   = null;
            Item secondaryItem = null;

            // If there were extra words typed in, then attempt to auto-map them
            if (extraWords.Count > 0)
            {
                // Try to auto-determine the choices if extra words are typed in
                var wordItemMap = WordTranslator.WordsToItems(extraWords, allUseableItems.Keys.ToList());
                var foundItems  = wordItemMap
                                  .Where(i => i.Value != null)
                                  .Select(i => i.Value)
                                  .ToList();

                // The primary item is considered the last item in the sentence that is a primary interaction item
                primaryItem = foundItems.LastOrDefault(i => i.IsInteractionPrimary);

                // This example contains only 1 item that has its primary property set (keyhole)
                // Considering that a player could type sentences like this
                //     use key on keyhole       - This syntax works also when there are 2 primaries involved
                //     use keyhole with key     - This syntax won't work with 2 primaries, it will get them backwards
                //                                For this reason, we disable this pattern all-together to avoid confusion
                // In cases where we are working with 2 primary items, the code can't really determine if the first
                // or the second is the primary. It works fine with 1 primary only both ways, but then messes up when there
                // are two primaries. Therefore to make it so sentences always produce a dependable result we make the
                // rule that a secondary item MUST come before the primary item in the sentence.
                // We only set secondary if a primary item was found though
                if (primaryItem != null)
                {
                    foreach (var foundItem in foundItems)
                    {
                        // We reached the primary item, stop looking as it is invalid
                        // for the secondary item to exist past the primary
                        if (foundItem.TrackingId == primaryItem.TrackingId)
                        {
                            break;
                        }
                        secondaryItem = foundItem;
                        break;
                    }
                }

                if (
                    primaryItem == null ||                                                    // extra words were typed, but no primary found
                    (primaryItem != null && secondaryItem == null && foundItems.Count > 1) || // the extra words looked like more items than what we could map to
                    (primaryItem != null && secondaryItem != null && foundItems.Count > 2)    // the extra words looked like more items than what we could map to
                    )
                {
                    interactingCharacter.SendDescriptiveTextDtoMessage("I don't quite understand, make sure the target item you want to use is last in the sentence.");
                    return;
                }

                // Otherwise the extra words seem to have translated into the items to use properly
                primaryItem.Interact(secondaryItem, interactingCharacter);
            }
        }
Esempio n. 2
0
        public void Execute(List <string> extraWords, Character grabbingCharacter)
        {
            var grabbingCharacterLocation = GrainClusterClient.Universe.GetCharacterLocation(grabbingCharacter.TrackingId).Result;
            var locationItems             = GrainClusterClient.Universe.GetLocationItems(grabbingCharacterLocation.TrackingId).Result;

            if (locationItems == null || locationItems.Count == 0)
            {
                grabbingCharacter.SendDescriptiveTextDtoMessage("There is nothing to grab.");
                grabbingCharacter.GetLocation().SendDescriptiveTextDtoMessage($"{grabbingCharacter.Name} is looking around for something.", grabbingCharacter);
                return;
            }

            var availableItems = locationItems
                                 .Where(i => !i.Key.IsBound && i.Key.IsVisible) // Filter out bound and invisible items because these cannot be picked up
                                 .Select(i => new KeyValuePair <Item, string>(
                                             i.Key,
                                             i.Key.GetDescription(i.Value).UppercaseFirstChar()
                                             ))
                                 .ToDictionary(i => i.Key, i => i.Value);

            if (!availableItems.Any())
            {
                grabbingCharacter.SendDescriptiveTextDtoMessage("There is nothing that can be grabbed.");
                grabbingCharacter.GetLocation().SendDescriptiveTextDtoMessage($"{grabbingCharacter.Name} is looking around for something.", grabbingCharacter);
                return;
            }

            // Try to auto-determine what the player is trying to grab
            var wordItemMap = WordTranslator.WordsToItems(extraWords, availableItems.Keys.ToList());
            var foundItems  = wordItemMap
                              .Where(i => i.Value != null)
                              .Select(i => i.Value)
                              .ToList();
            Item itemToGrab;

            if (foundItems.Count == 0)
            {
                grabbingCharacter.SendDescriptiveTextDtoMessage("There is nothing like that here.");
                grabbingCharacter.GetLocation().SendDescriptiveTextDtoMessage($"{grabbingCharacter.Name} is looking around for something.", grabbingCharacter);
                return;
            }
            itemToGrab = foundItems[0];

            var itemAmountToGrab = locationItems[itemToGrab];

            if (itemAmountToGrab > 1)
            {
                var leftWords     = wordItemMap.Where(i => i.Value == null).Select(i => i.Key).ToList();
                var wordNumberMap = WordTranslator.WordsToNumbers(leftWords);
                var foundNumbers  = wordNumberMap.Where(i => i.Value.HasValue).Select(i => i.Value.Value).ToList();
                if (foundNumbers.Count > 0)
                {
                    itemAmountToGrab = foundNumbers[0];
                }

                if (itemAmountToGrab <= 0)
                {
                    return;
                }
                if (itemAmountToGrab > locationItems[itemToGrab])
                {
                    itemAmountToGrab = locationItems[itemToGrab];
                }
            }

            itemToGrab.Grab(itemAmountToGrab, grabbingCharacter);
        }
Esempio n. 3
0
        public void Execute(List <string> extraWords, Character droppingCharacter)
        {
            var droppingCharacterLocation = GrainClusterClient.Universe.GetCharacterLocation(droppingCharacter.TrackingId).Result;
            var droppingCharacterItems    = GrainClusterClient.Universe.GetCharacterItems(droppingCharacter.TrackingId).Result;

            if (droppingCharacterItems == null || droppingCharacterItems.Count == 0)
            {
                droppingCharacter.SendDescriptiveTextDtoMessage("You have no items.");
                droppingCharacter.GetLocation().SendDescriptiveTextDtoMessage($"{droppingCharacter.Name} is happy that they have no items.", droppingCharacter);
                return;
            }

            var availableItems = droppingCharacterItems
                                 .Where(i => !i.Key.IsBound && i.Key.IsVisible) // Filter out bound and invisible items because these cannot be dropped
                                 .Select(i => new KeyValuePair <Item, string>(
                                             i.Key,
                                             i.Key.GetDescription(i.Value).UppercaseFirstChar()
                                             ))
                                 .ToDictionary(i => i.Key, i => i.Value);

            if (!availableItems.Any())
            {
                droppingCharacter.SendDescriptiveTextDtoMessage("You have nothing that can be dropped.");
                droppingCharacter.GetLocation().SendDescriptiveTextDtoMessage($"{droppingCharacter.Name} is digging around in their inventory looking for something.", droppingCharacter); // TODO: he/she/pronoun ?
                return;
            }

            // Try to auto-determine what the character is trying to drop
            var wordItemMap = WordTranslator.WordsToItems(extraWords, availableItems.Keys.ToList());
            var foundItems  = wordItemMap
                              .Where(i => i.Value != null)
                              .Select(i => i.Value)
                              .ToList();
            Item itemToDrop;

            if (foundItems.Count == 0)
            {
                droppingCharacter.SendDescriptiveTextDtoMessage("You don't have anything like that.");
                droppingCharacter.GetLocation().SendDescriptiveTextDtoMessage($"{droppingCharacter.Name} is digging around in their inventory looking for something.", droppingCharacter); // TODO: he/she/pronoun ?
                return;
            }
            itemToDrop = foundItems[0];

            var itemAmountToDrop = droppingCharacterItems[itemToDrop];

            if (itemAmountToDrop > 1)
            {
                var leftWords     = wordItemMap.Where(i => i.Value == null).Select(i => i.Key).ToList();
                var wordNumberMap = WordTranslator.WordsToNumbers(leftWords);
                var foundNumbers  = wordNumberMap.Where(i => i.Value.HasValue).Select(i => i.Value.Value).ToList();
                if (foundNumbers.Count > 0)
                {
                    itemAmountToDrop = foundNumbers[0];
                }

                if (itemAmountToDrop <= 0)
                {
                    return;
                }
                if (itemAmountToDrop > droppingCharacterItems[itemToDrop])
                {
                    itemAmountToDrop = droppingCharacterItems[itemToDrop];
                }
            }

            itemToDrop.Drop(itemAmountToDrop, droppingCharacter);
        }