예제 #1
0
파일: Drink.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            // Rule: Do we have an item matching in our inventory?
            // @@@ TODO: Support drinking from, for instance, a fountain sitting in the room.
            string itemIdentifier = actionInput.Tail.Trim();
            this.thingToDrink = sender.Thing.FindChild(itemIdentifier.ToLower());
            if (this.thingToDrink == null)
            {
                return "You do not hold " + actionInput.Tail.Trim() + ".";
            }

            // Rule: Is the item drinkable?
            this.drinkableBehavior = this.thingToDrink.Behaviors.FindFirst<DrinkableBehavior>();
            if (this.drinkableBehavior == null)
            {
                return itemIdentifier + " is not drinkable";
            }

            return null;
        }
예제 #2
0
파일: Chop.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Prepare for, and determine if the command's prerequisites have been met.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            // Rule: Did they specify a tree to chop?
            // @@@ TODO: Better thing finders...
            Thing parent = actionInput.Controller.Thing.Parent;
            Thing thing = parent.Children.Find(t => t.Name.Equals(actionInput.Params[0], StringComparison.CurrentCultureIgnoreCase));
            if (thing == null)
            {
                return string.Format("{0} is not here.", actionInput.Params[0]);
            }

            // @@@ TODO: Detect ConsumableProviderBehavior on the item, and detect if it is choppable.
            //if (!(item is Item))
            //{
            //    return string.Format("{0} is not a tree.", actionInput.Params[0]);
            //}

            //this.tree = (Item) item;

            //if (this.tree.NumberOfResources <= 0)
            //{
            //    return string.Format("The tree doesn't contain any suitable wood.");
            //}

            return null;
        }
예제 #3
0
파일: Wield.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;

            this.itemToWieldBehavior.Wielder = sender.Thing;

            // Create an event handler that intercepts the ChangeOwnerEvent and
            // prevents dropping/trading the item around while it is wielded.
            // A reference is stored in the WieldableBehavior instance so it
            // can be easily removed by the unwield command.
            var interceptor = new CancellableGameEventHandler(this.Eventing_MovementRequest);
            this.itemToWieldBehavior.MovementInterceptor = interceptor;
            this.itemToWield.Eventing.MovementRequest += interceptor;

            var contextMessage = new ContextualString(sender.Thing, this.itemToWield.Parent)
            {
                ToOriginator = "You wield the $WieldedItem.Name.",
                ToOthers = "$ActiveThing.Name wields a $WieldedItem.Name.",
            };

            var sensoryMessage = new SensoryMessage(SensoryType.Sight, 100, contextMessage);

            var wieldEvent = new WieldUnwieldEvent(this.itemToWield, true, sender.Thing, sensoryMessage);

            sender.Thing.Eventing.OnCombatRequest(wieldEvent, EventScope.ParentsDown);

            if (!wieldEvent.IsCancelled)
            {
                sender.Thing.Eventing.OnCombatEvent(wieldEvent, EventScope.ParentsDown);
            }
        }
예제 #4
0
        /// <summary>Prepare for, and determine if the command's prerequisites have been met.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            // Rule: We should have at least 1 item in our words array.
            int numberWords = actionInput.Params.Length;
            if (numberWords < 2)
            {
                return "You must specify a room to create a portal to.";
            }

            // Check to see if the first word is a number.
            string roomToGet = actionInput.Params[1];
            if (string.IsNullOrEmpty(roomToGet))
            {
                // Its not a number so it could be an entity... try it.
                this.targetPlace = GameAction.GetPlayerOrMobile(actionInput.Params[0]);
                if (this.targetPlace == null)
                {
                    return "Could not convert " + actionInput.Params[0] + " to a room number.";
                }
            }

            //            this.targetRoom = bridge.World.FindRoom(roomToGet);
            if (this.targetPlace == null)
            {
                return string.Format("Could not find the room {0}.", roomToGet);
            }

            return null;
        }
예제 #5
0
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            string[] normalizedParams = this.NormalizeParameters(actionInput.Controller);
            string role = normalizedParams[0];
            string playerName = normalizedParams[1];

            Thing player = GameAction.GetPlayerOrMobile(playerName);
            if (player == null)
            {
                // If the player is not online, then load the player from the database
                //player = PlayerBehavior.Load(playerName);
            }

            // Rule: Does the player exist in our Universe?
            // @@@ TODO: Add code to make sure the player exists.

            // Rule: Does player already have role?
            /* @@@ FIX
            if (Contains(player.Roles, role))
            {
                return player.Name + " already has the " + role + " role.";
            }*/

            return null;
        }
