public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <objectToLungeAt>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // Get the object to lunge at
            World.GameObject objectToLungeAt = server.world.FindFirstGameObject(givenArguments[1], sender.position);

            /*
             * // Make sure there is an object to lunge at
             * if(objectToLungeAt == null)
             * {
             *  RPCs.RPCSay rPC = new RPCs.RPCSay();
             *  rPC.arguments.Add(response);
             *  server.SendRPC(rPC, nameOfSender);
             * }*/
            // The message we're going to send back
            string response = "You lunge at ";

            // If the sender is already standing, change the response accordingly
            if (sender.specialProperties["stance"] == World.Creature.StanceToString(World.Creature.Stances.STANDING))
            {
                response = "You are already standing.";
            }
            // Otherwise, if you aren't in a stance that can transition
            else if (!World.Creature.CheckStanceTransition(World.Creature.StringToStance(sender.specialProperties["stance"]), World.Creature.Stances.STANDING))
            {
                response = "You can't stand while " + sender.specialProperties["stance"].ToLower() + ".";
            }
            // Send info back to the sender
            RPCs.RPCSay rPC = new RPCs.RPCSay();
            rPC.arguments.Add(response);
            server.SendRPC(rPC, nameOfSender);
            // If we actually were able to perform the action
            if (response == "You stand up.")
            {
                // Change the stance of the sender
                sender.specialProperties["stance"] = World.Creature.StanceToString(World.Creature.Stances.STANDING);
                // Notify everyone in the chunk
                foreach (World.GameObject gameObject in server.world.GetChunkOrGenerate(sender.position).children)
                {
                    if (gameObject.specialProperties.ContainsKey("isPlayer") && gameObject.identifier.name != sender.identifier.name)
                    {
                        // Send a message to this player saying that we left the chunk
                        RPCs.RPCSay newRPC = new RPCs.RPCSay();
                        newRPC.arguments.Add(nameOfSender + " stood up.");
                        server.SendRPC(newRPC, gameObject.identifier.name);
                    }
                }
            }
        }
Exemplo n.º 2
0
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <nameOfObjectToExamine>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // The gameObject that we will be examined
            World.GameObject gameObjectToExamine = server.world.FindFirstGameObject(givenArguments[0], sender.position);

            #region Find all the children of the ObjectToExamine and describe them

            string descriptionOfGameObject = "";

            // Make room for the children sorted by type
            Dictionary <Type, List <World.GameObject> > childrenSortedByType = new Dictionary <Type, List <World.GameObject> >();
            foreach (World.GameObject child in gameObjectToExamine.children)
            {
                // If the dictionary dose not have the child type then make a new type
                if (!childrenSortedByType.ContainsKey(child.type))
                {
                    childrenSortedByType.Add(child.type, new List <World.GameObject>());
                }
                childrenSortedByType[child.type].Add(child);
            }

            RPCs.RPCSay response = new RPCs.RPCSay();
            response.arguments.Add(descriptionOfGameObject);
            server.SendRPC(response, nameOfSender);
            // Let everyone else in the chunk know that this player dropped something
            RPCs.RPCSay information = new RPCs.RPCSay();
            information.arguments.Add(nameOfSender + " examined " + Processing.Describer.GetArticle(gameObjectToExamine.identifier.fullName) + " " + gameObjectToExamine.identifier.fullName + ".");
            // Find everyone in the same chunk and let them know
            foreach (KeyValuePair <string, Core.Player> playerEntry in server.world.players)
            {
                // If this player is not the one that picked something up, and it's position is the same as the original player's position
                if (playerEntry.Key != nameOfSender && playerEntry.Value.controlledGameObject.position == sender.position)
                {
                    // Send an informational RPC to them letting them know
                    server.SendRPC(information, playerEntry.Key);
                }
            }
            #endregion
        }
