Esempio n. 1
0
        public static Item[] VisibleItems(MOB mob, Body vehicle)
        {
            Room startingRoom = vehicle.Position.ForRoom;

            //Massively TODO.
            //In the long term, I think MOBs should have some short term memory about this, knowing who went where,
            //which might also be used to cache what they can see.
            //No great ideas for the calculations themselves right now. I probably want to keep this very simple somehow instead
            //of doing lots of trig and angles and sizes for everything.

            //Related idea TODO eventually:
            //Have a setting for 'Item shortcuts'. Add something like {a} then {b} then {c} and so on (going to {aaa} and so on if needed) to items a user observes.
            //Let user refer to items/things by {a} and so on instead of the name. Require that shortcuts not be reused for x amount of time.
            //Want to maybe do something extra fancy with this, for similar things user could conceivably confuse together or things that change unnoticed;
            //"Mook in red shirt {a} leaves east. Mook in red shirt {b} enters from the west." <-- gives away two different mooks
            //"Mook in red shirt {a} leaves east. Mook in red shirt {a} enters from the west." <-- implies same mook but maybe they are actually different but unusually similar.
            //"Mook in red shirt {a} leaves east. Damsel in distress {a} enters from the east." <-- similarly gives away that mook is disguised as damsel.

            //Another Related idea TODO eventually:
            //Allow user to ASSIGN shortcuts to items. This needs to be fundamentally different then the other item shortcuts though, maybe with a user-selected option for each item.
            // - Can remember only the item, assume it's the same item if see something similar elsewhere.
            // - Remember the item and position, assume it's the same item if see something similar in the same place later.
            // - Track the item, similar as above? probably not make this an option.

            return(startingRoom.GetItems());
        }
Esempio n. 2
0
        /// <summary>
        /// Try to parse the input as a command for this MOB to perform. If found, immediately executes the command.
        /// This method will probably end up being refactored in the future, some of this makes more sense in Command.cs and
        /// some of this will need to be smarter about context for commands before just running commands (e.g. 'order')
        /// </summary>
        /// <param name="input">Full input string to try to Execute.</param>
        /// <param name="currentMob">Current MOB to perform the action as, if there is a MOB associated with the input.</param>
        public void TryFindCommand(string input, MOB currentMob)
        {
            string[] words       = input.Split(' ');
            string   commandWord = words[0].ToLower();
            Command  command;

            if (Command.UniqueCommands.TryGetValue(commandWord, out command))
            {
                if (!command.CanUse(this, currentMob))
                {
                    sendMessage("You cannot ever use \"" + command.OriginalCommandName + "\".");
                    return;
                }
            }
            else
            {
                List <CommandEntry> options = Command.SortedAllCommands;
                int index = options.BinarySearch(new CommandEntry(commandWord, null));
                if (index < 0)
                {
                    index = -index - 1;
                }
                while (index > 0 && options[index - 1].Trigger.StartsWith(commandWord)) //In case of exact commandWord matches, backtrack to the first Command with that word.
                {
                    index--;
                }
                while (index < options.Count)
                {
                    CommandEntry next = options[index];
                    if (!next.Trigger.StartsWith(commandWord))
                    {
                        break; //No matches. command is default from TryGetValue
                    }
                    if (next.Command.CanUse(this, currentMob))
                    {
                        command = next.Command;
                        break;
                    }
                }
            }

            if (command != null)
            {
                QueuedCommand userCommand = command.GetQueuedCommand(input);
                if (currentMob != null)
                {
                    command.Execute(currentMob, userCommand);
                }
                else
                {
                    command.Execute(this, userCommand);
                }
            }
            else
            {
                sendMessage("No command available for \"" + words[0] + "\".");
            }
        }
Esempio n. 3
0
 public bool RemoveMOB(MOB mob)
 {
     if (!mobs.Remove(mob))
     {
         return(false);
     }
     this.Save();
     return(true);
 }