예제 #6
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            // Not sure what would call this other than a player, but exit early just in case.
            // Implicitly also verifies that this.sender exists.
            if (this.userControlledBehavior == null)
            {
                return;
            }

            // No arguments were provided. Just show the current buffer setting and exit.
            if (string.IsNullOrEmpty(actionInput.Tail))
            {
                this.ShowCurrentBuffer();
                return;
            }

            // Set the value for the current session
            if (this.session.Connection != null)
            {
                this.session.Connection.PagingRowLimit = (this.parsedBufferLength == -1) ? this.session.Terminal.Height : this.parsedBufferLength;
            }

            this.userControlledBehavior.PagingRowLimit = this.parsedBufferLength;

            this.userControlledBehavior.Save();

            this.ShowCurrentBuffer();
        }
예제 #7
0
        public void TestParseText()
        {
            // Test empty string
            var actionInput = new ActionInput(string.Empty, null);
            Verify.IsNull(actionInput.Noun);
            Verify.IsNull(actionInput.Tail);
            Verify.IsNull(actionInput.Params);

            // Test simple 1-word command
            var oneWordInput = new ActionInput("look", null);
            Verify.AreEqual(oneWordInput.Noun, "look");
            Verify.IsNull(actionInput.Tail);
            Verify.IsNull(actionInput.Params);

            // Test 2-word command
            var twoWordInput = new ActionInput("look foo", null);
            Verify.AreEqual(twoWordInput.Noun, "look");
            Verify.AreEqual(twoWordInput.Tail, "foo");
            Verify.IsNotNull(twoWordInput.Params);
            Verify.AreEqual(twoWordInput.Params.Length, 1);

            // Test 2-word command
            var threeWordInput = new ActionInput("create consumable metal", null);
            Verify.AreEqual(threeWordInput.Noun, "create");
            Verify.AreEqual(threeWordInput.Tail, "consumable metal");
            Verify.IsNotNull(threeWordInput.Params);
            Verify.AreEqual(threeWordInput.Params.Length, 2);

            // Test input with leading/trailing spaces
            var spacedWordInput = new ActionInput(" look  foo ", null);
            Verify.AreEqual(spacedWordInput.Noun, "look");
            Verify.AreEqual(spacedWordInput.Tail, "foo");
            Verify.IsNotNull(spacedWordInput.Params);
            Verify.AreEqual(spacedWordInput.Params.Length, 1);
        }
예제 #8
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            Thing parent = sender.Thing.Parent;
            string searchString = actionInput.Tail.Trim().ToLower();

            if (string.IsNullOrEmpty(searchString))
            {
                sender.Write("You must specify something to search for.");
                return;
            }

            // Unique case. Use 'here' to list the contents of the room.
            if (searchString == "here")
            {
                sender.Write(this.ListRoomItems(parent));
                return;
            }

            // First check the place where the sender is located (like a room) for the target,
            // and if not found, search the sender's children (like inventory) for the target.
            Thing thing = parent.FindChild(searchString) ?? sender.Thing.FindChild(searchString);
            if (thing != null)
            {
                // @@@ TODO: Send a SensoryEvent?
                sender.Write(thing.Description);
            }
            else
            {
                sender.Write("You cannot find " + searchString + ".");
            }
        }
예제 #9
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            var contextMessage = new ContextualString(sender.Thing, this.target)
            {
                ToOriginator = "You cast ThunderClap at $ActiveThing.Name!",
                ToReceiver = "$Aggressor.Name casts ThunderClap at you, you only hear a ringing in your ears now.",
                ToOthers = "You hear $Aggressor.Name cast ThunderClap at $ActiveThing.Name!  It was very loud.",
            };
            var sm = new SensoryMessage(SensoryType.Hearing, 100, contextMessage);

            var attackEvent = new AttackEvent(this.target, sm, sender.Thing);
            sender.Thing.Eventing.OnCombatRequest(attackEvent, EventScope.ParentsDown);
            if (!attackEvent.IsCancelled)
            {
                var deafenEffect = new AlterSenseEffect()
                {
                    SensoryType = SensoryType.Hearing,
                    AlterAmount = -1000,
                    Duration = new TimeSpan(0, 0, 45),
                };

                this.target.Behaviors.Add(deafenEffect);
                sender.Thing.Eventing.OnCombatEvent(attackEvent, EventScope.ParentsDown);
            }
        }
예제 #10
0
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            string targetName = actionInput.Tail.Trim().ToLower();

            // Rule: Is the target an entity?
            this.target = GameAction.GetPlayerOrMobile(targetName);
            if (this.target == null)
            {
                return "You cannot see " + targetName + ".";
            }

            // Rule: Is the target in the same room?
            if (actionInput.Controller.Thing.Parent.ID != this.target.Parent.ID)
            {
                return "You cannot see " + targetName + ".";
            }

            // Rule: Is the target alive?
            if (this.target.Stats["health"].Value <= 0)
            {
                return this.target.Name + " is dead.";
            }

            return null;
        }
