/// <summary> /// Saves the character to application memory. /// </summary> public override SMItem ProduceCorpse() { // Create the corpse SMItem corpse = SMItemFactory.Get("Misc", "Corpse"); corpse.ItemName = this.GetFullName() + " Corpse"; // If it's an animal or some such, create the destroyed output elements. if (this.DestroyedOutput != null) { corpse.DestroyedOutput = this.DestroyedOutput; } // Previous item family type corpse.PreviousItemFamily = this.FamilyType; // Create the "held items" list ready for transferring items to the corpse. corpse.HeldItems = new List <SMItem>(); if (this.Slots != null) { foreach (SMSlot sms in this.Slots) { if (!sms.isEmpty()) { corpse.HeldItems.Add(sms.EquippedItem); } } } // TODO Add clothing / armour items to the held items list ready for looting. return(corpse); }
/// <summary> /// Finds an item in a list by matching the items id, name or family to a given identifier. /// </summary> /// <returns>The item from the list.</returns> /// <param name="list">List od items to look search.</param> /// <param name="itemIdentifier">Item identifier.</param> private static SMItem FindItemInList(List <SMItem> list, string itemIdentifier) { string ciIdentifier = itemIdentifier.ToLower(); SMItem foundItem = null; foundItem = list.FirstOrDefault((SMItem item) => item.ItemID == itemIdentifier); if (foundItem == null) { foundItem = list.FirstOrDefault((SMItem item) => item.ItemName.ToLower() == ciIdentifier); } if (foundItem == null) { foundItem = list.FirstOrDefault((SMItem item) => item.PluralName.ToLower() == ciIdentifier); } if (foundItem == null) { foundItem = list.FirstOrDefault((SMItem item) => item.ItemFamily.ToLower() == ciIdentifier); } if (foundItem == null) { foundItem = list.FirstOrDefault((SMItem item) => item.GetPluralFamilyName().ToLower() == ciIdentifier); } if (foundItem == null) { foundItem = list.FirstOrDefault((SMItem item) => item.ItemType.ToLower() == ciIdentifier); } return(foundItem); }
/// <summary> /// Removes an item from a list recursivly looking through containers within containers. /// </summary> /// <returns><c>true</c>, if the item was removed, <c>false</c> otherwise.</returns> /// <param name="list">List to remove item from.</param> /// <param name="itemIdentifier">Item identifier.</param> private static bool RemoveItemFromListRecursive(List <SMItem> list, string itemIdentifier) { SMItem foundItem = FindItemInList(list, itemIdentifier); if (foundItem != null) { list.Remove(foundItem); return(true); } foreach (SMItem item in list) { // TODO account for locked containers if (item.CanHoldOtherItems() && item.HeldItems != null) { foundItem = FindItemInListRecursive(item.HeldItems, itemIdentifier); if (foundItem != null) { item.HeldItems.Remove(foundItem); return(true); } } } return(false); }
/// <summary> /// Gets a new general item based on the spec provided. /// </summary> /// <param name="guid">A guid for the new item.</param> /// <param name="jsonSpec">The spec of the item as a json string.</param> /// <returns>An SMItem instance.</returns> private static SMItem GetItem(string guid, string jsonSpec) { SMItem item = JsonConvert.DeserializeObject <SMItem>(jsonSpec); item.ItemID = guid; return(item); }
/// <summary> /// Puts an item in a container, initialising the containers HeldItems property to an new list if required. /// </summary> /// <param name="item">The item to put.</param> /// <param name="container">The container to put in.</param> public static void PutItemInContainer(SMItem item, SMItem container) { if (container.HeldItems == null) { container.HeldItems = new List <SMItem>(); } container.HeldItems.Add(item); }
/// <summary> /// Removes an item from the room, recursively looks through containers for the item if required. /// </summary> /// <param name="item">SMItem to remove.</param> public void RemoveItem(SMItem item) { if (this.RoomItems != null) { SMItemHelper.RemoveItemFromList(this.RoomItems, item.ItemID); } this.SaveToApplication(); }
/// <summary> /// Adds an item to the room, so any user can collect it. /// </summary> /// <param name="item">Item.</param> public void AddItem(SMItem item) { if (this.RoomItems == null) { this.RoomItems = new List <SMItem>(); } this.RoomItems.Add(item); this.SaveToApplication(); }
/// <summary> /// Gets the id of an item in the room by its name /// </summary> /// <param name="itemName"></param> /// <returns>The ItemID</returns> public string GetRoomItemID(string itemName) { SMItem item = this.GetItemByName(itemName); if (item != null) { return(item.ItemID); } return(null); }
/// <summary> /// Gets a container item from the room matching a given identifier. /// </summary> /// <param name="identifier">The container identifier.</param> /// <returns>The container if found otherwise null.</returns> public SMItem GetRoomContainer(string identifier) { SMItem item = SMItemHelper.GetItemFromList(this.RoomItems, identifier); if (item == null || !item.CanHoldOtherItems()) { return(null); } return(item); }
/// <summary> /// Checks if this item contains a specified other item. /// </summary> /// <param name="item">The item to test for inside this.</param> /// <returns>Bool indicating of the item is inside this.</returns> public bool Contains(SMItem item) { if (this.HeldItems != null && this.HeldItems.Any()) { SMItem foundItem = SMItemHelper.GetItemFromList(this.HeldItems, item.ItemID); return(foundItem == null ? false : true); } return(false); }
/// <summary> /// Checks if a given item matches a given string identifier (id, name, family). /// </summary> /// <returns><c>true</c>, if the identifier matches the itemed, <c>false</c> otherwise.</returns> /// <param name="item">SMItem.</param> /// <param name="identifier">String identifier (id, name, family).</param> public static bool ItemMatches(SMItem item, string identifier) { if (item.ItemID == identifier || item.ItemName.ToLower() == identifier.ToLower() || item.ItemFamily.ToLower() == identifier.ToLower() || item.ItemType.ToLower() == identifier.ToLower()) { return(true); } return(false); }
/// <summary> /// Determines if the item can hold a given other item by checking the properties of both items and the available /// capacity of this item. /// </summary> /// <param name="item">The item to be put inside this.</param> /// <returns>Bool indicating if the item can be put inside this.</returns> public bool CanHoldItem(SMItem item) { if (this.CanHoldOtherItems() && this.CanHoldItemByFamily(item)) { if (SMItemHelper.GetItemAvailbleCapacity(this) >= item.ItemSize) { return(true); } } return(false); }
/// <summary> /// Attack an item /// </summary> /// <param name="attackingCharacter">The attacking character</param> /// <param name="targetItem">The target item</param> public static void Attack(SMCharacter attackingCharacter, SMItem targetItem) { // Check that the target has hitpoints if (targetItem.HitPoints > 0) { // Use the skill attackingCharacter.UseSkill(GetSkillToUse(attackingCharacter), targetItem.ItemName, true); } else // Report that the target can not be found { attackingCharacter.sendMessageToPlayer(ResponseFormatterFactory.Get().General($"{targetItem.ItemName} can not be found")); } }
/// <summary> /// Checks if a given item can be equipped, based on its type and the slots status /// </summary> /// <returns><c>true</c>, if the iten can be equipped, <c>false</c> otherwise.</returns> /// <param name="item">Item.</param> public bool canEquipItem(SMItem item) { if (this.isEmpty()) { if (this.AllowedTypes.Contains("any")) { return(true); } return(this.AllowedTypes.Contains(item.ItemType)); } return(false); }
/// <summary> /// Gets the item weight, including any items it contains. /// </summary> /// <returns>The item weight.</returns> /// <param name="item">Item to get the weight for.</param> public static int GetItemWeight(SMItem item) { int weight = item.ItemWeight; if (item.CanHoldOtherItems() && item.HeldItems != null) { foreach (SMItem smi in item.HeldItems) { weight += GetItemWeight(smi); } } return(weight); }
/// <summary> /// Checks if a given item matches a given string identifier (id, name, family). /// </summary> /// <returns><c>true</c>, if the identifier matches the itemed, <c>false</c> otherwise.</returns> /// <param name="item">SMItem.</param> /// <param name="identifier">String identifier (id, name, family).</param> public static bool ItemMatches(SMItem item, string identifier) { string ciIdentifier = identifier.ToLower(); if (item.ItemID == identifier || item.ItemName.ToLower() == ciIdentifier || item.PluralName.ToLower() == ciIdentifier || item.ItemFamily.ToLower() == ciIdentifier || item.GetPluralFamilyName().ToLower() == ciIdentifier || item.ItemType.ToLower() == ciIdentifier) { return(true); } return(false); }
/// <summary> /// Counts the number of items in a given container that match a given id, name or family. /// </summary> /// <param name="container">The countainer to look in.</param> /// <param name="itemIdentiifier">The id, name or family to match.</param> /// <returns>The count of matching items.</returns> public static int CountItemsInContainer(SMItem container, string itemIdentiifier) { int count = 0; if (container.HeldItems != null && container.HeldItems.Any()) { foreach (SMItem item in container.HeldItems) { if (ItemMatches(item, itemIdentiifier)) { count++; } } } return(count); }
/// <summary> /// Calculates the used capacity of a container. /// </summary> /// <param name="item">The container to look at.</param> /// <returns>The containers used capacity.</returns> public static int GetItemUsedCapacity(SMItem item) { if (!item.CanHoldOtherItems()) { return(0); } int used = 0; if (item.HeldItems.Any()) { foreach (SMItem smi in item.HeldItems) { used += GetItemWeight(smi); } } return(used); }
public SMItem GetProducedItem() { SMItem smi = null; // Get the right path, and work out if the file exists. string path = FilePathSystem.GetFilePath("Objects", this.GetProducedItemName()); // Check if the character exists.. if (File.Exists(path)) { using (StreamReader r = new StreamReader(path)) { // Get the character from the json string string json = r.ReadToEnd(); smi = JsonConvert.DeserializeObject <SMItem>(json); } } return(smi); }
/// <summary> /// Searches a specified container recursively to find a container matching a given identifier. /// Will return the specified container itself if the identifier matches. /// </summary> /// <param name="identifier">The identifier for the container to search for.</param> /// <param name="container">The container to search in.</param> /// <returns>An SMItem object representing the container matching the idetifier.</returns> public static SMItem FindContainerInContainerRecursive(string identifier, SMItem container) { SMItem foundContainer = ItemMatches(container, identifier) ? container : null; if (foundContainer == null) { foreach (SMItem innerItem in container.HeldItems) { if (innerItem.CanHoldOtherItems()) { if (ItemMatches(innerItem, identifier)) { return(innerItem); } return(FindContainerInContainerRecursive(identifier, innerItem)); } } } return(foundContainer); }
/// <summary> /// Removes anSMItem from a list of items based on a given item identifier. /// </summary> /// <returns><c>true</c>, if the was removed, <c>false</c> otherwise.</returns> /// <param name="list">List of SMItems to remove from.</param> /// <param name="itemIdentifier">Item identifier (id, name, family).</param> /// <param name="recursive">If set to <c>true</c> recursive look through container items in the list until /// one item is removed.</param> public static bool RemoveItemFromList(List <SMItem> list, string itemIdentifier, bool recursive = true) { if (list == null) { return(false); } if (recursive == true) { return(RemoveItemFromListRecursive(list, itemIdentifier)); } SMItem itemToRemove = GetItemFromList(list, itemIdentifier, false); if (itemToRemove != null) { list.Remove(itemToRemove); return(true); } return(false); }
/// <summary> /// Searches a specified container recursively to find a suitable container to place a given item in. /// Will return the specified container itself if the item can go directly in to it. /// </summary> /// <param name="item">The item to find a container for.</param> /// <param name="container">The container to search in.</param> /// <returns>An SMItem object the item can go in or null.</returns> public static SMItem FindContainerForItemRecursive(SMItem item, SMItem container) { SMItem foundContainer = container.CanHoldItem(item) ? container : null; if (foundContainer == null) { foreach (SMItem innerItem in container.HeldItems) { if (innerItem.CanHoldOtherItems() && innerItem.HeldItems != null) { foundContainer = FindContainerForItemRecursive(item, innerItem); if (foundContainer != null) { return(foundContainer); } } } } return(foundContainer); }
public static string GetSkillToUse(SMCharacter attackingCharacter) { string skillToUse = "Brawl"; if (!attackingCharacter.AreHandsEmpty()) { // Get the equipped item from the character if any SMItem smi = attackingCharacter.GetEquippedItem(); skillToUse = "Basic Attack"; if ((smi != null) && (smi.RequiredSkills != null)) { // Check the player has the required skills bool hasAllRequiredSkills = true; bool isFirst = true; foreach (SMRequiredSkill smrs in smi.RequiredSkills) { if (hasAllRequiredSkills) { hasAllRequiredSkills = attackingCharacter.HasRequiredSkill(smrs.SkillName, smrs.SkillLevel); if (isFirst) { skillToUse = smrs.SkillName; } } } // If the player has all the required skills if (!hasAllRequiredSkills) { // Tell the player they can't really wield that item. attackingCharacter.sendMessageToPlayer(ResponseFormatterFactory.Get().General($"You are not skilled with the {smi.ItemFamily}, practicing gives you a chance to increase your skill")); } } } return(skillToUse); }
/// <summary> /// Gets the items listing of a given container in a string ready for outputting. /// </summary> /// <param name="container">Container SMItem to get the listings for.</param> /// <returns>Containers item listings.</returns> public static string GetContainerContents(SMItem container) { // Return null it not a container if (!container.CanHoldOtherItems()) { return(null); } // If the container is empty if (container.HeldItems == null || !container.HeldItems.Any()) { return(OutputFormatterFactory.Get().Italic("Empty")); } // Get list of item counts // TODO bring this functionality into this class List <ItemCountObject> lines = SMItemUtils.GetItemCountList(container.HeldItems); string output = ""; foreach (ItemCountObject line in lines) { string itemDetails = $"{line.Count} x "; if (line.Count > 1) { itemDetails += line.PluralName; } else { itemDetails += line.SingularName; } output += OutputFormatterFactory.Get().General(itemDetails); } return(output); }
/// <summary> /// Finds an item in a list recursivly looking through containers within containers. /// </summary> /// <returns>The item from the list.</returns> /// <param name="list">List.</param> /// <param name="itemIdentifier">Item identifier.</param> private static SMItem FindItemInListRecursive(List <SMItem> list, string itemIdentifier) { SMItem foundItem = FindItemInList(list, itemIdentifier); if (foundItem == null) { foreach (SMItem item in list) { // TODO account for locked containers if (item.CanHoldOtherItems() && item.HeldItems != null) { foundItem = FindItemInListRecursive(item.HeldItems, itemIdentifier); if (foundItem != null) { return(foundItem); } } } } return(foundItem); }
/// <summary> /// Determines if the item can hold a given itme based on the properties of both items. /// </summary> /// <param name="item">The item that is to be put in this item.</param> /// <returns>Bool indicating if the item can be put in this item.</returns> public bool CanHoldItemByFamily(SMItem item) { if (!this.CanHoldOtherItems()) { return(false); } if (this.CanHoldFamilies != null && this.CanHoldFamilies.Any()) { if (this.CanHoldFamilies.Contains("any")) { return(true); } if (CanHoldFamilies.FirstOrDefault(s => s.ToLower() == item.ItemFamily.ToLower()) != null) { return(true); } return(false); } return(true); }
/// <summary> /// Calculates the available capacity of a container. /// </summary> /// <param name="item">The container to look at.</param> /// <returns>The containers available capacity.</returns> public static int GetItemAvailbleCapacity(SMItem item) { if (!item.CanHoldOtherItems()) { return(0); } if (item.HeldItems == null || !item.HeldItems.Any()) { return(item.ItemCapacity); } int used = 0; if (item.HeldItems.Any()) { foreach (SMItem smi in item.HeldItems) { used += GetItemWeight(smi); } } return(item.ItemCapacity - used); }
public static void StartAnNPCReactionCheck(SMNPC npc, string actionType, SMCharacter invokingCharacter, SMItem itemIn = null) { HttpContext ctx = HttpContext.Current; Thread npcReactionThread = new Thread(new ThreadStart(() => { HttpContext.Current = ctx; npc.RespondToAction("PlayerCharacter.GivesItemToThem", invokingCharacter, itemIn); })); npcReactionThread.Start(); }
public void RespondToAction(string actionType, SMCharacter invokingCharacter, SMItem itemIn = null) { // Get a list of characters that respond to this action type in the room List <NPCResponses> listToChooseFrom = NPCResponses.FindAll(npcr => npcr.ResponseType == actionType); // If there are some responses for this character for the actionType if (listToChooseFrom != null) { // If there is more than one of the item randomise the list if (listToChooseFrom.Count > 1) { listToChooseFrom = listToChooseFrom.OrderBy(item => new Random().Next()).ToList(); } // Loop around until a response is selected bool responseSelected = false; foreach (NPCResponses npr in listToChooseFrom) { // If we're still looking for a response try the next one (if there is one) if (!responseSelected) { // randomly select whether this happens or not int rndChance = new Random().Next(1, 100); if (rndChance <= npr.Frequency) { // If the invoking character is null if ((invokingCharacter == null) && (this.RoomID != "IsSpawned")) { // Get a random player (in line with the scope of the additional data) invokingCharacter = this.GetRoom().GetRandomCharacter(this, npr.AdditionalData); } // If the invoking character is not null if (invokingCharacter != null) { // Process the response ProcessResponse(npr, invokingCharacter, itemIn); } // Set that a response has been selected so we can drop out of the loop responseSelected = true; } } } } }
private void ProcessConversationStep(NPCConversations npcc, string stepID, SMCharacter invokingCharacter) { NPCConversationStep npccs = npcc.ConversationSteps.FirstOrDefault(cs => cs.StepID == stepID); bool continueToNextStep = true; if (npccs != null) { switch (npccs.Scope.ToLower()) { case "choice": string[] choices = npccs.AdditionalData.Split(','); int choicesNumber = choices.Count(); int randomChoice = (new Random().Next(1, choicesNumber + 1)) - 1; if (randomChoice > choicesNumber) { randomChoice = 0; } ProcessConversationStep(npcc, choices[randomChoice], invokingCharacter); break; case "say": this.Say(ProcessResponseString(npccs.AdditionalData, invokingCharacter)); break; case "shout": this.Shout(ProcessResponseString(npccs.AdditionalData, invokingCharacter)); break; case "whisper": this.Whisper(ProcessResponseString(npccs.AdditionalData, invokingCharacter), invokingCharacter.GetFullName()); break; case "emote": this.GetRoom().ChatEmote(ProcessResponseString(npccs.AdditionalData, invokingCharacter), this, this); break; case "saytoplayer": // Construct the message string sayToPlayerMessage = OutputFormatterFactory.Get().Italic(this.GetFullName() + " says:", 0) + " \"" + ProcessResponseString(npccs.AdditionalData, invokingCharacter) + "\""; // Send the message invokingCharacter.sendMessageToPlayer(sayToPlayerMessage); break; case "emotetoplayer": // Construct the message string emoteToPlayerMessage = OutputFormatterFactory.Get().Italic(this.GetFullName() + " " + ProcessResponseString(npccs.AdditionalData, invokingCharacter)); // Send the message invokingCharacter.sendMessageToPlayer(emoteToPlayerMessage); break; case "attack": // Simply attack a target player this.Attack(invokingCharacter.GetFullName()); break; case "giveitem": // give an item to the player string[] additionalDataSplit = npccs.AdditionalData.Split(','); string[] itemParts = additionalDataSplit[0].Split('.'); // Create the item.. if (itemParts.Count() == 2) { int numberToCreate = int.Parse(additionalDataSplit[1]); // Create the right number of the items. while (numberToCreate > 0) { // Get the item (with a new GUID) SMItem itemBeingGiven = SMItemFactory.Get(itemParts[0], itemParts[1]); // Pass it to the player invokingCharacter.PickUpItem("", itemBeingGiven, true); // Reduce the number to create numberToCreate--; } } break; case "addquest": // Load the quest SMQuest smq = SMQuestFactory.Get(npccs.AdditionalData); if (smq != null) { invokingCharacter.AddQuest(smq); } break; case "updatequest": // Load the quest SMQuest qtu = SMQuestFactory.Get(npccs.AdditionalData); if (qtu != null) { invokingCharacter.UpdateQuest(qtu); } break; case "checkquestinprogress": // Check the quest log isn't null if (invokingCharacter.QuestLog != null) { if (invokingCharacter.QuestLog.Count(questcheck => (questcheck.QuestName.ToLower() == npccs.AdditionalData.ToLower()) && (questcheck.Completed)) > 0) { continueToNextStep = false; } } break; case "setplayerattribute": // Add a response option switch (npccs.AdditionalData.ToLower()) { case "firstname": invokingCharacter.FirstName = invokingCharacter.VariableResponse; break; case "lastname": invokingCharacter.LastName = invokingCharacter.VariableResponse; break; case "sex": invokingCharacter.Sex = char.Parse(invokingCharacter.VariableResponse); break; } invokingCharacter.SaveToApplication(); invokingCharacter.SaveToFile(); break; case "setvariableresponse": invokingCharacter.VariableResponse = npccs.AdditionalData.ToLower(); break; case "teachskill": // Check if the player already has the skill if (invokingCharacter.Skills == null) { invokingCharacter.Skills = new List <SMSkillHeld>(); } // Get the skill and level to teach to string[] skillToTeach = npccs.AdditionalData.Split('.'); // Check if the character already has the skill if (invokingCharacter.Skills.Count(skill => skill.SkillName == skillToTeach[0]) == 0) { // Create a new skill help object SMSkillHeld smsh = new SMSkillHeld(); smsh.SkillName = skillToTeach[0]; smsh.SkillLevel = int.Parse(skillToTeach[1]); // Finally add it to the player invokingCharacter.Skills.Add(smsh); // Save the player invokingCharacter.SaveToApplication(); invokingCharacter.SaveToFile(); // Inform the player they have learnt a new skill invokingCharacter.sendMessageToPlayer(OutputFormatterFactory.Get().Italic($"You learn a new skill: {smsh.SkillName}({smsh.SkillLevel}).")); } break; case "wait": System.Threading.Thread.Sleep(int.Parse(npccs.AdditionalData) * 1000); break; } if (continueToNextStep) { if (npccs.ResponseOptions != null) { if (npccs.ResponseOptions.Count > 0) { ProcessResponseOptions(npcc, npccs, invokingCharacter); } } if (npccs.NextStep != null) { string[] splitNextStep = npccs.NextStep.Split('.'); if (splitNextStep[1] != "0") { System.Threading.Thread.Sleep(int.Parse(splitNextStep[1]) * 1000); } ProcessConversationStep(npcc, splitNextStep[0], invokingCharacter); } } } }