Esempio n. 4
0
 /// <summary>
 /// Permanently removes a character from this account.
 /// </summary>
 /// <param name="mob"></param>
 /// <returns></returns>
 public bool RemoveCharacter(MOB mob)
 {
     if (unloadedCharacters.Remove(mob))
     {
         mob.OwningAccount = null;
         this.Save();
         return(true);
     }
     return(false);
 }
Esempio n. 5
0
        //TODO: Race/genes, body data specific to race(s). Hybrids will probably have a HybridBodyData with
        //sub-BodyData objects for each race and sort things out that way... also need Race/Body data stuff for vehicles,
        //which won't have genes but do have bodies. Maybe a modifications section for bodies that vehicles use entirely.
        //Also need indications of what functionality the body has and how to execute those functionalities / what they
        //cost.
        //Side concern: What if a spell or something can make an Item a Body? Probably need to figure out that edge case
        //at some point. Most inclined to make a special Body class that wraps the Item, but that definitely has some
        //issues I don't like.
        //MOB Bodys may be a subclass of this later? Pretty certain yes. Those bodies will contain stat lines and maybe
        //other stuff I figure out later. At the moment I can't actually think of anything other than a statline, basically.

        public bool AddMOB(MOB mob)
        {
            if (mobs.Contains(mob))
            {
                return(false);
            }
            mobs.Add(mob);
            this.Save();
            return(true);
        }
Esempio n. 6
0
        public override void Execute(MOB mob, QueuedCommand command)
        {
            StringWords  input    = command.parsedCommand;
            int          distance = -1;
            MovementUnit unit;

            if (input.Segments.Length > 1)
            {
                TextParsing.ParseAsDistance(input, out distance, out unit, 1);
            }
            //TODO: finish this
        }
Esempio n. 7
0
 public void AddMOBLock(MOB mob)
 {
     while (true)
     {
         Body body         = mob.Body;
         Room startingRoom = body.Position.ForRoom;
         lockToDispose.AddResource(startingRoom);
         if (body == mob.Body && body.Position.ForRoom == startingRoom)
         {
             return;
         }
     }
 }
Esempio n. 8
0
        public static List <Item> FindKnownItems(StringWords input, MOB mob, int start, int end)
        {
            input.ValidateEndIndex(ref end);
            Item[]      items         = GeneralUtilities.VisibleItems(mob, mob.Body);
            List <Item> matchingItems = new List <Item>();

            foreach (Item item in items)
            {
                if (mob.CanRecognize(item, input, start, end))
                {
                    matchingItems.Add(item);
                }
            }
            return(matchingItems);
        }
Esempio n. 9
0
        /// <summary>
        /// Find an item that the specified mob can sense and identify from the given text input.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="mob"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="onPrompt"></param>
        /// <param name="addToPrompt"></param>
        /// <returns></returns>
        public static Item FindKnownItem(StringWords input, MOB mob, int start, int end, SelectAction onPrompt = null, StandardHeldPrompt addToPrompt = null) //, out RoomLink viaExit
        {
            //viaExit = null; //TODO later: When finding items in other rooms, report what direction the item is in.
            List <Item> options = FindKnownItems(input, mob, start, end);

            if (options.Count == 1)
            {
                return(options[0]);
            }

            Client client = mob.Client;

            if (client == null)
            {
                //TODO: Have an NPC say they don't know what item they were told to find?
                return(null);
            }

            if (options.Count == 0)
            {
                client.sendMessage("You don't notice a '" + input.StringRange(start, end) + "'");
                return(null);
            }

            if (onPrompt == null)
            {
                client.sendMessage("There are too many things that fit that description.");
                return(null);
            }
            //TODO: Consider an alternative function to move prompt stuff to and add an out bool for prompting instead, not
            //sure if there's a need for that bool right now though; leave this one without prompt stuff

            //TODO: Some way to check if the prompt is still valid would be nice too, but not sure how to do that well without
            // just requiring another function passed into here. Might do that anyways.
            SelectFromList <Item> itemSelectPrompt = new SelectFromList <Item>(onPrompt.Invoke);

            if (addToPrompt == null || !addToPrompt.TransitionTo(itemSelectPrompt, true))
            {
                client.Prompt(itemSelectPrompt);
            }
            return(null);
        }
