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); } } } }
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 }
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 }
// 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(); }
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 }
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); } } }