예제 #11
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            var parameters = actionInput.Params;

            // Ensure two 'credits' commands at the same time do not race for shared cache, etc.
            lock (cacheLockObject)
            {
                if (cachedContents == null || (parameters.Length > 0 && parameters[0].ToLower() == "reload"))
                {
                    StreamReader reader = new StreamReader("Files\\Credits.txt");
                    StringBuilder stringBuilder = new StringBuilder();
                    string s;
                    while ((s = reader.ReadLine()) != null)
                    {
                        if (!s.StartsWith(";"))
                        {
                            stringBuilder.AppendLine(s);
                        }
                    }

                    cachedContents = stringBuilder.ToString();
                }

                sender.Write(cachedContents);
            }
        }
예제 #12
0
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            // The comon guards already guarantees the sender is a player, hence no null checks here.
            this.player = sender.Thing;
            this.playerBehavior = sender.Thing.Behaviors.FindFirst<PlayerBehavior>();

            // Rule: The new pretitle must be empty or meet the length requirements.
            this.oldPretitle = this.player.SingularPrefix;

            if (!string.IsNullOrEmpty(actionInput.Tail)) {
                this.newPretitle = actionInput.Tail;

                if (this.newPretitle.Length < 2 || this.newPretitle.Length > 15)
                {
                    return "The pretitle may not be less than 2 nor more than 15 characters long.";
                }
            }

            //// One could implement 'no color' or 'no swearing' or 'no non-alpha character' rules here, etc.

            return null;
        }
예제 #13
0
파일: Drop.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            // Generate an item changed owner event.
            IController sender = actionInput.Controller;
            ContextualStringBuilder csb = new ContextualStringBuilder(sender.Thing, this.parent);
            csb.Append(@"$ActiveThing.Name drops $Thing.Name.", ContextualStringUsage.WhenNotBeingPassedToOriginator);
            csb.Append(@"You drop $Thing.Name.", ContextualStringUsage.OnlyWhenBeingPassedToOriginator);
            SensoryMessage message = new SensoryMessage(SensoryType.Sight, 100, csb);
            var changeOwnerEvent = new ChangeOwnerEvent(sender.Thing, message, sender.Thing, this.parent, this.thing);

            // Broadcast as a request and see if anything wants to prevent the event.
            this.parent.Eventing.OnMovementRequest(changeOwnerEvent, EventScope.ParentsDown);
            if (!changeOwnerEvent.IsCancelled)
            {
                // Always have to remove an item before adding it because of the event observer system.
                // @@@ TODO: Test, this may be broken now...
                this.thing.Parent.Remove(this.thing);
                this.parent.Add(this.thing);

                //// @@@ BUG: Saving currently throws a NotImplementedException. Disabled for now...
                this.thing.Save();
                this.parent.Save();

                // Broadcast the event.
                this.parent.Eventing.OnMovementEvent(changeOwnerEvent, EventScope.ParentsDown);
            }
        }
예제 #14
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            string[] normalizedParams = this.NormalizeParameters(sender);
            string role = normalizedParams[0];
            string playerName = normalizedParams[1];

            Thing player = GameAction.GetPlayerOrMobile(playerName);
            if (player == null)
            {
                // If the player is not online, then load the player from the database
                //player = PlayerBehavior.Load(playerName);
            }

            var userControlledBehavior = player.Behaviors.FindFirst<UserControlledBehavior>();
            var existingRole = (from r in userControlledBehavior.Roles where r.Name == role select r).FirstOrDefault();
            if (existingRole == null)
            {
                var roleRepository = new RoleRepository();

                // @@@ TODO: The role.ToUpper is a hack. Need to create a case insensitive method for the RoleRepository.NoGen.cs class.
                RoleRecord record = roleRepository.GetByName(role.ToUpper());
                //userControlledBehavior.RoleRecords.Add(record);
                //userControlledBehavior.UpdateRoles();
                player.Save();

                sender.Write(player.Name + " has been granted the " + role + " role.", true);
            }
        }