Exemplo n.º 3
0
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <nameOfObjectToDull> <nameOfObjectToDullWith>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // Get the object to dull
            World.GameObject objectToDull = server.world.FindFirstGameObject(givenArguments[0], sender.position);
            // Get the object to dull with
            World.GameObject objectToDullWith = server.world.FindFirstGameObject(givenArguments[1], sender.position);

            // Make sure both the objects exist
            if (objectToDull == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("There is no nearby " + givenArguments[0] + ".");
                server.SendRPC(error, nameOfSender);
                return;
            }
            if (objectToDullWith == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("There is no nearby " + givenArguments[1] + ".");
                server.SendRPC(error, nameOfSender);
                return;
            }
            // Check if the object to dull with can be used
            if (!objectToDullWith.specialProperties.ContainsKey("canBeDulledWith") || objectToDull == objectToDullWith)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("You can't use the " + objectToDullWith.identifier.fullName + " to dull the " + objectToDull.identifier.fullName + ".");
                server.SendRPC(error, nameOfSender);
                return;
            }

            // Tell the player in the present tense that they are completing the action
            string presentTenseConfirmationString = "You are dulling " + Processing.Describer.GetArticle(objectToDull.identifier.fullName) + " " + objectToDull.identifier.fullName + "...";

            RPCs.RPCSay presentTenseConfirmation = new RPCs.RPCSay();
            presentTenseConfirmation.arguments.Add(presentTenseConfirmationString);
            server.SendRPC(presentTenseConfirmation, nameOfSender);
            // Loop the elipsis three times and send it to the player, implying work being done
            for (int i = 0; i < 5000 / 1000; i++)
            {
                Thread.Sleep(1000);
                RPCs.RPCSay elipsis = new RPCs.RPCSay();
                elipsis.arguments.Add("...");
                server.SendRPC(elipsis, nameOfSender);
            }

            // Make the object dull
            objectToDull.identifier.descriptiveAdjectives.Add("blunt");
            // If the object was sharp make shure its not
            if (objectToDull.identifier.descriptiveAdjectives.Contains("sharp"))
            {
                objectToDull.identifier.descriptiveAdjectives.Remove("sharp");
            }

            // Confirm to the sender that they dulled the object
            RPCs.RPCSay confirmation = new RPCs.RPCSay();
            confirmation.arguments.Add("You dulled the " + objectToDull.identifier.fullName + " with the " + objectToDullWith.identifier.fullName + ".");
            server.SendRPC(confirmation, nameOfSender);
            // Let everyone else in the chunk know that this player dulled something
            RPCs.RPCSay information = new RPCs.RPCSay();
            information.arguments.Add(nameOfSender + " sharpened a " + objectToDull.identifier.fullName + " with a " + objectToDullWith.identifier.fullName + ".");
            // Find everyone in the same chunk and let them know
            foreach (KeyValuePair <string, Core.Player> playerEntry in server.world.players)
            {
                // If this player is not the one that picked something up, and it's position is the same as the original player's position
                if (playerEntry.Key != nameOfSender && playerEntry.Value.controlledGameObject.position == sender.position)
                {
                    // Send an informational RPC to them letting them know
                    server.SendRPC(information, playerEntry.Key);
                }
            }
        }
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <nameOfObject> <nameOfContainer>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // The object itself
            World.GameObject objectToPut = server.world.FindFirstGameObject(givenArguments[0], sender.position);
            // The container to put the object into
            World.GameObject containerToPutInto = server.world.FindFirstGameObject(givenArguments[1], sender.position);

            #region Make sure the objects exist
            // First off, make sure the crafting recipe exists
            if (containerToPutInto == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("The " + givenArguments[1] + " is not nearby.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            else if (objectToPut == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("The " + givenArguments[0] + " is not nearby.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            #endregion

            #region Make sure the container really is a container
            if (!containerToPutInto.specialProperties.ContainsKey("isContainer"))
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("The " + givenArguments[1] + " is not a container.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            #endregion

            #region Make sure the object can really be put in the container
            if (objectToPut.parent.type == typeof(World.Plants.PlantRope))
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("The " + givenArguments[1] + " is attached to something.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            else if (objectToPut.parent == containerToPutInto)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("The " + givenArguments[1] + " is already inside the " + containerToPutInto.identifier.fullName + ".");
                server.SendRPC(error, nameOfSender);
                return;
            }
            else if (objectToPut == containerToPutInto)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("You can't put the " + givenArguments[1] + " inside itself!.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            #endregion

            #region Put the object inside the container
            // Add it as a child
            containerToPutInto.AddChild(objectToPut);
            #endregion

            #region Confirm that the object was put into the container
            // Confirm to the sender that they crafted the object
            RPCs.RPCSay confirmation = new RPCs.RPCSay();
            confirmation.arguments.Add("You put " + Processing.Describer.GetArticle(objectToPut.identifier.fullName) + " " + objectToPut.identifier.fullName + " into  " + Processing.Describer.GetArticle(containerToPutInto.identifier.fullName) + " " + containerToPutInto.identifier.fullName + ".");
            // Let everyone else in the chunk know that this player crafted something
            RPCs.RPCSay information = new RPCs.RPCSay();
            information.arguments.Add(nameOfSender + " put " + Processing.Describer.GetArticle(objectToPut.identifier.fullName) + " " + objectToPut.identifier.fullName + " into  " + Processing.Describer.GetArticle(containerToPutInto.identifier.fullName) + " " + containerToPutInto.identifier.fullName + ".");
            // Send the RPCs out
            server.SendRPC(confirmation, nameOfSender);
            server.SendRPC(information, sender.position, new List <string>()
            {
                nameOfSender
            });
            #endregion
        }
Exemplo n.º 5
0
        // Returns a description of the given GameObject
        public static string Describe(World.Chunk chunkToDescribe, World.GameObject objectRecievingDescription)
        {
            // The description to return
            string description = "\n\n";
            // The random generator
            Random random = new Random();

            #region Describe the biome
            // Describe the biome with a little variation
            if (random.Next(0, 1) == 0)
            {
                description += "You are surrounded by ";
            }
            else
            {
                description += "You are in ";
            }
            // If the biome is plural
            if (chunkToDescribe.biome.name[(chunkToDescribe.biome.name.Length == 0) ? 0 : chunkToDescribe.biome.name.Length - 1] == 's')
            {
                description += "some ";
            }
            // Update log of info stream
            //Logs.biomeName = GetArticle(chunkToDescribe.biome.name);
            description += GetArticle(chunkToDescribe.biome.name) + " ";
            description += ToColor(chunkToDescribe.biome.name, chunkToDescribe.biome.associatedColor);
            description += ". ";

            #endregion

            #region Describe the weather
            // Describe the wind speed
            if (chunkToDescribe.windSpeed < 5)
            {
                description += "\nThe air is very still. ";
            }
            else if (chunkToDescribe.windSpeed < 20)
            {
                description += "\nThe wind is blowing gently. ";
            }
            else if (chunkToDescribe.windSpeed < 40)
            {
                description += "\nThe wind is $jablowing $jaharshly. ";
            }
            else
            {
                description += "\nThe wind is $jahowling $jauncontrollably. ";
            }
            // Describe the temperature
            if (chunkToDescribe.temperature < 20)
            {
                description += "\nThe temperature is $lavery $lacold. ";
            }
            else if (chunkToDescribe.temperature < 40)
            {
                description += "\nThe temperature is $lacold. ";
            }
            else if (chunkToDescribe.temperature < 60)
            {
                description += "\nThe temperature is mildly cold. ";
            }
            else if (chunkToDescribe.temperature < 80)
            {
                description += "\nThe temperature is $gawarm. ";
            }
            else if (chunkToDescribe.temperature < 100)
            {
                description += "\nThe temperature is $gahot. ";
            }
            else
            {
                description += "\nThe temperature is $eavery $eahot. ";
            }
            #endregion

            #region Describe the surrounding areas of land

            #endregion

            #region Describe the GameObjects
            // Tack on some new line characters
            description += "\n\n";

            #region Get all visible objects

            #endregion

            #region Sort by importance level
            // Get all the gameObjects on the chunk
            List <World.GameObject> allGameObjectsOnChunk = chunkToDescribe.GetAllChildren();
            // The list of all gameObjects on the chunk sorted by importance level
            Dictionary <int, List <World.GameObject> > allGameObjectsOnChunkSortedByImportanceLevel = new Dictionary <int, List <World.GameObject> >();
            // Loop through all the gameObjects on the chunk, sorting by importance level
            foreach (World.GameObject gameObject in allGameObjectsOnChunk)
            {
                // If the list doesn't have the key, allocate a new list in the slot in the dictionary
                if (!allGameObjectsOnChunkSortedByImportanceLevel.ContainsKey(gameObject.importanceLevel))
                {
                    allGameObjectsOnChunkSortedByImportanceLevel.Add(gameObject.importanceLevel, new List <World.GameObject>());
                }
                // Once we know the slot is allocated, add the game object to the slot
                allGameObjectsOnChunkSortedByImportanceLevel[gameObject.importanceLevel].Add(gameObject);
            }
            #endregion

            #region Sort by type and amount of each object
            // The list of the different types of objects, used for determining how to output them
            Dictionary <Type, int> amountOfEachObject = new Dictionary <Type, int>();
            // The dictionary of the first of each of the gameObjects
            List <World.GameObject> firstOfEachGameObject = new List <World.GameObject>();
            // Describe the players first
            foreach (World.GameObject gameObject in chunkToDescribe.children)
            {
                // If this object is a player, describe it
                if (gameObject.specialProperties.ContainsKey("isPlayer"))
                {
                    if (gameObject.identifier.name != objectRecievingDescription.identifier.name)
                    {
                        description += gameObject.identifier.name + " is nearby.\n";
                    }
                }
                // If the dictionary does not contain the given type yet, add it
                else if (!amountOfEachObject.ContainsKey(gameObject.type))
                {
                    amountOfEachObject.Add(gameObject.type, 1);
                    firstOfEachGameObject.Add(gameObject);
                }
                else
                {
                    amountOfEachObject[gameObject.type]++;
                }
            }
            // Loop through again and add to the description according to how many there are
            foreach (World.GameObject gameObject in firstOfEachGameObject)
            {
                // The subject of the sentence we are creating
                string subject = "";
                // The verb phrase
                string verbPhrase = "";
                // The prepositional phrase tacked on at the end
                string prepositionalPhrase = "";
                // If there is only one of this type of object, print accordingly
                if (amountOfEachObject[gameObject.type] == 1)
                {
                    subject             = "There";
                    verbPhrase          = "is";
                    prepositionalPhrase = "a nearby " + ToColor(gameObject.identifier.fullName, gameObject.specialProperties.ContainsKey("colorAdd") ? gameObject.specialProperties["colorAdd"] : "");
                }
                // If there are relativly few, print accordingly
                else if (amountOfEachObject[gameObject.type] <= 10)
                {
                    subject             = "There";
                    verbPhrase          = "are";
                    prepositionalPhrase = "some nearby " + ToColor(gameObject.identifier.fullName.Pluralize(), gameObject.specialProperties.ContainsKey("colorAdd") ? gameObject.specialProperties["colorAdd"] : "");

                    /*
                     * // If the word ends in "s", add an "es" to the end
                     * if (gameObject.identifier.name[(gameObject.identifier.name.Length == 0) ? 0 : gameObject.identifier.name.Length - 1] == 's')
                     *  prepositionalPhrase = "some nearby " + ToColor(gameObject.identifier.fullName, gameObject.specialProperties.ContainsKey("colorAdd") ? gameObject.specialProperties["colorAdd"] : "") + "es";
                     * else
                     *  prepositionalPhrase = "some nearby " + ToColor(gameObject.identifier.fullName, gameObject.specialProperties.ContainsKey("colorAdd") ? gameObject.specialProperties["colorAdd"] : "") + "s";
                     */
                }
                // If there are a lot, print accordingly
                else
                {
                    subject             = "There";
                    verbPhrase          = "are many nearby";
                    prepositionalPhrase = ToColor(gameObject.identifier.fullName.Pluralize(), gameObject.specialProperties.ContainsKey("colorAdd") ? gameObject.specialProperties["colorAdd"] : "");

                    /*
                     * // If the word ends in "s", don't change it to plural
                     * if (gameObject.identifier.name[(gameObject.identifier.name.Length == 0) ? 0 : gameObject.identifier.name.Length - 1] == 's')
                     *  prepositionalPhrase = ToColor(gameObject.identifier.fullName, gameObject.specialProperties.ContainsKey("colorAdd") ? gameObject.specialProperties["colorAdd"] : "");
                     * else
                     *  prepositionalPhrase = ToColor(gameObject.identifier.fullName, gameObject.specialProperties.ContainsKey("colorAdd") ? gameObject.specialProperties["colorAdd"] : "") + "s";
                     */
                }
                // Build the description
                description += subject + " " + verbPhrase + " " + prepositionalPhrase + ". \n";
            }
            #endregion

            #endregion

            // Update log chunk
            logChunk = chunkToDescribe;

            return(description);
        }
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <nameOfObjectToApproach>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }
            // Find the gameObject we are going to approach

            // Check if name is a player's name
            World.GameObject gameObjectToApproach = null;
            foreach (World.GameObject gameObject in server.world.GetChunk(sender.position).children)
            {
                if (gameObject.specialProperties.ContainsKey("isPlayer") && gameObject.identifier.name != sender.identifier.name && gameObject.identifier.name == givenArguments[0])
                {
                    // Send a message to this player saying that we left the chunk
                    gameObjectToApproach = gameObject;
                }
            }
            // If not a player, find the first object with the name
            if (gameObjectToApproach == null)
            {
                List <World.GameObject> listOfPotentialObjects = server.world.GetChunkOrGenerate(sender.position).FindChildrenWithName(givenArguments[0]);
                if (listOfPotentialObjects.Count > 0)
                {
                    gameObjectToApproach = listOfPotentialObjects.First();
                }
            }

            // If no gameObject was found, send back an error
            if (gameObjectToApproach == null)
            {
                // If this fails, let the player know
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("There is no nearby " + givenArguments[0] + ".");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // Now that we have the game object we are going to approach, make sure it isn't already in our proximity
            if (sender.gameObjectsInProximity.Contains(gameObjectToApproach))
            {
                // If this fails, let the player know
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are already near the " + gameObjectToApproach.identifier.fullName + ".");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // The message we're going to send back
            string intermediateResponse = "You walk up to the " + gameObjectToApproach.identifier.fullName + "...";

            RPCs.RPCSay intermediateRPC = new RPCs.RPCSay();
            intermediateRPC.arguments.Add(intermediateResponse);
            server.SendRPC(intermediateRPC, nameOfSender);

            new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                Thread.Sleep(1000);

                // Add it to the list of object's in our proximity
                sender.gameObjectsInProximity.Add(gameObjectToApproach);
                gameObjectToApproach.gameObjectsInProximity.Add(sender);
                gameObjectToApproach.OnEnterProximity(sender);
                // Notify every, and modify the message a little if we are approaching a player
                if (gameObjectToApproach.specialProperties.ContainsKey("isPlayer"))
                {
                    server.world.SendMessageToPosition("You approached a " + gameObjectToApproach.identifier.fullName + ".", nameOfSender, nameOfSender + " approached " + gameObjectToApproach.identifier.fullName + ".", sender.position);
                }
                else
                {
                    server.world.SendMessageToPosition("You approached the " + gameObjectToApproach.identifier.fullName + ".", nameOfSender, nameOfSender + " approached " + Processing.Describer.GetArticle(gameObjectToApproach.identifier.fullName) + " " + gameObjectToApproach.identifier.fullName + ".", sender.position);
                }
            }).Start();
        }
Exemplo n.º 7
0
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <nameOfObjectToStrike> <nameOfObjectToUse> <(l)eft|(r)ight|(h)ead>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // The object to strike
            World.GameObject objectToStrike = server.world.FindFirstGameObject(givenArguments[0], sender.position);
            // The object to use
            World.GameObject objectToUse = null;

            #region Get the object to use
            // Loop through all the utilizable objects on the sender
            foreach (World.GameObject potentialObjectToUse in sender.FindChildrenWithSpecialProperty("isUtilizable"))
            {
                // If this potential object or what it's holding matches, use it
                if (potentialObjectToUse.identifier.DoesStringPartiallyMatchFullName(givenArguments[1]))
                {
                    objectToUse = potentialObjectToUse;
                    break;
                }
                // Otherwise, if this potential object's first child, the thing it's holding, matches, use it
                else if (potentialObjectToUse.children.Count > 0)
                {
                    if (potentialObjectToUse.children.First().identifier.DoesStringPartiallyMatchFullName(givenArguments[1]))
                    {
                        objectToUse = potentialObjectToUse.children.First();
                        break;
                    }
                }
            }
            #endregion

            #region Make sure the arguments are valid
            // Make sure the object to strike exists
            if (objectToStrike == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("\"" + givenArguments[0] + "\" is not nearby.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            // Make sure the object to use exists
            else if (objectToUse == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("\"" + givenArguments[1] + "\" is not something you are holding.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            // Make sure the direction to strike is valid
            else if (givenArguments[2] != "left" &&
                     givenArguments[2] != "right" &&
                     givenArguments[2] != "head" &&
                     givenArguments[2] != "l" &&
                     givenArguments[2] != "r" &&
                     givenArguments[2] != "h")
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("\"" + givenArguments[2] + "\" is not a direction to strike. Use \"left\", \"right\", or \"head\".");
                server.SendRPC(error, nameOfSender);
                return;
            }
            // Translate the short hand of the direction to block if one was used
            if (givenArguments[2] == "l")
            {
                givenArguments[2] = "left";
            }
            else if (givenArguments[2] == "r")
            {
                givenArguments[2] = "right";
            }
            else if (givenArguments[2] == "h")
            {
                givenArguments[2] = "head";
            }
            #endregion

            #region Check the stance
            if (sender.specialProperties["stance"] != "STANDING" && sender.specialProperties["stance"] != "CROUCHING")
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("You can't strike from the stance you're in.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            #endregion

            #region Check the object is in proximity
            if (!sender.gameObjectsInProximity.Contains(objectToStrike))
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("You are not close enough to the " + objectToStrike.identifier.fullName + ". You must approach it first.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            #endregion

            #region Calculate the time to wait
            // Calculate the time to wait, which is just the sender's reaction time plus the object's weight over our strength
            // reactionTime + (objectWeight/senderStrength)
            float timeToWait =
                float.Parse(sender.specialProperties["reactionTime"], CultureInfo.InvariantCulture.NumberFormat) +
                (float.Parse(objectToUse.specialProperties["weight"], CultureInfo.InvariantCulture.NumberFormat) /
                 float.Parse(sender.specialProperties["strength"], CultureInfo.InvariantCulture.NumberFormat));
            #endregion

            #region Tell everyone that the object is about to be struck
            // Create unique messages for the sender, reciever, and everyone else
            RPCs.RPCSay rpcToSender       = new RPCs.RPCSay();
            RPCs.RPCSay rpcToReciever     = new RPCs.RPCSay();
            RPCs.RPCSay rpcToEveryoneElse = new RPCs.RPCSay();
            // Build the messages to each person
            rpcToReciever.arguments.Add(nameOfSender + " is about to $mastrike your " +
                                        objectToStrike.identifier.fullName +
                                        " from the $oa" + givenArguments[2] + " with " +
                                        Processing.Describer.GetArticle(objectToUse.identifier.fullName) + " " +
                                        objectToUse.identifier.fullName + " in $oa" + timeToWait.ToString() + " seconds!");

            // Build the message back to the sender
            // If the object to strike was attached to a player, change the messages accordingly
            if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0)
            {
                rpcToSender.arguments.Add("You swing at " + objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name + "'s " + objectToStrike.identifier.fullName + " from the " + givenArguments[2] + " with your " +
                                          objectToUse.identifier.fullName + "!");

                rpcToEveryoneElse.arguments.Add(nameOfSender + " swings at " +
                                                objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name + "'s " +
                                                objectToStrike.identifier.fullName + " with " +
                                                Processing.Describer.GetArticle(objectToUse.identifier.fullName) + " " +
                                                objectToUse.identifier.fullName + "!");
            }
            else
            {
                rpcToSender.arguments.Add("You swing at the " + objectToStrike.identifier.fullName + " from the " + givenArguments[2] + " with your " +
                                          objectToUse.identifier.fullName + "!");

                rpcToEveryoneElse.arguments.Add(nameOfSender + " swings at " +
                                                Processing.Describer.GetArticle(objectToStrike.identifier.fullName) + " " +
                                                objectToStrike.identifier.fullName + " with " +
                                                Processing.Describer.GetArticle(objectToUse.identifier.fullName) + " " +
                                                objectToUse.identifier.fullName + "!");
            }
            // Send the confirmation back to the sender
            server.SendRPC(rpcToSender, nameOfSender);
            // If the object to strike was attached to a player, send a message to the reciever and ignore the sender and reciever of the strike command
            if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0)
            {
                server.SendRPC(rpcToReciever, objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name);
                server.SendRPC(rpcToEveryoneElse, sender.position, new List <string>()
                {
                    objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name,
                    nameOfSender
                });
            }
            // Otherwise, just send the message to everyone else saying we struck something
            else
            {
                server.SendRPC(rpcToEveryoneElse, sender.position, new List <string>()
                {
                    nameOfSender
                });
            }
            #endregion

            #region Wait for the appropriate amount of time based off of the sender strength and the object to use
            // TODO: Output ellipses in increments

            // Send back to the player how long it's going to take
            RPCs.RPCSay info = new RPCs.RPCSay();
            info.arguments.Add("Striking in " + timeToWait.ToString() + " seconds.");
            server.SendRPC(info, nameOfSender);
            // Sleep this thread for the time to wait
            Thread.Sleep((int)(timeToWait * 1000.0f));

            #endregion

            #region Check for blocking
            // Get the object that's being used to block, if any
            World.GameObject objectBeingUsedToBlock = null;
            // If we're hitting something that is a player
            if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0)
            {
                if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().FindChildrenWithSpecialPropertyAndValue("blocking", givenArguments[2]).Count > 0)
                {
                    // Set the object being used to block
                    objectBeingUsedToBlock = objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().FindChildrenWithSpecialPropertyAndValue("blocking", givenArguments[2]).First();
                    // Create unique messages for the sender, reciever, and everyone else
                    RPCs.RPCSay rpcToSenderForBlocking       = new RPCs.RPCSay();
                    RPCs.RPCSay rpcToRecieverForBlocking     = new RPCs.RPCSay();
                    RPCs.RPCSay rpcToEveryoneElseForBlocking = new RPCs.RPCSay();

                    // Build the messages to each person

                    // Build the message for the person recieving the block
                    rpcToSenderForBlocking.arguments.Add(objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.fullName + " blocked your " +
                                                         objectToUse.identifier.fullName + " with " +
                                                         Processing.Describer.GetArticle(objectBeingUsedToBlock.identifier.fullName) + " " +
                                                         objectBeingUsedToBlock.identifier.fullName + "!");

                    // Build the message for the sender and everyone else.  The if is to determine whether or not we hit another player.  Change the output a little if we hit another player
                    if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0)
                    {
                        rpcToRecieverForBlocking.arguments.Add("You blocked " +
                                                               nameOfSender + "'s " +
                                                               objectToUse.identifier.fullName + " with your " +
                                                               objectBeingUsedToBlock.identifier.fullName + "!");

                        rpcToEveryoneElseForBlocking.arguments.Add(objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name + " blocked " +
                                                                   nameOfSender + "'s " +
                                                                   objectToUse.identifier.fullName + " with " +
                                                                   Processing.Describer.GetArticle(objectToStrike.identifier.fullName) + " " +
                                                                   objectToStrike.identifier.fullName + "!");
                    }
                    else
                    {
                        rpcToEveryoneElseForBlocking.arguments.Add(objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name + " blocked the " +
                                                                   nameOfSender + "'s " +
                                                                   objectToUse.identifier.fullName + " with " +
                                                                   Processing.Describer.GetArticle(objectToStrike.identifier.fullName) + " " +
                                                                   objectToStrike.identifier.fullName + "!");
                    }
                    // Send the confirmation back to the sender
                    server.SendRPC(rpcToSenderForBlocking, nameOfSender);
                    // If the object to strike was attached to a player, send a message to the reciever and ignore the sender and reciever of the strike command
                    if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0)
                    {
                        server.SendRPC(rpcToRecieverForBlocking, objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name);
                        server.SendRPC(rpcToEveryoneElseForBlocking, sender.position, new List <string>()
                        {
                            objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name,
                            nameOfSender
                        });
                    }
                    // Otherwise, just send the message to everyone else saying we struck something
                    else
                    {
                        server.SendRPC(rpcToEveryoneElseForBlocking, sender.position, new List <string>()
                        {
                            nameOfSender
                        });
                    }
                    // Stop the function here
                    return;
                }
            }
            #endregion

            #region Calculate damage
            // Get the object that will actually do damage, which could be the head of an axe, or just the stick or hand
            World.GameObject objectToDoDamage = objectToUse;
            // If the object to use has children, use the bottommost child
            if (objectToUse.children.Count > 0)
            {
                objectToDoDamage = objectToUse.GetAllChildren().Last();
            }
            // Calculate the damage
            float damage = float.Parse(objectToDoDamage.specialProperties["weight"], CultureInfo.InvariantCulture.NumberFormat);

            // Calculate damage multipliers
            // If the weapon is long, do a damage multiplier
            if (objectToUse.identifier.descriptiveAdjectives.Contains("long"))
            {
                damage *= 2;
            }
            // If weapon is sharp, do damage multiplier
            if (objectToDoDamage.identifier.descriptiveAdjectives.Contains("sharp"))
            {
                damage *= 3;
            }
            #endregion

            #region Confirm to everyone that the object was struck
            // Create unique messages for the sender, reciever, and everyone else
            RPCs.RPCSay rpcToSenderForBeingStruck       = new RPCs.RPCSay();
            RPCs.RPCSay rpcToRecieverForBeingStruck     = new RPCs.RPCSay();
            RPCs.RPCSay rpcToEveryoneElseForBeingStruck = new RPCs.RPCSay();
            // Build the messages to each person
            rpcToRecieverForBeingStruck.arguments.Add(Processing.Describer.ToColor(nameOfSender + " struck your " +
                                                                                   objectToStrike.identifier.fullName + " with " +
                                                                                   Processing.Describer.GetArticle(objectToUse.identifier.fullName) + " " +
                                                                                   objectToUse.identifier.fullName + "!", "$ma"));

            // Build the message back to the sender
            // If the object to strike was attached to a player, change the messages accordingly
            if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0)
            {
                rpcToSenderForBeingStruck.arguments.Add(Processing.Describer.ToColor("You struck " + objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name + "'s " + objectToStrike.identifier.fullName + " with your " +
                                                                                     objectToUse.identifier.fullName + "!\nYou did " + damage.ToString() + " damage!", "$ka"));

                rpcToEveryoneElseForBeingStruck.arguments.Add(nameOfSender + " struck " +
                                                              objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name + "'s " +
                                                              objectToStrike.identifier.fullName + " with " +
                                                              Processing.Describer.GetArticle(objectToUse.identifier.fullName) + " " +
                                                              objectToUse.identifier.fullName + "!");
            }
            else
            {
                rpcToSenderForBeingStruck.arguments.Add("You struck the " + objectToStrike.identifier.fullName + " with your " +
                                                        objectToUse.identifier.fullName + ", dealing " + damage.ToString() + " damage!");

                rpcToEveryoneElseForBeingStruck.arguments.Add(nameOfSender + " struck " +
                                                              Processing.Describer.GetArticle(objectToStrike.identifier.fullName) + " " +
                                                              objectToStrike.identifier.fullName + " with a " +
                                                              Processing.Describer.GetArticle(objectToUse.identifier.fullName) + " " +
                                                              objectToUse.identifier.fullName + "!");
            }
            // Send the confirmation back to the sender
            server.SendRPC(rpcToSenderForBeingStruck, nameOfSender);
            // If the object to strike was attached to a player, send a message to the reciever and ignore the sender and reciever of the strike command
            if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0)
            {
                server.SendRPC(rpcToRecieverForBeingStruck, objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name);
                server.SendRPC(rpcToEveryoneElseForBeingStruck, sender.position, new List <string>()
                {
                    objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name,
                    nameOfSender
                });
            }
            // Otherwise, just send the message to everyone else saying we struck something
            else
            {
                server.SendRPC(rpcToEveryoneElseForBeingStruck, sender.position, new List <string>()
                {
                    nameOfSender
                });
            }
            #endregion

            #region Apply damage to the object

            // Call the take damage function on the object being struck
            objectToStrike.OnStrikeThisGameObjectWithGameObject(sender, objectToDoDamage, damage);

            #region Physically change the object being struck, such as knock the player over, etc

            // If it's a player, knock them over if necessary
            // If we're hitting a player
            if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0 && objectToStrike.identifier.name.Contains("leg") ||
                objectToStrike.FindParentsWithSpecialProperty("isPlayer").Count > 0 && objectToStrike.identifier.name.Contains("head"))
            {
                if (objectToStrike.FindParentsWithSpecialProperty("isPlayer").Last().specialProperties["stance"] != "LAYING")
                {
                    #region Confirm to everyone that the player has been knocked over
                    // Create unique messages for the sender, reciever, and everyone else
                    RPCs.RPCSay rpcToSenderForBeingKnocked       = new RPCs.RPCSay();
                    RPCs.RPCSay rpcToRecieverForBeingKnocked     = new RPCs.RPCSay();
                    RPCs.RPCSay rpcToEveryoneElseForBeingKnocked = new RPCs.RPCSay();

                    rpcToSenderForBeingKnocked.arguments.Add("You knocked " + objectToStrike.FindParentsWithSpecialProperty("isPlayer").Last().identifier.fullName + " over with your " + objectToUse.identifier.fullName + " from a strike to the " + objectToStrike.identifier.fullName + "!");
                    rpcToRecieverForBeingKnocked.arguments.Add(nameOfSender + " knocked you over with " + Processing.Describer.GetArticle(objectToUse.identifier.fullName) + " " + objectToUse.identifier.fullName + " from a strike to the " + objectToStrike.identifier.fullName + "!");
                    rpcToEveryoneElseForBeingKnocked.arguments.Add(nameOfSender + " knocked " + objectToStrike.FindParentsWithSpecialProperty("isPlayer").Last().identifier.fullName + " over with " + Processing.Describer.GetArticle(objectToUse.identifier.fullName) + " " + objectToUse.identifier.fullName + " from a strike to the " + objectToStrike.identifier.fullName + "!");

                    server.SendRPC(rpcToSenderForBeingKnocked, nameOfSender);
                    server.SendRPC(rpcToRecieverForBeingKnocked, objectToStrike.FindParentsWithSpecialProperty("isPlayer").Last().identifier.name);
                    server.SendRPC(rpcToEveryoneElseForBeingKnocked, sender.position, new List <string>()
                    {
                        nameOfSender, objectToStrike.FindParentsWithSpecialProperty("isPlayer").Last().identifier.name
                    });
                    #endregion

                    #region Make the person who has been knocked fall over
                    RPCs.RPCSay rpcToRecieverForFalling = new RPCs.RPCSay();
                    rpcToRecieverForFalling.arguments.Add("You are falling...");
                    server.SendRPC(rpcToRecieverForFalling, objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name);
                    // Put them in the falling stance
                    objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().specialProperties["stance"] = "FALLING";
                    new Thread(() =>
                    {
                        Thread.CurrentThread.IsBackground = true;
                        Thread.Sleep(2000);

                        RPCs.RPCSay rpcToRecieverForLaying = new RPCs.RPCSay();
                        rpcToRecieverForLaying.arguments.Add("You have fallen.");
                        server.SendRPC(rpcToRecieverForLaying, objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().identifier.name);
                        // Put them in the lying stance
                        objectToStrike.FindParentsWithSpecialProperty("isPlayer").First().specialProperties["stance"] = "LAYING";
                    }).Start();

                    #endregion
                }
            }


            #endregion

            #endregion
        }
