Пример #1
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);
            }

            int itemParam = 0;

            parent = sender.Thing.Parent;

            if (actionInput.Tail.ToLower().Contains("from"))
            {
                // Find the from keyword in the params.
                int itemMarker = 0;
                for (int i = 0; i < actionInput.Params.Length; i++)
                {
                    if (actionInput.Params[i].ToLower() == "from")
                    {
                        itemMarker = i;
                    }
                }

                // Destination container
                for (int j = itemParam; j < itemMarker; j++)
                {
                    destinationContainerName += actionInput.Params[j] + ' ';
                }

                destinationContainerName = destinationContainerName.Trim();

                // Source Container name is everything from the marker to the end.
                sourceContainerName = string.Empty;
                for (int i = itemMarker + 1; i < actionInput.Params.Length; i++)
                {
                    sourceContainerName += actionInput.Params[i] + ' ';
                }

                sourceContainerName = sourceContainerName.Trim();

                // Rule: Do we have an item matching the one specified in our inventory?
                // If not then does the room have a container with the name.
                // TODO: Fix: This Find pattern is probably broken...
                destinationContainer = sender.Thing.Children.Find(t => t.Name == destinationContainerName.ToLower());
                if (destinationContainer == null)
                {
                    destinationContainer = parent.Children.Find(t => t.Name == destinationContainerName.ToLower());
                    if (destinationContainer == null)
                    {
                        return("You cannot see " + destinationContainerName);
                    }
                }

                // Rule: Is the item specified as a container actually a container?
                this.containerBehavior = destinationContainer.Behaviors.FindFirst <ContainerBehavior>();
                if (this.containerBehavior == null)
                {
                    return(destinationContainerName + " is not able to hold things.");
                }
                else
                {
                    var holdsLiquidBehavior = destinationContainer.Behaviors.FindFirst <HoldsLiquidBehavior>();
                    if (holdsLiquidBehavior == null)
                    {
                        return(string.Format(
                                   "It does not appear that the {0} will hold liquid.",
                                   destinationContainerName));
                    }
                }

                // Rule: Is the item open?
                var openableBehavior = destinationContainer.Behaviors.FindFirst <OpensClosesBehavior>();
                if (openableBehavior != null && !openableBehavior.IsOpen)
                {
                    return(string.Format("You cannot fill the {0} as it is closed.", destinationContainerName));
                }

                // Rule: Do we have an item matching the one specified in our inventory?
                // If not then does the room have a container with the name.
                // TODO: Investigate; This search method is probably broken.
                sourceContainer = sender.Thing.Children.Find(t => t.Name == sourceContainerName.ToLower());
                if (sourceContainer == null)
                {
                    sourceContainer = parent.Children.Find(t => t.Name == sourceContainerName.ToLower());

                    if (sourceContainer == null)
                    {
                        return("You cannot see " + sourceContainerName);
                    }
                }

                // Rule: Is the item specified as a container actually a container?
                ContainerBehavior containerBehavior = sourceContainer.Behaviors.FindFirst <ContainerBehavior>();
                if (containerBehavior == null)
                {
                    return(string.Format("The {0} does not hold anything to fill the {1} with.", sourceContainerName, destinationContainerName));
                }

                // TODO: HoldsLiquidBehavior?

                // Rule: Is the item open?
                OpensClosesBehavior opensClosesBehavior = sourceContainer.Behaviors.FindFirst <OpensClosesBehavior>();
                if (!opensClosesBehavior.IsOpen)
                {
                    return(string.Format("You cannot fill from the {0} as it is closed.", sourceContainerName));
                }
            }
            else
            {
                return("You must use \"from\" to specify the source, as in, \"fill wine skin from fountain\".");
            }

            return(null);
        }