예제 #15
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;

            // Remove "weapon" from input tail and use the rest as the name.
            string weaponName = actionInput.Tail.Substring(6).Trim().ToLower();

            Thing weaponItem = new Thing(new WieldableBehavior(), new MovableBehavior());
            weaponItem.Name = weaponName;
            weaponItem.SingularPrefix = "a";
            //weaponItem.ID = Guid.NewGuid().ToString();
            weaponItem.ID = "0";

            var wasAdded = sender.Thing.Parent.Add(weaponItem);

            var userControlledBehavior = sender.Thing.Behaviors.FindFirst<UserControlledBehavior>();
            if (wasAdded)
            {
                userControlledBehavior.Controller.Write(string.Format("You create a weapon called {0}.", weaponItem.Name));
            }
            else
            {
                userControlledBehavior.Controller.Write(string.Format("Could not add {0} to the room!", weaponItem.Name));
            }
        }
예제 #16
0
파일: Mute.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;

            // Strings to be displayed when the effect is applied/removed.
            var muteString = new ContextualString(sender.Thing, this.playerToMute)
            {
                ToOriginator = "You mute $Target.",
                ToReceiver = "You are muted by $ActiveThing.",
                ToOthers = "$ActiveThing mutes $Target."
            };
            var unmuteString = new ContextualString(sender.Thing, this.playerToMute)
            {
                ToOriginator = "$Target is no longer mute.",
                ToReceiver = "You are no longer mute."
            };

            // Turn the above sets of strings into sensory messages.
            var muteMessage = new SensoryMessage(SensoryType.Sight, 100, muteString);
            var unmuteMessage = new SensoryMessage(SensoryType.Sight, 100, unmuteString);

            // Create the effect.
            var muteEffect = new MutedEffect(sender.Thing, this.muteDuration, muteMessage, unmuteMessage);

            // Apply the effect.
            this.playerToMute.Behaviors.Add(muteEffect);
        }
예제 #17
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            if (sender != null && sender.Thing != null)
            {
                Thing entity = sender.Thing;

                if (entity != null)
                {
                    if (!string.IsNullOrEmpty(this.NewDescription))
                    {
                        entity.Description = this.NewDescription;
                        entity.Save();
                        sender.Write("Description successfully changed.");
                    }
                    else
                    {
                        sender.Write(string.Format("Your current description is \"{0}\".", entity.Description));
                    }
                }
                else
                {
                    sender.Write("Unexpected error occurred changing description, please contact admin.");
                }
            }
        }
예제 #18
0
파일: Enter.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            // Rule: A thing must be singly targeted.
            // @@@ TODO: Try to find a single target according to the specified identifiers.  If more than one thing
            //           meets the identifiers then use a disambiguation targeting system to try to narrow to one thing.
            // @@@ TODO: This sort of find pattern may become common; maybe we need to simplify
            //           to having a Thing method which does this?  IE "List<Thing> FindChildren<T>(string id)"?
            Predicate<Thing> findPredicate = (Thing t) => t.Behaviors.FindFirst<EnterableExitableBehavior>() != null;
            List<Thing> enterableThings = sender.Thing.Parent.FindAllChildren(findPredicate);

            if (enterableThings.Count > 1)
            {
                return "There is more than one thing by that identity.";
            }
            else if (enterableThings.Count == 1)
            {
                Thing thing = enterableThings.First();
                this.enterableBehavior = thing.Behaviors.FindFirst<EnterableExitableBehavior>();
                if (this.enterableBehavior == null)
                {
                    return "You can not enter " + thing.Name + ".";
                }
            }

            // If we got this far, we couldn't find an appropriate enterable thing in the room.
            return "You can't see anything like that to enter.";
        }
예제 #19
0
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            Thing wielder = sender.Thing;
            Thing room = wielder.Parent;

            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            string itemName = actionInput.Tail.Trim().ToLower();

            // First look for a matching item in inventory and make sure it can
            // be wielded. If nothing was found in inventory, look for a matching
            // wieldable item in the surrounding environment.
            this.itemToUnwield = wielder.FindChild(item => item.Name.ToLower() == itemName && item.HasBehavior<WieldableBehavior>() && item.Behaviors.FindFirst<WieldableBehavior>().Wielder == sender.Thing);

            if (this.itemToUnwield == null)
            {
                this.itemToUnwield = wielder.Parent.FindChild(item => item.Name.ToLower() == itemName && item.HasBehavior<WieldableBehavior>() && item.Behaviors.FindFirst<WieldableBehavior>().Wielder == sender.Thing);
            }

            if (this.itemToUnwield == null)
            {
                return "You are not wielding the " + itemName + ".";
            }

            this.itemToUnwieldBehavior = this.itemToUnwield.Behaviors.FindFirst<WieldableBehavior>();

            return null;
        }