Esempio n. 10
0
        /// <summary>
        /// Simpler function to call instead of ThreadManager.StartEvent. Return value works the same way.
        /// </summary>
        /// <param name="mob"></param>
        /// <returns></returns>
        public IDisposable StartEventFor(MOB mob, int timeout = 1000, bool?ignorePause = null)
        {
restart:
            Body body = mob.Body;
            Room        startingRoom = body.Position.ForRoom;
            IDisposable disposable;

            using (disposable = ThreadManager.StartEvent(startingRoom, this, timeout, ignorePause))
            {
                if (disposable == null)
                {
                    return(null); //Notify caller that event entirely failed.
                }
                if (mob.Body != body || body.Position.ForRoom != startingRoom)
                {
                    // Race condition, need to try again with new body/get lock for new room.
                    goto restart;  //This is probably fine but might make something smarter later.
                }
                disposable = null; //Have the caller dispose this instead.
                return(this);
            }
        }
Esempio n. 11
0
 /// <summary>
 /// Permanently adds a character to this account.
 /// </summary>
 /// <param name="mob"></param>
 public void AddCharacter(MOB mob)
 {
     this.unloadedCharacters.Add(mob);
     mob.OwningAccount = this;
     this.Save();
 }
Esempio n. 12
0
 /// <summary>
 /// Runs this command with the given mob and arguments.
 /// </summary>
 /// <param name="mob">Mob to perform the command.</param>
 /// <param name="command">Performed command data</param>
 public abstract void Execute(MOB mob, QueuedCommand command);
Esempio n. 13
0
        /// <summary>
        /// TODO: Move to a more appropriate place?
        ///  Should be called for a MOB's commands when a specific command is disabled on them.
        /// </summary>
        // Honestly this probably shouldn't be used. It probably still makes sense to generate things all at once.
        //public void removeCommands(MOB mob)
        //{
        //    foreach (CommandEntry entry in this.CommandEntries)
        //    {

        //        //listOfCommands.BinaryRemove(entry);
        //    }
        //}

        /// <summary>
        /// Checks if the given user or mob has access to this command. Doesn't mean they can use it,
        /// e.g. they may know a spell but not have the mana to cast it.
        /// </summary>
        /// <param name="user"></param>
        /// <param name="mob"></param>
        /// <returns>True if this command should be found in the mob's list of commands</returns>
        public abstract bool CanUse(Client user, MOB mob);
Esempio n. 14
0
 public static Room GetRoom(MOB fromMob)
 {
     return(fromMob.Body?.Position?.ForRoom);
 }
Esempio n. 15
0
 public void SetMoveSource(MOB mob, Body vehicle)
 {
     movementSource   = mob;
     eventSource      = vehicle ?? mob.Body;
     originalPosition = eventSource.Position;
 }
Esempio n. 16
0
 public override bool CanUse(Client user, MOB mob)
 {
     return(mob != null);
 }