Пример #2
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)
        {
            IController sender        = actionInput.Controller;
            string      commonFailure = VerifyCommonGuards(actionInput, ActionGuards);

            if (commonFailure != null)
            {
                return(commonFailure);
            }

            // Check to see if the first word is a number.
            // @@@ Is TryParse meant to be used this way? Character analysis may be better. I worry that
            //     this might be throwing a caught exception upon each fail, which is a typical case here.
            int.TryParse(actionInput.Params[0], out this.numberToGet);

            int    itemParam = 0;
            string itemName  = string.Empty;

            // Rule: If we have to get a number of something, shunt up the positions of our other params.
            if (this.numberToGet > 0)
            {
                itemParam = 1;
            }

            // Rule: is the player using the command to get something from a container
            //       or to get something from the room?
            Thing targetParent = sender.Thing.Parent;

            if (actionInput.Tail.ToLower().Contains("from"))
            {
                // Find the from keyword in the params.
                int itemMarker = 0;
                for (int i = 0; i < actionInput.Params.Length; i++)
                {
                    if (actionInput.Params[i].ToLower() == "from")
                    {
                        itemMarker = i;
                    }
                }

                // Item name is everything from number (if present) to the from marker.
                for (int j = itemParam; j < itemMarker; j++)
                {
                    itemName += actionInput.Params[j] + ' ';
                }

                itemName = itemName.Trim();

                // Container name is everything from the marker to the end.
                string targetFromName = string.Empty;
                for (int i = itemMarker + 1; i < actionInput.Params.Length; i++)
                {
                    targetFromName += actionInput.Params[i] + ' ';
                }

                targetFromName = targetFromName.Trim();

                // Rule: Do we have an item matching the one specified in our inventory?
                // If not then does the room have a container with the name.
                Thing foundContainer = sender.Thing.FindChild(targetFromName.ToLower());
                if (foundContainer == null)
                {
                    foundContainer = targetParent.FindChild(targetFromName.ToLower());

                    if (foundContainer == null)
                    {
                        return(string.Format("You cannot see {0}.", targetFromName));
                    }
                }

                // Rule: Is the 'from' thing specified as a container actually a container?
                ContainerBehavior containerBehavior = foundContainer.Behaviors.FindFirst <ContainerBehavior>();
                if (containerBehavior == null)
                {
                    return(string.Format("{0} is not able to hold {1}.", foundContainer.Name, itemName));
                }

                // @@@ Removed OpensClosesBehavior check here... Test to ensure that 'get' is blocked by the
                //     OpensClosesBehavior receiving and cancelling the relevant events and message is good...

                targetParent = foundContainer;
            }
            else
            {
                // From the room.
                // Item name is everything from number (if present) to the from marker.
                for (int j = itemParam; j < actionInput.Params.Length; j++)
                {
                    itemName += actionInput.Params[j] + ' ';
                }

                itemName = itemName.Trim();
            }

            // Rule: Do we have an item matching in the container?
            this.thingToGet = targetParent.FindChild(itemName.ToLower());
            if (this.thingToGet == null)
            {
                return(string.Format("{0} does not contain {1}.", targetParent.Name, itemName));
            }

            // Rule: The targeted thing must be movable.
            this.movableBehavior = this.thingToGet.Behaviors.FindFirst <MovableBehavior>();
            if (this.movableBehavior == null)
            {
                return(this.thingToGet.Name + " does not appear to be movable.");
            }

            // @@@ TODO: Rule: Is the thing allowed to be picked up? (CannotPickUpBehavior or needs CarryableBehavior or whatnot? hmm)

            return(null);
        }
Пример #3
0
        public static (int X, int Y, Vector Direction) NextPosition(double milliseconds, Rectangle bounds, ContainerBehavior containerBehaviour, Vector direction, int x, int y)
        {
            x = (int)Math.Round((double)x + (milliseconds / 10) * direction.X);
            y = (int)Math.Round((double)y + (milliseconds / 10) * direction.Y);

            switch (containerBehaviour)
            {
            case ContainerBehavior.BOUNCE:
                if (x < 0 || x > bounds.X)
                {
                    direction = new Vector(-direction.X, direction.Y);
                }
                if (y < 0 || y > bounds.Y)
                {
                    direction = new Vector(direction.X, -direction.Y);
                }
                break;

            case ContainerBehavior.STICK:
                direction = new Vector(0, 0);
                break;

            case ContainerBehavior.WRAP:
                if (x < 0)
                {
                    x = 1000;
                }
                if (y > bounds.X)
                {
                    x = 0;
                }
                if (y < 0)
                {
                    y = 1000;
                }
                if (y > bounds.Y)
                {
                    y = 0;
                }
                break;
            }

            return(x, y, direction);
        }