예제 #20
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;

            this.itemToUnwieldBehavior.Wielder = null;

            // Remove the event handler that prevents dropping the item while wielded.
            var interceptor = this.itemToUnwieldBehavior.MovementInterceptor;
            this.itemToUnwield.Eventing.MovementRequest -= interceptor;

            var contextMessage = new ContextualString(sender.Thing, this.itemToUnwield.Parent)
            {
                ToOriginator = "You unwield the $WieldedItem.Name.",
                ToOthers = "$ActiveThing.Name unwields a $WieldedItem.Name.",
            };

            var sensoryMessage = new SensoryMessage(SensoryType.Sight, 100, contextMessage);

            var unwieldEvent = new WieldUnwieldEvent(this.itemToUnwield, true, sender.Thing, sensoryMessage);

            sender.Thing.Eventing.OnCombatRequest(unwieldEvent, EventScope.ParentsDown);

            if (!unwieldEvent.IsCancelled)
            {
                sender.Thing.Eventing.OnCombatEvent(unwieldEvent, EventScope.ParentsDown);
            }
        }
예제 #21
0
파일: GoTo.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            // Send just one message to the command sender since they know what's going on.
            IController sender = actionInput.Controller;

            // Attempt exact ID match
            var targetPlace = ThingManager.Instance.FindThing(actionInput.Tail);

            // If input is a simple number, assume we mean a room
            int roomNum;
            targetPlace = int.TryParse(actionInput.Tail, out roomNum) ? ThingManager.Instance.FindThing("room/" + roomNum) : ThingManager.Instance.FindThingByName(actionInput.Tail, false, true);

            if (targetPlace == null)
            {
                sender.Write("Room or Entity not found.\n");
                return;
            }

            if (targetPlace.FindBehavior<RoomBehavior>() == null)
            {
                // If the target's parent is a room, go there instead
                if (targetPlace.Parent != null && targetPlace.Parent.FindBehavior<RoomBehavior>() != null)
                {
                    targetPlace = targetPlace.Parent;
                }
                else
                {
                    sender.Write("Target is not a room and is not in a room!\n");
                    return;
                }
            }

            var leaveContextMessage = new ContextualString(sender.Thing, sender.Thing.Parent)
            {
                ToOriginator = null,
                ToReceiver = @"$ActiveThing.Name disappears into nothingness.",
                ToOthers = @"$ActiveThing.Name disappears into nothingness.",
            };
            var arriveContextMessage = new ContextualString(sender.Thing, targetPlace)
            {
                ToOriginator = "You teleport to " + targetPlace.Name + ".",
                ToReceiver = @"$ActiveThing.Name appears from nothingness.",
                ToOthers = @"$ActiveThing.Name appears from nothingness.",
            };
            var leaveMessage = new SensoryMessage(SensoryType.Sight, 100, leaveContextMessage);
            var arriveMessage = new SensoryMessage(SensoryType.Sight, 100, arriveContextMessage);

            // If we successfully move (IE the move may get cancelled if the user doesn't have permission
            // to enter a particular location, some other behavior cancels it, etc), then perform a 'look'
            // command to get immediate feedback about the new location.
            // @@@ TODO: This should not 'enqueue' a command since, should the player have a bunch of
            //     other commands entered, the 'look' feedback will not immediately accompany the 'goto'
            //     command results like it should.
            var movableBehavior = sender.Thing.FindBehavior<MovableBehavior>();

            if (movableBehavior != null && movableBehavior.Move(targetPlace, sender.Thing, leaveMessage, arriveMessage))
            {
                CommandManager.Instance.EnqueueAction(new ActionInput("look", sender));
            }
        }
예제 #22
0
파일: Who.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            string div = string.Empty;
            string mudName = MudEngineAttributes.Instance.MudName;
            string mudNameLine = "                                ";
            string plural = string.Empty;
            string plural1 = string.Empty;
            StringBuilder sb = new StringBuilder();

            plural1 = "is";

            if (PlayerManager.Instance.Players.Count > 1)
            {
                plural = "s";
                plural1 = "are";
            }

            // TODO: Version, Sort and add by guild/class
            // div = "<%b%><%green%>" + string.Empty.PadLeft(sender.Entity.Terminal.Width, '~') + "<%n%>";
            div = "<%b%><%green%>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<%n%>";
            mudNameLine += mudName;
            sb.AppendLine();
            sb.AppendLine(div);
            sb.AppendLine(mudNameLine);
            sb.AppendLine(div);
            sb.AppendLine();
            sb.AppendLine("The following player" + plural + " " + plural1 + " currently online:");
            foreach (PlayerBehavior player in PlayerManager.Instance.Players)
            {
                // TODO: I used string literal to handle "" issue is there a neater approach?
                sb.AppendFormat(@"<%mxpsecureline%><send ""finger {0}|tell {0}"" ""|finger|tell"">{0}</send>", player.Parent.Name);
                sb.AppendFormat(" - {0}", player.Parent.Name);

                // Add in AFK message
                if (player.IsAFK)
                {
                    sb.Append(" (afk");

                    if (!string.IsNullOrEmpty(player.AFKReason))
                    {
                        sb.AppendFormat(": {0}", player.AFKReason);
                    }

                    sb.Append(")");
                }

                // End with a newline char
                sb.Append("<%nl%>");
            }

            sb.AppendLine();
            sb.AppendLine(div);
            sb.AppendFormat("Counted {0} player{1} online.", PlayerManager.Instance.Players.Count, plural);
            sb.AppendLine();
            sb.AppendLine(div);
            actionInput.Controller.Write(sb.ToString().TrimEnd(null));
        }