Exemplo n.º 8
0
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <nameOfObjectToPickUp> <OPTIONAL:nameOfObjectToPickUpWith>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // Get the hashset of the utilizable parts of the player, like the hands, tail, etc
            List <World.GameObject> utilizableParts = sender.FindChildrenWithSpecialProperty("isUtilizable");

            // The gameObject that we will take the object with, which will be determined
            World.GameObject utilizablePart = null;

            #region Determine the object to take the object
            // First off, check if we even have a hand that can hold an object
            if (utilizableParts.Count == 0)
            {
                return;
            }
            // If there was a specified part we were asked to take the object with, use that
            if (givenArguments.Count == 3)
            {
                // Loop through and find the part with the name
                foreach (World.GameObject part in utilizableParts)
                {
                    if (part.identifier.DoesStringPartiallyMatchFullName(givenArguments[1]))
                    {
                        utilizablePart = part;
                        break;
                    }
                }
                // If it fails, send an appropriate message back
                if (utilizablePart == null)
                {
                    RPCs.RPCSay confirmation = new RPCs.RPCSay();
                    confirmation.arguments.Add("You have no " + givenArguments[1] + ".");
                    server.SendRPC(confirmation, nameOfSender);
                    return;
                }
                else if (utilizablePart.children.Count > 0)
                {
                    RPCs.RPCSay confirmation = new RPCs.RPCSay();
                    confirmation.arguments.Add("Your " + givenArguments[1] + " is being used.");
                    server.SendRPC(confirmation, nameOfSender);
                    return;
                }
            }
            // Otherwise
            else
            {
                // Find the first utilizable part that is not holding something already and go with that
                foreach (World.GameObject part in utilizableParts)
                {
                    if (part.children.Count == 0)
                    {
                        utilizablePart = part;
                        break;
                    }
                }
                // If it fails, send an appropriate message back
                if (utilizablePart == null)
                {
                    RPCs.RPCSay confirmation = new RPCs.RPCSay();
                    confirmation.arguments.Add("You have nothing to hold the " + givenArguments[0] + " with.");
                    server.SendRPC(confirmation, nameOfSender);
                    return;
                }
            }
            #endregion

            #region Find the object, pick it up, and send appripriate messages to the sender and everyone else in the chunk

            // Find possible gameObjects to pick up
            List <World.GameObject> gameObjectToPickUp = server.world.GetChunkOrGenerate(sender.position).FindChildrenWithName(givenArguments[0]);
            // If no gameObject was found, send back an error
            if (gameObjectToPickUp.Count == 0)
            {
                // If this fails, let the player know
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("There is no nearby " + givenArguments[0] + ".");
                server.SendRPC(failure, nameOfSender);
                return;
            }
            // If the first gameObject we found that is a canidate to pick up isn't holding us or anything weird like that
            if (gameObjectToPickUp.First().ContainsChild(nameOfSender) == null && gameObjectToPickUp.First() != sender)
            {
                // Put the object in the players utilizable part, usually a hand
                utilizablePart.AddChild(gameObjectToPickUp.First());
                // Remove it from the chunk
                server.world.GetChunkOrGenerate(sender.position).RemoveChild(gameObjectToPickUp.First());
                // Confirm to the sender that they picked up the object
                RPCs.RPCSay confirmation = new RPCs.RPCSay();
                confirmation.arguments.Add("You picked up " + Processing.Describer.GetArticle(gameObjectToPickUp.First().identifier.fullName) + " " + gameObjectToPickUp.First().identifier.fullName + " in your " + utilizablePart.identifier.fullName + ".");
                server.SendRPC(confirmation, nameOfSender);
                // Let everyone else in the chunk know that this player picked up something
                RPCs.RPCSay information = new RPCs.RPCSay();
                information.arguments.Add(nameOfSender + " picked up " + Processing.Describer.GetArticle(gameObjectToPickUp.First().identifier.fullName) + " " + gameObjectToPickUp.First().identifier.fullName + ".");
                // Find everyone in the same chunk and let them know
                foreach (KeyValuePair <string, Core.Player> playerEntry in server.world.players)
                {
                    // If this player is not the one that picked something up, and it's position is the same as the original player's position
                    if (playerEntry.Key != nameOfSender && playerEntry.Value.controlledGameObject.position == sender.position)
                    {
                        // Send an informational RPC to them letting them know
                        server.SendRPC(information, playerEntry.Key);
                    }
                }
            }

            #endregion
        }
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <(l)eft|(r)ight|(h)ead>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // The object to block with
            World.GameObject objectToBlockWith = null;

            #region Validate the argument
            if (givenArguments[0] != "left" &&
                givenArguments[0] != "right" &&
                givenArguments[0] != "head" &&
                givenArguments[0] != "l" &&
                givenArguments[0] != "r" &&
                givenArguments[0] != "h")
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("\"" + givenArguments[0] + "\" is not a valid direction to block. Use \"left\", \"right\", or \"head\".");
                server.SendRPC(error, nameOfSender);
                return;
            }
            // Translate the short hand of the direction to block if one was used
            if (givenArguments[0] == "l")
            {
                givenArguments[0] = "left";
            }
            else if (givenArguments[0] == "r")
            {
                givenArguments[0] = "right";
            }
            else if (givenArguments[0] == "h")
            {
                givenArguments[0] = "head";
            }
            #endregion

            #region Get the object to block with
            // Make sure there is an object to block with
            if (sender.FindChildrenWithSpecialProperty("isUtilizable").Count <= 0)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("You have nothing to block with.");
                server.SendRPC(error, nameOfSender);
                return;
            }
            // Loop through all the utilizable objects on the sender
            foreach (World.GameObject potentialObjectToUse in sender.FindChildrenWithSpecialProperty("isUtilizable"))
            {
                // If this potential object's thing being held matches, use it
                if (potentialObjectToUse.children.Count > 0)
                {
                    objectToBlockWith = potentialObjectToUse.children.First();
                    break;
                }
            }
            // If the loop didn't find anything that the sender is holding to block with, just use the first utilizable part
            if (objectToBlockWith == null)
            {
                objectToBlockWith = sender.FindChildrenWithSpecialProperty("isUtilizable").First();
            }
            #endregion

            #region Set the attribute on the object to block with, and set a timer to cancel it
            objectToBlockWith.specialProperties["blocking"] = givenArguments[0];
            new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                Thread.Sleep(2000);
                objectToBlockWith.specialProperties["blocking"] = "NULL";

                RPCs.RPCSay rpcToSenderForReset       = new RPCs.RPCSay();
                RPCs.RPCSay rpcToEveryoneElseForReset = new RPCs.RPCSay();

                rpcToSenderForReset.arguments.Add("You let down your guard.");
                rpcToEveryoneElseForReset.arguments.Add(nameOfSender + " let down their guard.");

                server.SendRPC(rpcToSenderForReset, nameOfSender);
                server.SendRPC(rpcToEveryoneElseForReset, sender.position, new List <string>()
                {
                    nameOfSender
                });
            }).Start();
            #endregion

            #region Confirm the block
            RPCs.RPCSay rpcToSender       = new RPCs.RPCSay();
            RPCs.RPCSay rpcToEveryoneElse = new RPCs.RPCSay();

            rpcToSender.arguments.Add("You blocked to your " + givenArguments[0] + " with your " + objectToBlockWith.identifier.fullName + "!");
            rpcToEveryoneElse.arguments.Add(nameOfSender + " blocked to the " + givenArguments[0] + " with " + Processing.Describer.GetArticle(objectToBlockWith.identifier.fullName) + " " + objectToBlockWith.identifier.fullName + "!");

            server.SendRPC(rpcToSender, nameOfSender);
            server.SendRPC(rpcToEveryoneElse, sender.position, new List <string>()
            {
                nameOfSender
            });
            #endregion
        }
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <nameOfObjectToDrop>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // Get the hashset of the utilizable parts of the player, like the hands, tail, etc
            List <World.GameObject> utilizableParts = sender.FindChildrenWithSpecialProperty("isUtilizable");

            // The gameObject that we will drop the object from, which will be determined
            World.GameObject utilizablePart = null;
            // The gameObject that we will drop
            World.GameObject gameObjectToDrop = null;

            #region Determine the utilizablePart to drop the object
            // First off, check if we even have a hand that can hold an object
            if (utilizableParts.Count == 0)
            {
                return;
            }
            // Find the first utilizable part that is holding the object with the name
            foreach (World.GameObject part in utilizableParts)
            {
                if (part.children.Count == 1 && part.children.First().identifier.DoesStringPartiallyMatchFullName(givenArguments[0]))
                {
                    utilizablePart = part;
                    break;
                }
            }
            // If it fails, send an appropriate message back
            if (utilizablePart == null)
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are not holding " + Processing.Describer.GetArticle(givenArguments[0]) + " " + givenArguments[0] + ".");
                server.SendRPC(failure, nameOfSender);
                return;
            }
            #endregion

            #region Drop the object and send appripriate messages to the sender and everyone else in the chunk
            // Get the object to drop
            gameObjectToDrop = utilizablePart.children.First();
            // Add the object to the chunk
            server.world.GetChunkOrGenerate(sender.position).AddChild(gameObjectToDrop);
            // Remove it from the utilizable part
            utilizablePart.RemoveChild(gameObjectToDrop);
            // Confirm to the sender that they dropped the object
            RPCs.RPCSay confirmation = new RPCs.RPCSay();
            confirmation.arguments.Add("You dropped the " + gameObjectToDrop.identifier.fullName + " in your " + utilizablePart.identifier.fullName + ".");
            server.SendRPC(confirmation, nameOfSender);
            // Let everyone else in the chunk know that this player dropped something
            RPCs.RPCSay information = new RPCs.RPCSay();
            information.arguments.Add(nameOfSender + " dropped " + Processing.Describer.GetArticle(gameObjectToDrop.identifier.fullName) + " " + gameObjectToDrop.identifier.fullName + ".");
            // Find everyone in the same chunk and let them know
            foreach (KeyValuePair <string, Core.Player> playerEntry in server.world.players)
            {
                // If this player is not the one that picked something up, and it's position is the same as the original player's position
                if (playerEntry.Key != nameOfSender && playerEntry.Value.controlledGameObject.position == sender.position)
                {
                    // Send an informational RPC to them letting them know
                    server.SendRPC(information, playerEntry.Key);
                }
            }
            #endregion
        }
        public override void Run(List <string> givenArguments, Server server)
        {
            // ARGS: <objectToAttach> <objectToAttachTo> <objectToAttachWith>

            // If dead
            if (sender.specialProperties["isDeceased"] == "TRUE")
            {
                RPCs.RPCSay failure = new RPCs.RPCSay();
                failure.arguments.Add("You are deceased.");
                server.SendRPC(failure, nameOfSender);
                return;
            }

            // Get each of the objects necessary to do the attaching
            World.GameObject objectToAttach     = server.world.FindFirstGameObject(givenArguments[0], sender.position);
            World.GameObject objectToAttachTo   = server.world.FindFirstGameObject(givenArguments[1], sender.position);
            World.GameObject objectToAttachWith = server.world.FindFirstGameObject(givenArguments[2], sender.position);

            // Make sure the objects exist
            if (objectToAttach == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("There is no nearby " + givenArguments[0] + ".");
                server.SendRPC(error, nameOfSender);
                return;
            }
            if (objectToAttachTo == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("There is no nearby " + givenArguments[1] + ".");
                server.SendRPC(error, nameOfSender);
                return;
            }
            if (objectToAttachWith == null)
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("There is no nearby " + givenArguments[2] + ".");
                server.SendRPC(error, nameOfSender);
                return;
            }
            // If the object we're trying to attach with can't be used to fasten with, throw an error
            if (!objectToAttachWith.specialProperties.ContainsKey("isFastenable"))
            {
                RPCs.RPCSay error = new RPCs.RPCSay();
                error.arguments.Add("You can't use " + Processing.Describer.GetArticle(objectToAttachWith.identifier.fullName) + " " + objectToAttachWith.identifier.fullName + " to fasten with.");
                server.SendRPC(error, nameOfSender);
                return;
            }

            // Tell the player in the present tense that they are completing the action
            string presentTenseConfirmationString = "You are attaching " + Processing.Describer.GetArticle(objectToAttach.identifier.fullName) + " " + objectToAttach.identifier.fullName
                                                    + " to " + Processing.Describer.GetArticle(objectToAttachTo.identifier.fullName) + " " + objectToAttachTo.identifier.fullName
                                                    + " using " + Processing.Describer.GetArticle(objectToAttachWith.identifier.fullName) + " " + objectToAttachWith.identifier.fullName + "...";

            RPCs.RPCSay presentTenseConfirmation = new RPCs.RPCSay();
            presentTenseConfirmation.arguments.Add(presentTenseConfirmationString);
            server.SendRPC(presentTenseConfirmation, nameOfSender);
            // Loop the elipsis three times and send it to the player, implying work being done
            for (int i = 0; i < 5000 / 1000; i++)
            {
                Thread.Sleep(1000);
                RPCs.RPCSay elipsis = new RPCs.RPCSay();
                elipsis.arguments.Add("...");
                server.SendRPC(elipsis, nameOfSender);
            }
            // Attach the objects together
            objectToAttachWith.AddChild(objectToAttach);
            objectToAttachTo.AddChild(objectToAttachWith);
            // The string we will send back as confirmation
            string confirmationString = "You attached " + Processing.Describer.GetArticle(objectToAttach.identifier.fullName) + " " + objectToAttach.identifier.fullName
                                        + " to " + Processing.Describer.GetArticle(objectToAttachTo.identifier.fullName) + " " + objectToAttachTo.identifier.fullName
                                        + " using " + Processing.Describer.GetArticle(objectToAttachWith.identifier.fullName) + " " + objectToAttachWith.identifier.fullName + ".";
            // The string we may or may not add
            string additionalConfirmation = "";

            // Check to see whether or not the object becomes a crafting combination
            World.Crafting.CraftingCombination possibleCombination = server.attachedApplication.recipeDatabase.CheckObjectForCombination(objectToAttachTo);
            // If so, rename the new object and have it inherit the classifier adjectives of the object we are attaching to it
            if (possibleCombination != null)
            {
                objectToAttachTo.identifier.classifierAdjectives.Clear();
                objectToAttachTo.identifier.classifierAdjectives = objectToAttach.identifier.classifierAdjectives;
                objectToAttachTo.identifier.name = possibleCombination.newName;
                additionalConfirmation           = "\nYou completed " + Processing.Describer.GetArticle(objectToAttachTo.identifier.fullName) + " " + objectToAttachTo.identifier.fullName + ".";
            }
            // Confirm to the sender that they successfully attached the object
            RPCs.RPCSay confirmation = new RPCs.RPCSay();
            confirmation.arguments.Add(confirmationString + additionalConfirmation);
            server.SendRPC(confirmation, nameOfSender);
            // Let everyone else in the chunk know that this player picked up something
            RPCs.RPCSay information = new RPCs.RPCSay();
            information.arguments.Add(nameOfSender + confirmationString.Substring(1));

            // Find everyone in the same chunk and let them know
            foreach (KeyValuePair <string, Core.Player> playerEntry in server.world.players)
            {
                // If this player is not the one that picked something up, and it's position is the same as the original player's position
                if (playerEntry.Key != nameOfSender && playerEntry.Value.controlledGameObject.position == sender.position)
                {
                    // Send an informational RPC to them letting them know
                    server.SendRPC(information, playerEntry.Key);
                }
            }
        }