Пример #4
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);
            }

            // Break out the specified parameters into their theoretical meaning.
            string sourceContainerName   = actionInput.Params[0];
            string destinationParentName = null;

            if (actionInput.Params.Length > 1)
            {
                // TODO: Maybe action input should have a means of automatically stripping words like this or "the" etc?
                if (actionInput.Params.Length > 2 &&
                    (actionInput.Params[1].Equals("into", StringComparison.CurrentCultureIgnoreCase) ||
                     actionInput.Params[1].Equals("onto", StringComparison.CurrentCultureIgnoreCase)))
                {
                    destinationParentName = actionInput.Params[2];
                }
                else
                {
                    destinationParentName = actionInput.Params[1];
                }
            }

            // Rule: The target must be an item in the command sender's inventory.
            Thing thing = sender.Thing.Children.Find(t => t.Name.Equals(sourceContainerName, StringComparison.CurrentCultureIgnoreCase));

            if (thing == null)
            {
                return(string.Format("You do not hold {0}.", sourceContainerName));
            }

            // Rule: The targeted thing must be a container of some sort.
            ContainerBehavior containerBehavior = thing.Behaviors.FindFirst <ContainerBehavior>();

            if (containerBehavior == null)
            {
                return(string.Format("The {0} is not a container.", thing.Name));
            }

            // Rule: The targeted container must not be empty already.
            sourceContainer = thing;
            if (sourceContainer.Children.Count == 0)
            {
                return(string.Format("The {0} is already empty.", sourceContainer.Name));
            }

            // TODO: Test; Not possible? If so, default to the current container's parent instead of failing?
            Debug.Assert(!string.IsNullOrEmpty(destinationParentName));

            if (destinationParentName.Equals("ground", StringComparison.CurrentCultureIgnoreCase) ||
                destinationParentName.Equals("out", StringComparison.CurrentCultureIgnoreCase))
            {
                // TODO: Test, this may be broken...
                destinationParent = sender.Thing.Parent;
            }
            else
            {
                // TODO: Allow targeting of containers in same place, like chests and whatnot?
                Thing destinationThing = sender.Thing.Children.Find(t => t.Name == destinationParentName.ToLower());
                if (destinationThing == null)
                {
                    return(string.Format("You do not hold {0}.", destinationParentName));
                }

                containerBehavior = thing.Behaviors.FindFirst <ContainerBehavior>();
                if (containerBehavior == null)
                {
                    return(string.Format("{0} is not a container.", destinationParentName));
                }

                destinationParent = thing.Parent;
            }

            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)
        {
            var commonFailure = VerifyCommonGuards(actionInput, ActionGuards);

            if (commonFailure != null)
            {
                return(commonFailure);
            }

            var itemParam = 0;

            parent = actionInput.Controller.Thing.Parent;

            if (actionInput.Tail.ToLower().Contains("from"))
            {
                // Find the from keyword in the params.
                var itemMarker = 0;
                for (var i = 0; i < actionInput.Params.Length; i++)
                {
                    if (actionInput.Params[i].ToLower() == "from")
                    {
                        itemMarker = i;
                    }
                }

                // Destination container
                for (var j = itemParam; j < itemMarker; j++)
                {
                    destinationContainerName += actionInput.Params[j] + ' ';
                }

                destinationContainerName = destinationContainerName.Trim();

                // Source Container name is everything from the marker to the end.
                sourceContainerName = string.Empty;
                for (var i = itemMarker + 1; i < actionInput.Params.Length; i++)
                {
                    sourceContainerName += actionInput.Params[i] + ' ';
                }

                sourceContainerName = sourceContainerName.Trim();

                // Rule: Do we have an item matching the one specified in our inventory?
                // If not then does the room have a container with the name.
                // TODO: Fix: This Find pattern is probably broken...
                destinationContainer = actionInput.Controller.Thing.Children.Find(t => t.Name == destinationContainerName.ToLower());
                if (destinationContainer == null)
                {
                    destinationContainer = parent.Children.Find(t => t.Name == destinationContainerName.ToLower());
                    if (destinationContainer == null)
                    {
                        return($"You cannot see {destinationContainerName}.");
                    }
                }

                // Rule: Is the item specified as a container actually a container?
                this.containerBehavior = destinationContainer.Behaviors.FindFirst <ContainerBehavior>();
                if (this.containerBehavior == null)
                {
                    return($"{destinationContainerName} is not able to hold things.");
                }

                var holdsLiquidBehavior = destinationContainer.Behaviors.FindFirst <HoldsLiquidBehavior>();
                if (holdsLiquidBehavior == null)
                {
                    return($"It does not appear that the {destinationContainerName} will hold liquid.");
                }

                // Rule: Is the item open?
                var openableBehavior = destinationContainer.Behaviors.FindFirst <OpensClosesBehavior>();
                if (openableBehavior is { IsOpen : false })