예제 #23
0
파일: Jump.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            Die die = DiceService.Instance.GetDie(3);

            // This is how you send text back to the player
            int height = die.Roll();
            sender.Write("Congrats!  You've jumped " + height + " feet!  You're special boy!  This is for testing, so George quits punching me back.");
        }
예제 #24
0
파일: Time.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            return null;
        }
예제 #25
0
파일: Time.cs 프로젝트: Hobbitron/WheelMUD
 /// <summary>Executes the command.</summary>
 /// <param name="actionInput">The full input specified for executing the command.</param>
 public override void Execute(ActionInput actionInput)
 {
     IController sender = actionInput.Controller;
     StringBuilder sb = new StringBuilder();
     sb.Append("Game time is: ");
        // @@@ Broken: sb.AppendLine(bridge.World.TimeSystem.Now);
     sb.Append("Real world server time is: ");
     sb.AppendLine(DateTime.Now.ToString());
     sender.Write(sb.ToString());
 }
예제 #26
0
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            // There are currently no arguments nor situations where we expect failure.
            return null;
        }
예제 #27
0
파일: Say.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Checks against the guards for the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        /// <returns>A string with the error message for the user upon guard failure, else null.</returns>
        public override string Guards(ActionInput actionInput)
        {
            string commonFailure = VerifyCommonGuards(actionInput, ActionGuards);
            if (commonFailure != null)
            {
                return commonFailure;
            }

            this.sayText = actionInput.Tail.Trim();
            return null;
        }
예제 #28
0
파일: Blind.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            /* @@@ Add an AltersSensesEffect or whatnot instead of modifying permanent senses!
            if (sender.Thing.Senses.Contains(SensoryType.Sight))
            {
                sender.Thing.Senses[SensoryType.Sight].Enabled = false;
            }

            sender.Write("You blind yourself");
            */
        }
예제 #29
0
파일: Web.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            ////target.Effects.AddEffect(new StatEffect("mobility", -2, "", "Your mobility increases"),
            ////                         new TimeSpan(0, 1, 0, 0));
            ////sender.Thing.Effects.AddEffect(new Unbalance(), new TimeSpan(0, 0, 3));

            // @@@ TODO: Should use Request and Event pattern and avoid direct Controller.Writes
            //var userControlledBehavior = sender.Thing.BehaviorManager.FindFirst<UserControlledBehavior>();
            //userControlledBehavior.Controller.Write("You cast a web over " + this.target.Name);
            //this.target.Controller.Write(sender.Thing.Name + " casts a web over you");
        }
예제 #30
0
파일: Yell.cs 프로젝트: Hobbitron/WheelMUD
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            IController sender = actionInput.Controller;
            Thing parent = sender.Thing.Parent;

            // This is to keep track of the previous rooms we've yelled at, to prevent echoes.
            List<Thing> previousRooms = new List<Thing>();

            this.CreateYellEvent(sender.Thing);
            this.TraverseRoom(parent, actionInput, sender, this.RoomFallOff, previousRooms);
        }
예제 #31
0
        /// <summary>Creates a scripting command from action input.</summary>
        /// <param name="actionInput">The action input to transform into a ScriptingCommand instance.</param>
        /// <returns>A new ScriptingCommand instance for the specified input, if found, else null.</returns>
        public ScriptingCommand Create(ActionInput actionInput)
        {
            // TODO: Build targeting into command selection when there are multiple valid targets; IE if multiple
            //     openable things registered an "open" context command, then if the user said "open door" then we
            //     want to select the context command attached to the closest match for "door" as our command; if
            //     there are still multiple targets, we can start a conflict resolution prompt, etc.  Individual non-
            //     context commands may also wish to use such targeting code, so it should be built to be reusable.
            ScriptingCommand command = TryCreateMasterCommand(actionInput, 0) ??
                                       TryCreateMasterCommand(actionInput, 1) ??
                                       TryCreateContextCommand(actionInput, 0) ??
                                       TryCreateContextCommand(actionInput, 1);

            if (command == null)
            {
                actionInput.Controller.Write(new OutputBuilder().AppendLine(unknownCommandResponse));
            }

            return(command);
        }