Esempio n. 17
0
        public override void Execute(MOB mob, QueuedCommand command)
        {
            /*
             * Form is always (optional direction/distance) (optional preposition) (optional target)
             *  direction/distance can work alone (implies 'from here')
             *  if direction/distance is missing, if preposition is not specific, 'in reach' is implied
             *  preposition requires a target
             *  target can work alone (depends on target. If target defaults to enterable, implies 'in'. Else 'near')
             * Search for prepositions, get a list of them.
             *  Validate prepositions. Need to have nothing or a valid direction/distance before preposition.
             *  How many can actually be possible? I think only zero or one preposition is really possible?
             *  TODO: Special user input to specify a preposition instead of parser guessing. Mostly goes in StringWords but
             *  matching prepositions/item names needs to respect that too (might work automatically).
             *      Some system similar to quotes probably. Quotes may be useful though, like book titles or something.
             * If no prepositions, attempt to parse full string as direction/distance. If successful, do that
             * //Search whole string for item/target matches and associated strings.
             *  In general, 'visible to MOB' items.
             *  Must match to end of string?
             *  Nevermind, this string will be identified but targets will not be searched for until a TryGoEvent is run.
             * //Find associated strings that line up with a preposition
             * Instead of above two major points:
             *  Identify all valid strings (start after preposition, go to end of string)
             *      TODO: Special user input to specify a string instead of parser guessing?
             *          This is basically implied by a preposition. However it maybe makes more sense to specify the target instead of the preposition.
             *  //Search all 'visible to MOB' items that exactly match any of the valid strings.
             * How to pick best match?
             *  Maybe just not go if more than one match found, request more info. prompt?
             */
            StringWords goToInput = command.parsedCommand;

            //See if there's a preposition
            int start = 1; //Skip command ("go")
            int prepValue;
            MovementPreposition prepEnum;
            MovementDirection   direction = null;
            TryGoEvent          moveEvent = new TryGoEvent();
            int index = TextParsing.FindAPreposition(goToInput, typeof(MovementPreposition), out prepValue, start);

            if (index != -1)
            {
                //Is this a valid preposition? Check if it starts correctly.
                prepEnum = (MovementPreposition)prepValue;
                if (!prepEnum.AllowDirection() && !prepEnum.AllowDistance())
                {
                    if (index != start + 1)
                    {
                        //Invalid preposition for this location, needs to be at start of command.
                        goto noPrepositionFound;
                    }
                }
                else if ((prepEnum.RequireDirection() || prepEnum.RequireDistance()) && index == start + 1)
                {
                    //Invalid preposition for this location, needs to come after a direction/distance.
                    goto noPrepositionFound;
                }
                else
                {
                    direction = TextParsing.ParseAsDirection(goToInput, start, ref index, prepEnum.RequireDirection(), prepEnum.RequireDistance(), prepEnum.AllowDirection(), prepEnum.AllowDistance());
                    if (direction == null) //Not a valid preposition. Ignore it.
                    {
                        goto noPrepositionFound;
                    }
                    else //Maybe valid preposition.
                    {
                        //Check if preposition matches direction more closely? I think the previous checks have finished that successfully at this point.

                        //Valid preposition. Parse the REST of the sentence as an object.
                        start = index;
                        goto startEvent;
                    }
                }
            }
            else
            {
                //Is the whole thing a direction?
                direction = TextParsing.ParseAsDirection(goToInput, start, ref index);
                if (direction != null)
                {
                    if (direction.direction != Directions.NoDirection && index == goToInput.Segments.Length)
                    {
                        //Mark it as ONLY a direction, no destination (goToInput has been completely parsed/consumed)
                        goToInput = null;
                        //goto startEvent;
                    }
                    else
                    {
                        //Can't go only a distance with NoDirection. Cancel this parsing.
                        direction = null;
                    }
                }
                //Else try to parse the whole thing as an object to go to
            }
            //Text parsing has decided what words go to what (i.e. direction vs. target).
            //Text parsing has NOT identified objects yet.
noPrepositionFound:
            moveEvent.targetDescription = goToInput;
            start    = 1;
            prepEnum = MovementPreposition.To; // null; ?

startEvent:                                    //foundPreposition
            moveEvent.targetDescriptionStart = start;
            moveEvent.direction = direction;
            moveEvent.relation  = prepEnum;
            moveEvent.SetMoveSource(mob, null);

            //Raw command parsing done, target parsing has not been done.
            //Run the event to try to find a path to the target.
            moveEvent.FullRunEvent();
        }
Esempio n. 18
0
 /// <summary>
 /// Check if the specified MOB can see this event happening.
 /// </summary>
 /// <param name="mob">The MOB trying to observe this event.</param>
 /// <param name="focus">What the MOB is using to see this event (their own eyes, a scrying effect, etc.)</param>
 /// <returns></returns>
 public virtual bool CanObserveThis(MOB mob, object focus)
 {
     return(false);
 }