예제 #32
0
        private ScriptingCommand TryCreateMasterCommand(ActionInput actionInput, int lastKeywordIndex)
        {
            string commandAlias = GetCommandAlias(actionInput, lastKeywordIndex);

            // If this isn't actually a command, bail now.
            ////if (string.IsNullOrEmpty(commandAlias) || !this.masterCommandList.ContainsKey(commandAlias))
            if (string.IsNullOrEmpty(commandAlias) || !CommandManager.Instance.MasterCommandList.ContainsKey(commandAlias))
            {
                return(null);
            }

            // Create a new instance of the specified GameAction.
            Command command       = CommandManager.Instance.MasterCommandList[commandAlias];
            var     commandScript = (GameAction)command.Constructor.Invoke(null);

            // Track the execute and guards delegates of this instance for calling soon, with the user's input.
            var executeDelegate = new CommandScriptExecuteDelegate(commandScript.Execute);
            var guardsDelegate  = new CommandScriptGuardsDelegate(commandScript.Guards);

            return(new ScriptingCommand(command.Name, executeDelegate, guardsDelegate, command.SecurityRole, actionInput));
        }
예제 #33
0
        private ScriptingCommand TryCreateContextCommand(ActionInput actionInput, int lastKeywordIndex)
        {
            string commandAlias = GetCommandAlias(actionInput, lastKeywordIndex);

            if (string.IsNullOrEmpty(commandAlias))
            {
                return(null);
            }

            // Find the first valid command of this name and of applicable context, if any.
            Thing sender         = actionInput.Controller.Thing;
            var   contextCommand = CommandManager.Instance.GetContextCommands(sender, commandAlias).FirstOrDefault();

            if (contextCommand == null)
            {
                return(null);
            }

            var executeDelegate = new CommandScriptExecuteDelegate(contextCommand.CommandScript.Execute);
            var guardsDelegate  = new CommandScriptGuardsDelegate(contextCommand.CommandScript.Guards);

            return(new ScriptingCommand(contextCommand.CommandKey, executeDelegate, guardsDelegate, SecurityRole.all, actionInput));
        }
예제 #34
0
        /// <summary>Try to execute the specified action input as a command.</summary>
        /// <param name="actionInput">The action input to try to execute.</param>
        private void TryExecuteAction(ActionInput actionInput)
        {
            try
            {
                ScriptingCommand command = CommandCreator.Instance.Create(actionInput);
                if (command == null)
                {
                    return;
                }

                // Verify the user has permissions to use this command.
                string guardsErrorMessage = CommandGuardHelpers.VerifyCommandPermission(command);
                if (guardsErrorMessage == null)
                {
                    guardsErrorMessage = (string)command.GuardsDelegate.DynamicInvoke(actionInput);
                }

                // Verify that the other command-specific guards are passed.
                if (guardsErrorMessage == null)
                {
                    // Execute the command if we passed all the guards.
                    command.ExecuteDelegate.DynamicInvoke(actionInput);
                }
                else
                {
                    // Otherwise display what went wrong to the user of the action.
                    IController controller = actionInput.Controller;
                    controller.Write(new OutputBuilder().AppendLine(guardsErrorMessage));
                }
            }
            catch (Exception ex)
            {
                // Most of our exceptions should be TargetInvocationExceptions but we're going to
                // handle them basically the same way as others, except that we only care about the
                // inner exception (what actually went wrong, since we know we're doing invokes here).
                if (ex is TargetInvocationException && ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                // In order to isolate command-specific issues, we're going to trap the exception, log
                // the details, and kill that command.  (Other commands and the game itself should be
                // able to continue through such situations.)
                // Start gathering info, but carefully to avoid causing potential further exceptions here.
                IController controller = actionInput.Controller;
#if DEBUG
                Thing  thing     = controller != null ? controller.Thing : null;
                string thingName = thing != null ? thing.Name : "[null]";
                string thingID   = thing != null?thing.Id.ToString() : "[null]";

                string fullCommand = actionInput != null ? actionInput.FullText : "[null]";
                string format      = "Exception encountered for command: {1}{0}From thing: {2} (ID: {3}){0}{4}";
                string message     = string.Format(format, Environment.NewLine, fullCommand, thingName, thingID, ex.ToDeepString());
#endif

                // If the debugger is attached, we probably want to break now in order to better debug
                // the issue closer to where it occurred; if your debugger broke here you may want to
                // look at the stack trace to see where the exception originated.
                if (Debugger.IsAttached)
                {
                    string stackTrace = ex.StackTrace;
                    Debugger.Break();
                }

                // TODO: FIX: this.host..UpdateSubSystemHost(this, message);
                if (controller != null)
                {
#if DEBUG
                    controller.Write(new OutputBuilder().AppendLine(message));
#else
                    controller.Write(new OutputBuilder().AppendLine("An error occured processing your command."));
#endif
                }
            }
        }
예제 #35
0
        /// <summary>Try to execute the specified action input as a command.</summary>
        /// <param name="actionInput">The action input to try to execute.</param>
        private void TryExecuteAction(ActionInput actionInput)
        {
            Debug.Assert(actionInput != null, "actionInput must be defined.");
            try
            {
                ScriptingCommand command = CommandCreator.Instance.Create(actionInput);
                if (command == null)
                {
                    return;
                }

                // Verify the user has permissions to use this command.
                string guardsErrorMessage = CommandGuardHelpers.VerifyCommandPermission(command);
                if (guardsErrorMessage == null)
                {
                    guardsErrorMessage = (string)command.GuardsDelegate.DynamicInvoke(actionInput);
                }

                // Verify that the other command-specific guards are passed.
                if (guardsErrorMessage == null)
                {
                    // Execute the command if we passed all the guards.
                    command.ExecuteDelegate.DynamicInvoke(actionInput);
                }
                else
                {
                    // Otherwise display what went wrong to the issuing session of this action input.
                    // (If there is no such session, such as an AI issuing a malformed action, for now this is just ignored. TODO: Send this issue to server log?)
                    actionInput.Session?.WriteLine(guardsErrorMessage);
                }
            }
            catch (Exception ex)
            {
                // Most of our exceptions should be TargetInvocationExceptions but we're going to
                // handle them basically the same way as others, except that we only care about the
                // inner exception (what actually went wrong, since we know we're doing invokes here).
                if (ex is TargetInvocationException && ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                // In order to isolate command-specific issues, we're going to trap the exception, log
                // the details, and kill that command.  (Other commands and the game itself should be
                // able to continue through such situations.)
                // Start gathering info, but carefully to avoid causing potential further exceptions here.
#if DEBUG
                // TODO: Improve action error output to always provide full details to server log and admin players.
                //       https://github.com/DavidRieman/WheelMUD/issues/136
                string thingName   = actionInput.Actor?.Name ?? "[null]";
                string thingID     = actionInput.Actor?.Id.ToString() ?? "[null]";
                string fullCommand = actionInput.FullText ?? "[null]";
                string format      = "Exception encountered for command: {1}{0}From thing: {2} (ID: {3}){0}{4}";
                string message     = string.Format(format, Environment.NewLine, fullCommand, thingName, thingID, ex.ToDeepString());
#else
                string message = "An error occurred while processing your command.";
#endif
                actionInput.Session?.WriteLine(message);

                // If the debugger is attached, we probably want to break now in order to better debug
                // the issue closer to where it occurred; if your debugger broke here you may want to
                // look at the stack trace to see where the exception originated.
                if (Debugger.IsAttached)
                {
                    string stackTrace = ex.StackTrace;
                    Debugger.Break();
                }
            }
        }
예제 #36
0
 /// <summary>Place an action on the command queue for execution.</summary>
 /// <param name="actionInput">The action input to attempt to execute.</param>
 public void ExecuteAction(ActionInput actionInput)
 {
     LastActionInput = actionInput;
     ActionReceived?.Invoke((IController)this, actionInput);
 }
예제 #37
0
 /// <summary>Executes the command.</summary>
 /// <remarks>Verify that the Guards pass first.</remarks>
 /// <param name="actionInput">The full input specified for executing the command.</param>
 public abstract void Execute(ActionInput actionInput);
예제 #38
0
 /// <summary>Execute the action.</summary>
 /// <param name="actionInput">The full input specified for executing the command.</param>
 public override void Execute(ActionInput actionInput)
 {
     // If the user invoked the context command, move them through this exit.
     exitBehavior.MoveThrough(actionInput.Controller.Thing);
 }
예제 #39
0
 /// <summary>Guards the command against incorrect usage.</summary>
 /// <param name="actionInput">The full input specified for executing the command.</param>
 /// <returns>An error message describing the failure for the user, or null if all guards pass.</returns>
 public abstract string Guards(ActionInput actionInput);
예제 #40
0
 /// <summary>Called when an action has been received, the manager can then put the action onto the queue.</summary>
 /// <param name="sender">The entity sending the action.</param>
 /// <param name="actionInput">The action input to be enqueued.</param>
 public void OnActionReceived(Thing sender, ActionInput actionInput)
 {
     CommandManager.Instance.EnqueueAction(actionInput);
 }