/// <summary> /// Spell scrolls loaded from saved player item data. /// </summary> /// <param name="scrollSpecial"></param> /// <returns></returns> public static Item CreateSpellScroll(string scrollSpecial) { string longDesc = ""; try { if (scrollSpecial.Contains("longDesc:")) { scrollSpecial = scrollSpecial.Replace("longDesc:", ""); longDesc = scrollSpecial.Substring(0, scrollSpecial.IndexOf("scrollSpellID:")); //longDesc = scrollSpecial.Substring(scrollSpecial.IndexOf("longDesc:") + "longDesc:".Length, scrollSpecial.IndexOf("scrollSpellID:") - "longDesc:".Length).Trim(); scrollSpecial = scrollSpecial.Replace(longDesc, ""); } } catch (System.Exception ex) { Utils.LogException(ex); longDesc = ""; } //scrollSpecial = scrollSpecial.Replace(longDesc, ""); //scrollSpecial = scrollSpecial.Trim(); int spellID = -1; //ScrollSpecial at this point is 'longDesc:scrollSpellID:....' So I added the string so that it correctly finds the length -dw try { if (scrollSpecial.Contains("scrollSpellID:")) { scrollSpecial = scrollSpecial.Replace("scrollSpellID:", ""); //spellID = System.Convert.ToInt32(scrollSpecial.Substring(scrollSpecial.IndexOf("longDesc:scrollSpellID:") + "longDesc:scrollSpellID:".Length, scrollSpecial.Length - "longDesc:scrollSpellID:".Length)); spellID = System.Convert.ToInt32(scrollSpecial); } } catch (System.Exception ex) { Utils.LogException(ex); spellID = -1; } var scroll = Item.CopyItemFromDictionary(Item.ID_WORN_BLANK_SCROLL); if (longDesc == "" || spellID == -1) { return(scroll); // failed to recreate the scribed scroll } GameSpell spell = GameSpell.GetSpell(spellID); scroll.spell = spell.ID; scroll.spellPower = -1; scroll.longDesc = longDesc; scroll.identifiedName = "Scroll of " + spell.Name; scroll.notes = "Scroll of " + spell.Name + " (scribed)"; scroll.special = "longDesc:" + scroll.longDesc + " scrollSpellID:" + spell.ID; scroll.coinValue = spell.TrainingPrice; scroll.charges = 0; return(scroll); }
public bool OnCommand(Character chr, string args) { System.Collections.Generic.List <GameSpell> spells = new System.Collections.Generic.List <GameSpell>(); foreach (int id in chr.spellDictionary.Keys) { spells.Add(GameSpell.GetSpell(id)); } if (chr.IsHybrid) // Currently only Knights and Ravagers { if (!chr.HasKnightRing) { chr.WriteToDisplay("You are not equipped with the proper item to cast spells."); return(true); } foreach (GameSpell gamespell in GameSpell.GameSpellDictionary.Values) { if (gamespell.IsClassSpell(chr.BaseProfession) && gamespell.IsAvailableAtTrainer && !spells.Contains(gamespell)) { spells.Add(gamespell); } } } spells.Sort(delegate(GameSpell spell1, GameSpell spell2) { int compareLevel = spell1.RequiredLevel.CompareTo(spell2.RequiredLevel); if (compareLevel == 0) { return(spell2.Name.CompareTo(spell2.Name)); } return(compareLevel); }); if (spells.Count > 0) { chr.WriteToDisplay("Known Spells:"); foreach (GameSpell spell in spells) { if (chr.spellDictionary.ContainsKey(spell.ID)) { chr.WriteToDisplay(spell.Name + " (" + spell.Command + ") " + chr.spellDictionary[spell.ID] + (chr.spellDictionary[spell.ID] == chr.MemorizedSpellChant ? " [MEMORIZED]":"")); } else { chr.WriteToDisplay(spell.Name + " (" + spell.Command + ")"); } } } else { chr.WriteToDisplay("You do not know any spells."); } return(true); }
/// <summary> /// Create a wand with a spell and all/some/no charges to be given to an NPC. The wand is currently placed in the NPC's sack or in lair loot. /// </summary> /// <param name="npc">The NPC to receive the spell wand.</param> /// <returns></returns> public static Item CreateSpellWand(NPC npc) { Item wand = null; try { var spellChoices = from spell in GameSpell.GameSpellDictionary.Values where npc.Level >= (spell.RequiredLevel - 1) && !spell.ClassTypes.Contains(Character.ClassType.None) && spell.IsFoundForCasting && !spell.OnlyFoundInLairs select spell; GameSpell chosenSpell = spellChoices.ElementAt(Rules.Dice.Next(spellChoices.Count())); //int count = 0; //while (chosenSpell.OnlyFoundInLairs && !npc.lairCritter && count <= 10) //{ // chosenSpell = spellChoices.ElementAt(Rules.Dice.Next(spellChoices.Count())); // count++; //} //// This kind of throws off calculations for lair scrolls. But oh well. Feeling a tad lazy. Let's add a check in disbursing lair loot in LootManager. //if (chosenSpell.OnlyFoundInLairs && !npc.lairCritter) // return null; //if (spellChoices.Count() > 0) // scroll = CreateSpellScroll(chosenSpell); if (wand != null) { Utils.Log(wand.GetLogString() + " created for NPC: " + npc.GetLogString(), Utils.LogType.LootWand); if (wand.vRandLow > 0) { wand.coinValue = Rules.Dice.Next(wand.vRandLow * 2, wand.vRandHigh * 2); } } } catch (System.Exception e) { Utils.Log(npc.GetLogString() + " has an issue with WandManager.CreateSpellWand", Utils.LogType.LootWarning); Utils.LogException(e); } return(wand); }
/// <summary> /// Create a random spell scroll. Either for scribing or casting, based on GameSpell variables and random dice rolls. /// </summary> /// <param name="spell">The GameSpell to be scribed or cast from the scroll.</param> /// <returns></returns> public static Item CreateSpellScroll(GameSpell spell) { var scroll = Item.CopyItemFromDictionary(Item.ID_WORN_BLANK_SCROLL); scroll.spell = spell.ID; scroll.spellPower = -1; scroll.longDesc = ScrollDescriptions[Rules.Dice.Next(ScrollDescriptions.Count)]; scroll.identifiedName = "Scroll of " + spell.Name; scroll.notes = "Scroll of " + spell.Name + " (scribed)"; scroll.special = "longDesc:" + scroll.longDesc + " scrollSpellID:" + spell.ID; scroll.coinValue = spell.TrainingPrice / 4; scroll.charges = 0; if ((spell.IsFoundForCasting && !spell.IsFoundForScribing) || (spell.IsFoundForCasting && Rules.RollD(1, 100) <= 30)) { scroll.spellPower = spell.RequiredLevel + Rules.RollD(1, 6); scroll.coinValue = scroll.coinValue / 2; scroll.charges = 1; scroll.notes = "Scroll of " + spell.Name + " (cast only)"; } return(scroll); }
public bool OnCommand(Character chr, string args) { if (args == null) { chr.WriteToDisplay("What spell do you want to cast?"); return(false); } string[] sArgs = args.Split(" ".ToCharArray()); chr.preppedSpell = GameSpell.GetSpell(sArgs[0].ToLower()); if (chr.preppedSpell == null) { chr.WriteToDisplay("Failed to find the spell " + sArgs[0] + "."); return(false); } chr.preppedSpell.WarmSpell(chr); chr.SendToAllInSight(chr.Name + ": " + GameSpell.GenerateMagicWords()); return(true); }
public bool OnCommand(Character chr, string args) { try { if (args != null) { string[] sArgs = args.Split(" ".ToCharArray()); Character target = GameSystems.Targeting.TargetAquisition.FindTargetInView(chr, sArgs[0], true, true); if (target == null) { chr.WriteToDisplay("Target not found."); target = chr; } if (target != null) { if (target.EffectsList.ContainsKey(Effect.EffectTypes.Blind)) { target.EffectsList[Effect.EffectTypes.Blind].StopCharacterEffect(); } if (target.EffectsList.ContainsKey(Effect.EffectTypes.Fear)) { target.EffectsList[Effect.EffectTypes.Fear].StopCharacterEffect(); } target.Stunned = 0; if (target.Poisoned > 0) { if (target.EffectsList.ContainsKey(Effect.EffectTypes.Poison)) { target.EffectsList[Effect.EffectTypes.Poison].StopCharacterEffect(); } target.Poisoned = 0; } if (target.EffectsList.ContainsKey(Effect.EffectTypes.Contagion)) { target.EffectsList[Effect.EffectTypes.Contagion].StopCharacterEffect(); } target.Hits = target.HitsFull; target.Stamina = target.StaminaFull; target.Mana = target.ManaFull; target.WriteToDisplay("You have been healed by the Ghods."); chr.WriteToDisplay("You have healed " + target.Name + " with your Ghodly powers."); GameSpell cureSpell = GameSpell.GetSpell((int)GameSpell.GameSpellID.Cure); if (!chr.IsInvisible) { target.SendSound(cureSpell.SoundFile); } return(true); } } } catch (Exception e) { Utils.LogException(e); } return(false); }
/// <summary> /// Create a scroll (scribeable) to be given to an NPC. The scroll is currently placed in the NPC's sack or in lair loot. /// </summary> /// <param name="npc">The NPC to receive the spell scroll.</param> /// <returns></returns> public static Item CreateUnavailableSpellScroll(NPC npc) { Item scroll = null; try { var spellChoices = from spell in GameSpell.GameSpellDictionary.Values where !spell.OnlyFoundInLairs && (spell.IsFoundForCasting || spell.IsFoundForScribing) && npc.Level >= (spell.RequiredLevel - 1) && !spell.ClassTypes.Contains(Character.ClassType.None) select spell; if (npc.lairCritter) { spellChoices = from spell in GameSpell.GameSpellDictionary.Values where (spell.IsFoundForCasting || spell.IsFoundForScribing) && npc.Level >= (spell.RequiredLevel - 1) && !spell.ClassTypes.Contains(Character.ClassType.None) && spell.OnlyFoundInLairs select spell; } if (spellChoices.Count() <= 0) // no spells were found { return(null); } GameSpell chosenSpell = spellChoices.ElementAt(Rules.Dice.Next(spellChoices.Count())); int loopCount = 0; while (chosenSpell.OnlyFoundInLairs && !npc.lairCritter && loopCount < spellChoices.Count()) { chosenSpell = spellChoices.ElementAt(Rules.Dice.Next(0, spellChoices.Count() - 1)); loopCount++; } // This kind of throws off calculations for lair scrolls. But oh well. Feeling a tad lazy. Let's add a check in disbursing lair loot in LootManager. if (chosenSpell.OnlyFoundInLairs && !npc.lairCritter) { return(null); } if (spellChoices.Count() > 0) { scroll = CreateSpellScroll(chosenSpell); } if (scroll != null) { Utils.Log(scroll.GetLogString() + " created for NPC: " + npc.GetLogString(), Utils.LogType.LootScroll); if (scroll.vRandLow > 0) { scroll.coinValue = Rules.Dice.Next(scroll.vRandLow * 2, scroll.vRandHigh * 2); } } } catch (System.Exception e) { Utils.Log(npc.GetLogString() + " has an issue with ScrollManager.CreateUnavailableSpellScroll", Utils.LogType.LootWarning); Utils.LogException(e); } return(scroll); }
//TODO: Create a single method to handle casting spells from items. 1/6/2017 -Eb public bool OnCommand(Character chr, string args) { if (chr.CommandWeight > 3) { chr.WriteToDisplay("Command weight limit exceeded. Cast command not processed."); return(true); } chr.CommandType = CommandTasker.CommandType.Cast; string outOfCharges = ""; if (args == null) { goto normalSpell; } string[] sArgs = args.Split(" ".ToCharArray()); #region Cast a spell from an Item try { #region Right Hand if (chr.RightHand != null && chr.RightHand.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.RightHand.spell).Command) { if (chr.RightHand.charges <= 0) { if (chr.RightHand.baseType == Globals.eItemBaseType.Scroll) { outOfCharges += "The " + chr.RightHand.name + " does not contain the proper runes to cast a spell. Perhaps it can be scribed."; } else { outOfCharges += "The " + chr.RightHand.name + " is out of charges. "; } goto checkLeftHand; } var storedSpell = chr.preppedSpell; var storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.RightHand.spell); if (chr.RightHand.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.RightHand.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.RightHand.charges > 0 && chr.RightHand.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.RightHand.charges--; // scrolls with charges disintegrate when they reach 0 charges if (chr.RightHand.baseType == Globals.eItemBaseType.Scroll && chr.RightHand.charges == 0) { chr.WriteToDisplay("The " + chr.RightHand.name + " disintegrates."); chr.UnequipRightHand(chr.RightHand); } } return(true); } #endregion checkLeftHand: #region Left Hand if (chr.LeftHand != null && chr.LeftHand.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.LeftHand.spell).Command) { if (chr.LeftHand.charges <= 0) { if (chr.LeftHand.baseType == Globals.eItemBaseType.Scroll) { outOfCharges += "The " + chr.LeftHand.name + " does not contain the proper runes to cast a spell. Perhaps it can be scribed."; } else { outOfCharges += "The " + chr.LeftHand.name + " is out of charges. "; } goto checkRightRing1; } var storedSpell = chr.preppedSpell; var storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.LeftHand.spell); if (chr.LeftHand.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.LeftHand.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.LeftHand.charges > 0 && chr.LeftHand.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.LeftHand.charges--; // scrolls with charges disintegrate when they reach 0 charges if (chr.LeftHand.baseType == Globals.eItemBaseType.Scroll && chr.LeftHand.charges == 0) { chr.WriteToDisplay("The " + chr.LeftHand.name + " disintegrates."); chr.UnequipLeftHand(chr.LeftHand); } } return(true); } #endregion checkRightRing1: #region Right Ring 1 if (chr.RightRing1 != null && chr.RightRing1.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.RightRing1.spell).Command) { if (chr.RightRing1.charges == 0) { outOfCharges += "The " + chr.RightRing1.name + " is out of charges. "; goto checkRightRing2; } GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.RightRing1.spell); if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.RightRing1.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.RightRing1.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.RightRing1.charges > 0 && chr.RightRing1.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.RightRing1.charges--; } return(true); } #endregion checkRightRing2: #region Right Ring 2 if (chr.RightRing2 != null && chr.RightRing2.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.RightRing2.spell).Command) { if (chr.RightRing2.charges == 0) { outOfCharges += "The " + chr.RightRing2.name + " is out of charges. "; goto checkRightRing3; } GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.RightRing2.spell); if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.RightRing2.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.RightRing2.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.RightRing2.charges > 0 && chr.RightRing2.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.RightRing2.charges--; } return(true); } #endregion checkRightRing3: #region Right Ring 3 if (chr.RightRing3 != null && chr.RightRing3.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.RightRing3.spell).Command) { if (chr.RightRing3.charges == 0) { outOfCharges += "The " + chr.RightRing3.name + " is out of charges. "; goto checkRightRing4; } GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.RightRing3.spell); if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.RightRing3.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.RightRing3.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.RightRing3.charges > 0 && chr.RightRing3.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.RightRing3.charges--; } return(true); } #endregion checkRightRing4: #region Right Ring 4 if (chr.RightRing4 != null && chr.RightRing4.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.RightRing4.spell).Command) { if (chr.RightRing4.charges == 0) { outOfCharges += "The " + chr.RightRing4.name + " is out of charges. "; goto checkLeftRing1; } GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.RightRing4.spell); if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.RightRing4.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.RightRing4.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.RightRing4.charges > 0 && chr.RightRing4.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.RightRing4.charges--; } return(true); } #endregion checkLeftRing1: #region Left Ring 1 if (chr.LeftRing1 != null && chr.LeftRing1.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.LeftRing1.spell).Command) { if (chr.LeftRing1.charges == 0) { outOfCharges += "The " + chr.LeftRing1.name + " is out of charges. "; goto checkLeftRing2; } GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.LeftRing1.spell); if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.LeftRing1.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.LeftRing1.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.LeftRing1.charges > 0 && chr.LeftRing1.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.LeftRing1.charges--; } return(true); } #endregion checkLeftRing2: #region Left Ring 2 if (chr.LeftRing2 != null && chr.LeftRing2.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.LeftRing2.spell).Command) { if (chr.LeftRing2.charges == 0) { outOfCharges += "The " + chr.LeftRing2.name + " is out of charges. "; goto checkLeftRing3; } GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.LeftRing2.spell); if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.LeftRing2.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.LeftRing2.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.LeftRing2.charges > 0 && chr.LeftRing2.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.LeftRing2.charges--; } return(true); } #endregion checkLeftRing3: #region Left Ring 3 if (chr.LeftRing3 != null && chr.LeftRing3.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.LeftRing3.spell).Command) { if (chr.LeftRing3.charges == 0) { outOfCharges += "The " + chr.LeftRing3.name + " is out of charges. "; goto checkLeftRing4; } GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.LeftRing3.spell); if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.LeftRing3.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.LeftRing3.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.LeftRing3.charges > 0 && chr.LeftRing3.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.LeftRing3.charges--; } return(true); } #endregion checkLeftRing4: #region Left Ring 4 if (chr.LeftRing4 != null && chr.LeftRing4.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(chr.LeftRing4.spell).Command) { if (chr.LeftRing4.charges == 0) { outOfCharges += "The " + chr.LeftRing4.name + " is out of charges. "; goto checkInventory; } GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(chr.LeftRing4.spell); if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.LeftRing4.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(chr.LeftRing4.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (chr.LeftRing4.charges > 0 && chr.LeftRing4.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { chr.LeftRing4.charges--; } return(true); } #endregion checkInventory: #region Inventory for (int a = 0; a < chr.wearing.Count; a++) { Item item = (Item)chr.wearing[a]; if (item != null && item.spell > 0 && sArgs[0].ToLower() == GameSpell.GetSpell(item.spell).Command) { if (item.charges == 0) { if (item.spell != (int)GameSpell.GameSpellID.Venom) { outOfCharges += "The " + item.name + " is out of charges. "; } } else { GameSpell storedSpell = chr.preppedSpell; long storedMagicSkill = chr.magic; chr.preppedSpell = GameSpell.GetSpell(item.spell); // Found an item with the spell venom. This will mean the item may be charged with venom. if (storedSpell != null && storedSpell.ID != (int)GameSpell.GameSpellID.Venom && chr.preppedSpell.ID == (int)GameSpell.GameSpellID.Venom && sArgs[0].ToLower() == "venom") { chr.WriteToDisplay("Items must be envenomed, or recharged with venom, by the spell."); chr.preppedSpell = storedSpell; continue; } if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (item.spellPower <= 0) { chr.magic = Skills.GetSkillForLevel(chr.preppedSpell.RequiredLevel); } else { chr.magic = Skills.GetSkillForLevel(item.spellPower); } chr.preppedSpell.CastSpell(chr, args); chr.preppedSpell = storedSpell; chr.magic = storedMagicSkill; if (item.charges > 0 && item.charges < Item.NUM_FOR_UNLIMITED_CHARGES) { item.charges--; } chr.wearing[a] = item; return(true); } } } #endregion } catch (Exception e) { Utils.LogException(e); } #endregion #region Knight or Ravager Spell if (chr.BaseProfession == Character.ClassType.Knight || chr.BaseProfession == Character.ClassType.Ravager) // caster is a knight or ravager { if (chr.HasKnightRing) // knight or ravager is wearing their ring { try { if (chr.IsPC) // npc knights already prepped their spell in Creature.prepareSpell { GameSpell spell = GameSpell.GetSpell(sArgs[0].ToLower()); if (spell != null && spell.IsClassSpell(chr.BaseProfession) && spell.IsAvailableAtTrainer && chr.Level >= spell.RequiredLevel) { chr.preppedSpell = GameSpell.GetSpell(sArgs[0].ToLower()); } else { if (outOfCharges != "") { chr.WriteToDisplay(outOfCharges); } else { chr.WriteToDisplay("You do not know that spell. You have not learned it or do not meet the level requirement to cast it."); } return(true); } } if (chr.preppedSpell != null) { // lawful knight or evil ravager if ((chr.Alignment == Globals.eAlignment.Lawful && chr.BaseProfession == Character.ClassType.Knight) || (chr.Alignment == Globals.eAlignment.Evil && chr.BaseProfession == Character.ClassType.Ravager)) { if (chr.Mana < chr.preppedSpell.ManaCost) // knight does not have enough mana { chr.WriteToDisplay("You do not have enough mana to cast the spell."); // message chr.preppedSpell = null; // remove the prepped spell return(true); } chr.preppedSpell.CastSpell(chr, args); chr.Mana -= chr.preppedSpell.ManaCost; chr.preppedSpell = null; chr.updateMP = true; } else // someone other than a lawful knight or evil ravager is using a ring with the "knight effect" { Item ring = null; chr.preppedSpell = null; for (int rnum = 1; rnum < 5; rnum++) { // check right ring = chr.GetSpecificRing(true, rnum); if (ring != null && (ring.itemID == Item.ID_KNIGHTRING || ring.itemID == Item.ID_RAVAGERRING)) { chr.WriteToDisplay("Your " + ring.identifiedName + " explodes!"); Combat.DoSpellDamage(chr, chr, null, Rules.RollD(2, 12), "concussion"); chr.SetSpecificRing(true, rnum, null); } // check left ring = chr.GetSpecificRing(false, rnum); if (ring != null && (ring.itemID == Item.ID_KNIGHTRING || ring.itemID == Item.ID_RAVAGERRING)) { chr.WriteToDisplay("Your " + ring.identifiedName + " explodes!"); Combat.DoSpellDamage(chr, chr, null, Rules.RollD(2, 12), "concussion"); chr.SetSpecificRing(false, rnum, null); } } } } return(true); } catch (Exception e) { Utils.Log("Command.cast(" + args + ") by " + chr.GetLogString(), Utils.LogType.CommandFailure); Utils.LogException(e); return(true); } } else { chr.WriteToDisplay("You are not wearing your " + Utils.FormatEnumString(chr.BaseProfession.ToString()) + "'s ring."); return(true); } } #endregion normalSpell: #region Normal Spell try { bool memorizedSpell = false; // Check if a spell is not prepared. Spells ALWAYS go to the preppedSpell object before being cast. if (chr.preppedSpell == null) { if (outOfCharges != "") { chr.WriteToDisplay(outOfCharges); chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.SpellFail)); } else { chr.WriteToDisplay("You don't have a spell warmed."); } if (!string.IsNullOrEmpty(chr.MemorizedSpellChant)) { if (chr.HasEffect(Effect.EffectTypes.Silence)) { chr.WriteToDisplay("You have been silenced."); return(true); } memorizedSpell = true; string[] mArgs = chr.MemorizedSpellChant.Split(" ".ToCharArray()); chr.CommandWeight = 0; CommandTasker.ParseCommand(chr, mArgs[0], mArgs[1] + " " + mArgs[2] + " " + mArgs[3]); } else { return(true); } } if (memorizedSpell) { if (chr.Stamina < Talents.MemorizeTalent.STAMINA_COST) { chr.WriteToDisplay("You do not have enough stamina to cast your memorized spell."); chr.preppedSpell = null; chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.SpellFail)); return(true); } chr.Stamina -= Talents.MemorizeTalent.STAMINA_COST; // reduce stamina whether the spell is cast or not, or whether if fails or succeeds } // memorized spell costs more mana int manaCost = memorizedSpell ? chr.preppedSpell.ManaCost + (chr.preppedSpell.ManaCost / 2) : chr.preppedSpell.ManaCost; // Check spell failure for newbie thaumaturge players casting higher level spells. if (chr.IsWisdomCaster && chr.IsPC) { if (Rules.CheckSpellFailure(Skills.GetSkillLevel(chr.magic), chr.preppedSpell.RequiredLevel)) { chr.Mana -= manaCost; chr.preppedSpell = null; chr.WriteToDisplay("The spell fizzles."); chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.SpellFail)); return(true); } } // Spell failure if not enough mana. if (chr.Mana < manaCost) { chr.Mana -= manaCost; chr.preppedSpell = null; chr.WriteToDisplay("The spell fails."); chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.SpellFail)); return(true); } else { // If no arguments then this spell will be cast at us (if it requires a target). if (args == null) { args = chr.preppedSpell.Command + " " + chr.Name; } if (chr.preppedSpell.CastSpell(chr, args)) { if (chr != null) { // give skill experience for casting a spell that requires mana int magicSkillLevel = Skills.GetSkillLevel(chr.magic); int bonusForHighSkill = 1; if (magicSkillLevel >= 11) { bonusForHighSkill = magicSkillLevel - 9; } int addend = chr.NumAttackers; // Adjustment here for Thief profession, both because they are hidden when casting and lack numAttackers and they do not // gain as much magic skill experience since they do not target enemies with spells. if (chr.BaseProfession == Character.ClassType.Thief) { addend += Skills.GetSkillLevel(chr.magic) / 2; } int skillAmount = (manaCost + addend) * magicSkillLevel * bonusForHighSkill; Skills.GiveSkillExp(chr, skillAmount, Globals.eSkillType.Magic); #region Give random experience if current map is 'magic intense' if (chr.Map.HasRandomMagicIntensity && chr.IsSpellWarmingProfession && (Rules.RollD(1, 6) == Rules.RollD(1, 6))) { switch (chr.BaseProfession) { case Character.ClassType.Wizard: chr.WriteToDisplay("Static electricity gathers around you and then dissipates gradually."); break; case Character.ClassType.Thaumaturge: chr.WriteToDisplay("An almost overwhelming feeling of serenity passes through you."); break; case Character.ClassType.Sorcerer: chr.WriteToDisplay("Black wisps of acrid smoke rapidly encircle your entire body and then slowly fade away."); break; default: chr.WriteToDisplay("You feel a rush of adrenalin coursing through your body."); break; } if (chr != null && chr.preppedSpell != null) { Skills.GiveSkillExp(chr, manaCost * (Skills.GetSkillLevel(chr.magic) * Rules.RollD(2, 4)), Globals.eSkillType.Magic); } } #endregion if (chr.preppedSpell != null) { chr.Mana -= manaCost; chr.preppedSpell = null; } } } else { if (chr != null) { if (chr.preppedSpell != null) { chr.Mana -= chr.preppedSpell.ManaCost; } chr.preppedSpell = null; chr.WriteToDisplay(GameSystems.Text.TextManager.YOUR_SPELL_FAILS); chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.SpellFail)); } } } if (chr != null) // NPC could be null due to death { chr.CommandWeight += 3; } return(true); } catch (Exception e) { Utils.Log("Command.cast(" + args + ") by " + chr.GetLogString(), Utils.LogType.CommandFailure); Utils.LogException(e); return(true); } #endregion }
public bool OnCommand(Character chr, string args) { if (chr.CommandWeight > 3) { chr.WriteToDisplay("Command weight limit exceeded. Scribe command not processed."); return(true); } // TODO: Implement a scribe skill, ability or tradeskill. if (Array.IndexOf(GameWorld.World.SpellWarmingProfessions, chr.BaseProfession) == -1 || chr.Level < Globals.MIN_SCRIBE_LEVEL) { chr.WriteToDisplay("You do not know how to scribe spells."); return(true); } else { var scroll = chr.FindHeldItem(args); if (scroll == null) { chr.WriteToDisplay("You are not holding a " + args + "."); return(true); } var spell = GameSpell.GetSpell(scroll.spell); if (spell == null || !spell.IsClassSpell(chr.BaseProfession)) { chr.WriteToDisplay("You cannot scribe this " + scroll.name + "."); return(true); } if (!GameWorld.Map.IsNextToScribingCrystal(chr)) { chr.WriteToDisplay("You are not in the proper location to scribe a spell."); return(true); } var spellbook = chr.FindHeldItem(Item.ID_SPELLBOOK); if (spellbook == null || spellbook.attunedID != chr.UniqueID) { chr.WriteToDisplay("You must be holding your spellbook when scribing a spell."); return(true); } if (!spell.IsFoundForScribing) { chr.WriteToDisplay("You cannot scribe this " + scroll.name + ". It may be cast by reading it aloud."); return(true); } if (chr.spellDictionary.ContainsKey(spell.ID)) { chr.WriteToDisplay("You already know the spell " + spell.Name + "."); return(true); } if (Skills.GetSkillLevel(chr.magic) < spell.RequiredLevel) { chr.WriteToDisplay("You are not skilled enough to scribe the spell " + spell.Name + "."); return(true); } // success GameSpell.ScribeSpell(chr, spell); if (scroll == chr.RightHand) { chr.UnequipRightHand(scroll); } else if (scroll == chr.LeftHand) { chr.UnequipLeftHand(scroll); } chr.WriteToDisplay("The " + scroll.name + " disintegrates."); } return(true); }
public bool OnCommand(Character chr, string args) { int num = 0; #region Handle bad arguments or heavy command weight // TODO: add support for "throw # item at <target>" and "throw # item at # target" if (args == null || args == "" || !args.Contains(" ")) { chr.WriteToDisplay( "Usage of throw: throw <item> <target/direction> | throw <left/right> <target/direction> | throw <item> at # <target>"); return(true); } if (chr.CommandWeight > 3) { chr.WriteToDisplay("Command weight limit exceeded. Throw command not processed."); return(true); } #endregion var sArgs = args.Split(" ".ToCharArray()); var rightHand = false; Item item = null; //var thrownAtTarget = false; if (args.Contains(" at ")) { args = args.Replace(" at ", " "); sArgs = args.Split(" ".ToCharArray()); //thrownAtTarget = true; } else { goto ThrowDirection; } // left hand match if (chr.LeftHand != null && (sArgs[0].ToLower() == "left" || chr.LeftHand.name.ToLower().StartsWith(sArgs[0].ToLower()))) { item = chr.LeftHand; } // right hand match else if (chr.RightHand != null && (sArgs[0].ToLower() == "right" || chr.RightHand.name.ToLower().StartsWith(sArgs[0].ToLower()))) { item = chr.RightHand; rightHand = true; } #region Find throwable item on belt // one hand is empty, check belt for items and use FIRST weapon that may be thrown from belt if (item == null && chr.GetFirstFreeHand() != (int)Globals.eWearOrientation.None) { foreach (string throwFromBelt in Item.ThrowFromBelt) { if (throwFromBelt.ToLower().StartsWith(sArgs[0].ToLower())) { item = chr.RemoveFromBelt(throwFromBelt); if (item != null) { switch (chr.GetFirstFreeHand()) { case (int)Globals.eWearOrientation.Right: chr.EquipRightHand(item); rightHand = true; break; case (int)Globals.eWearOrientation.Left: chr.EquipLeftHand(item); rightHand = false; break; default: break; } break; } } } } #endregion if (item == null) { chr.WriteToDisplay("You do not have a " + sArgs[0] + " to throw."); return(true); } #region Thrown item is attuned if (chr.IsPC && item.IsAttunedToOther(chr)) { chr.CurrentCell.Add(item); chr.WriteToDisplay("The " + item.name + " leaps from your hand!"); if (rightHand) { chr.UnequipRightHand(item); } else { chr.UnequipLeftHand(item); } return(true); } #endregion #region Thrown item is aligned if (!item.AlignmentCheck(chr)) { chr.CurrentCell.Add(item); chr.WriteToDisplay("The " + item.name + " singes your hand and falls to the ground!"); if (rightHand) { chr.RightHand = null; Combat.DoDamage(chr, chr, Rules.Dice.Next(1, 4), false); } else { chr.LeftHand = null; Combat.DoDamage(chr, chr, Rules.Dice.Next(1, 4), false); } return(true); } #endregion Character target = null; #region Throw an item at a target // throw <item> <target>, throw <item> # <target>, throw <item> <direction> // throw <item> at # <target> if (sArgs.Length == 3 && char.IsNumber(sArgs[1].ToCharArray()[0])) { num = Convert.ToInt32(sArgs[1]); target = GameSystems.Targeting.TargetAquisition.FindTargetInView(chr, sArgs[2].ToLower(), num); } else { target = GameSystems.Targeting.TargetAquisition.FindTargetInView(chr, sArgs[1].ToLower(), false, chr.IsImmortal); } Cell targetCell = null; var isFigurine = false; if (target != null) { chr.CommandType = CommandTasker.CommandType.Throw; #region Thrown item is a weapon if (item.itemType == Globals.eItemType.Weapon) { targetCell = target.CurrentCell; chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.ThrownWeapon)); Combat.DoCombat(chr, target, item); // Possible double attack if returning weapon. if (item != null && item.returning && target != null && !target.IsDead) { Combat.CheckDoubleAttack(chr, target, item); } if (chr.LeftHand != null && chr.LeftHand.returning && chr.LeftHand.itemType == Globals.eItemType.Weapon && target != null && !target.IsDead) { Combat.CheckDualWield(chr, target, chr.LeftHand); } /* The code below was added by mlt in order to give Carfel extra attacks. * A better way to do this is to add a numAttacks or similar attribute to the Character class. */ #region Carfel hard code //if (!chr.IsPC && chr.Name == "Carfel" && target != null && !target.IsDead) //{ // Combat.DoCombat(chr, target, item); // if (target != null && !target.IsDead) // { // Combat.DoCombat(chr, target, item); // } //} #endregion #region Weapon with "figurine" in special - eg: Ebonwood Staff (snake staff) if (item.special.Contains("figurine")) { if (item == chr.RightHand) { chr.UnequipRightHand(item); } else if (item == chr.LeftHand) { chr.UnequipLeftHand(item); } Rules.SpawnFigurine(item, targetCell, chr); } #endregion } #endregion #region else if Figurine thrown at a target else if (item.special.ToLower().Contains("figurine") || item.baseType == Globals.eItemBaseType.Figurine || item.itemID == Item.ID_EBONSNAKESTAFF) // if thrown item is figurine { isFigurine = true; // breakable chance if figurine is fragile if (item.fragile) { // 2d100 roll for fig break var figBreakRoll = Rules.RollD(2, 100); if (chr.IsLucky && Rules.RollD(1, 100) >= 10) { figBreakRoll++; } // two 1's are rolled, character is not lucky if (figBreakRoll == 2) { target.SendShout("something shatter into a hundred pieces."); target.EmitSound(Sound.GetCommonSound(Sound.CommonSound.BreakingGlass)); //TODO implement NPCs throwing figurines Utils.Log(chr.GetLogString() + " broke a figurine. Item ID: " + item.GetLogString() + " FigExp: " + item.figExp.ToString(), Utils.LogType.ItemFigurineUse); } else { Rules.SpawnFigurine(item, target.CurrentCell, chr); } } else { Rules.SpawnFigurine(item, target.CurrentCell, chr); } } #endregion #region else if Bottle thrown at a target else if (item.baseType == Globals.eItemBaseType.Bottle || item is SoulGem) // what to do if the thrown item is a bottle { if (Combat.CheckFumble(chr, item)) { target = chr; chr.SendToAllInSight(chr.Name + " fumbles!"); chr.WriteToDisplay("You fumble!"); } if (item.effectType.Length > 0) { var effectTypes = item.effectType.Split(" ".ToCharArray()); var effectAmounts = item.effectAmount.Split(" ".ToCharArray()); var effectDurations = item.effectDuration.Split(" ".ToCharArray()); for (int a = 0; a < effectTypes.Length; a++) { var effectType = (Effect.EffectTypes)Convert.ToInt32(effectTypes[a]); if (effectType == Effect.EffectTypes.Nitro) { GameSpell.CastGenericAreaSpell(target.CurrentCell, "", Effect.EffectTypes.Nitro, Convert.ToInt32(effectAmounts[a]), ""); } else if (effectType == Effect.EffectTypes.Naphtha) { var cells = new ArrayList { target.CurrentCell }; var effect = new AreaEffect(Effect.EffectTypes.Fire, Cell.GRAPHIC_FIRE, Convert.ToInt32(effectAmounts[a]), Convert.ToInt32(effectDurations[a]), chr, cells); } } } if (item.baseType == Globals.eItemBaseType.Bottle) { target.SendShout("the sound of glass shattering."); } else { target.SendShout("the sound of something shattering."); } target.EmitSound(Sound.GetCommonSound(Sound.CommonSound.BreakingGlass)); if (item == chr.LeftHand) { chr.UnequipLeftHand(item); } if (item == chr.RightHand) { chr.UnequipRightHand(item); } } #endregion else { #region all other thrown objects targetCell = target.CurrentCell; if (Rules.RollD(1, 2) == 1) { chr.WriteToDisplay("Your " + item.name + " bounces harmlessly off of " + target.GetNameForActionResult(true) + "."); } else { chr.WriteToDisplay("You miss!"); } target.WriteToDisplay(chr.GetNameForActionResult() + " misses you!"); if (targetCell != null && !targetCell.Items.Contains(item)) { if (!item.special.Contains("figurine")) { targetCell.Add(item); if (chr.RightHand == item) { chr.UnequipRightHand(item); } else if (chr.LeftHand == item) { chr.UnequipLeftHand(item); } } } #endregion } } else { if (num > 0) { chr.WriteToDisplay(GameSystems.Text.TextManager.NullTargetMessage(sArgs[1] + " " + sArgs[2])); } else { chr.WriteToDisplay(GameSystems.Text.TextManager.NullTargetMessage(sArgs[1])); } return(true); } // ** item may have been removed from hand if fumbled result in Rules.doCombat // if the attack caused fatal damage the item is removed in Combat.DND_Attack if (rightHand && chr.RightHand != null && !item.returning && targetCell != null && !targetCell.Items.Contains(item)) { if (!item.fragile && !isFigurine) { targetCell.Add(item); } chr.UnequipRightHand(item); } else if (!rightHand && chr.LeftHand != null && !item.returning && targetCell != null && !targetCell.Items.Contains(item)) { if (!item.fragile && !isFigurine) { targetCell.Add(item); } chr.UnequipLeftHand(item); } return(true); #endregion ThrowDirection: // left hand match if (chr.LeftHand != null && (sArgs[0].ToLower() == "left" || chr.LeftHand.name.ToLower().StartsWith(sArgs[0].ToLower()))) { item = chr.LeftHand; } // right hand match else if (chr.RightHand != null && (sArgs[0].ToLower() == "right" || chr.RightHand.name.ToLower().StartsWith(sArgs[0].ToLower()))) { item = chr.RightHand; rightHand = true; } if (item == null) { chr.WriteToDisplay("You do not have a " + sArgs[0] + " to throw."); return(true); } #region Throw an item in a direction // not throwing an item AT a target args = ""; for (int a = 1; a < sArgs.Length; a++) { args += sArgs[a] + " "; } Cell cell = Map.GetCellRelevantToCell(chr.CurrentCell, args.Substring(0, args.Length - 1), true); if (cell != chr.CurrentCell) { var pathTest = new PathTest(PathTest.RESERVED_NAME_THROWNOBJECT, chr.CurrentCell); if (!pathTest.SuccessfulPathTest(cell)) { cell = chr.CurrentCell; } pathTest.RemoveFromWorld(); } int totalHeight = 0; // used to record how fall an object falls if (cell != null && cell.DisplayGraphic == Cell.GRAPHIC_AIR) { Segue segue = null; int countLoop = 0; do { segue = Segue.GetDownSegue(Cell.GetCell(cell.FacetID, cell.LandID, cell.MapID, cell.X, cell.Y, cell.Z)); countLoop++; if (segue != null) { cell = Cell.GetCell(cell.FacetID, segue.LandID, segue.MapID, segue.X, segue.Y, segue.Z); totalHeight += segue.Height; } else { break; } } while (cell.CellGraphic == Cell.GRAPHIC_AIR && countLoop < 100); } if (item.effectType.Length > 0) { #region Thrown item causes an effect string[] effectTypes = item.effectType.Split(" ".ToCharArray()); string[] effectAmounts = item.effectAmount.Split(" ".ToCharArray()); string[] effectDurations = item.effectDuration.Split(" ".ToCharArray()); for (int a = 0; a < effectTypes.Length; a++) { Effect.EffectTypes effectType = (Effect.EffectTypes)Convert.ToInt32(effectTypes[a]); if (effectType == Effect.EffectTypes.Nitro) { GameSpell.CastGenericAreaSpell(cell, "", Effect.EffectTypes.Nitro, Convert.ToInt32(effectAmounts[a]), "concussion", chr); } else if (effectType == Effect.EffectTypes.Naphtha) { ArrayList cells = new ArrayList { cell }; AreaEffect effect = new AreaEffect(Effect.EffectTypes.Fire, Cell.GRAPHIC_FIRE, Convert.ToInt32(effectAmounts[a]), Convert.ToInt32(effectDurations[a]), chr, cells); } } if (item.baseType == Globals.eItemBaseType.Bottle) { if (cell.DisplayGraphic != Cell.GRAPHIC_WATER) { cell.SendShout("the sound of glass shattering."); cell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.BreakingGlass)); } else { cell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.Splash)); } } else if (item.fragile) { int breakRoll = Rules.RollD(1, 100); // add experience level of figurine to roll if (item.baseType == Globals.eItemBaseType.Figurine) { breakRoll += Rules.GetExpLevel(item.figExp); // less chance for a lucky character to break a figurine if (chr.IsLucky && Rules.RollD(1, 100) >= 10) { breakRoll += 20; } } if (breakRoll > 25) { cell.Add(item); } else { cell.SendShout("something shatter into pieces."); cell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.BreakingGlass)); if (item.baseType == Globals.eItemBaseType.Figurine) { Utils.Log(chr.GetLogString() + " broke a figurine. Item ID: " + item.GetLogString() + " FigExp: " + item.figExp.ToString(), Utils.LogType.ItemFigurineUse); } } } else { cell.Add(item); } #endregion } else { #region if figurine or snake staff thrown direction if (item.baseType == Globals.eItemBaseType.Figurine || item.special.ToLower().IndexOf("snake") > -1) // if thrown item is figurine { // breakable chance if figurine is fragile if (item.fragile) { // 2d100 roll for fig break int figBreakRoll = Rules.RollD(2, 100); // still a small chance for the figurine to break if (chr.IsLucky && Rules.RollD(1, 100) >= 10) { figBreakRoll++; } // every 20 feet of height dropped increases the chance of a break if (totalHeight > 0) { figBreakRoll -= Convert.ToInt32(totalHeight / 20); } if (figBreakRoll <= 2) { cell.SendShout("something shatter into a hundred pieces."); cell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.BreakingGlass)); Utils.Log(chr.GetLogString() + " broke a figurine. Item ID: " + item.GetLogString() + " FigExp: " + item.figExp.ToString(), Utils.LogType.ItemFigurineUse); } else { Rules.SpawnFigurine(item, cell, chr); } } else { Rules.SpawnFigurine(item, cell, chr); } } #endregion #region else if fragile else if (item.fragile) { int breakRoll = Rules.RollD(1, 100); // increase chance to break with every 20 feet dropped if (totalHeight > 0) { breakRoll -= Convert.ToInt32(totalHeight / 20); } if (item is SoulGem) { breakRoll -= 100; } if (cell != null) { // 25% chance to break if (breakRoll > 25) { cell.Add(item); } else { cell.SendShout("something shatter into pieces."); cell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.BreakingGlass)); } } } #endregion else if (cell != null) { cell.Add(item); } } if (rightHand) { chr.UnequipRightHand(item); } else { chr.UnequipLeftHand(item); } #endregion return(true); }
public bool OnCommand(Character chr, string args) { Book book; int pagesToFlip = 0; int iArgCount = 0; if (chr.RightHand != null && chr.RightHand.baseType == Globals.eItemBaseType.Book) // get the book from hand { book = (Book)chr.RightHand; } else if (chr.LeftHand != null && chr.LeftHand.baseType == Globals.eItemBaseType.Book) { book = (Book)chr.LeftHand; } else { chr.WriteToDisplay("You are not holding a book."); return(true); } try { if (args == null) { args = "1"; // flip all alone should advance one page } String[] sArgs = args.Split(" ".ToCharArray()); iArgCount = sArgs.GetUpperBound(0) + 1; // Start filtering out too many/wrong args if (iArgCount > 3 || (iArgCount == 3 && (sArgs[0].ToLower() != "book" && sArgs[0].ToLower() != "spellbook"))) // FLIP Book TO # { chr.WriteToDisplay("Usage: Flip [back / forward / to] [number]"); return(true); } if (iArgCount == 3) // only way this is true is if first arg is "book" or "spellbook", so we eliminate it { sArgs[0] = sArgs[1]; sArgs[1] = sArgs[2]; iArgCount = 2; } if (iArgCount == 2) // make sure the second argument, if there is one, is numeric { try { pagesToFlip = Convert.ToInt32(sArgs[1]); } catch { chr.WriteToDisplay("Format: Flip [back / forward / to] [number]"); return(true); } } switch (sArgs[0].ToLower()) { case "back": if (iArgCount == 1) // FLIP BACK { pagesToFlip = -1; } else // FLIP BACK # { pagesToFlip = pagesToFlip * -1; } break; case "forward": pagesToFlip = pagesToFlip * 1; break; case "to": pagesToFlip = pagesToFlip - book.CurrentPage; //pagesToFlip = pagesToFlip - 1;//pagesToFlip = pagesToFlip - currentPage; break; case "page": // FLIP PAGE - turn one page pagesToFlip = 1; break; case "book": // READ Book ends up here. So just read the current page. break; default: // either it's a number or it's bad input try { pagesToFlip = Convert.ToInt32(sArgs[0]); } catch { chr.WriteToDisplay("Format: Flip [back / forward / to] [number]"); return(true); } break; } if (book.CurrentPage + pagesToFlip <= 0) // the book does not have a negative amount of pages, set to 0 { book.CurrentPage = 1; } else if (book.BookType != Book.BookTypes.Spellbook && book.CurrentPage + pagesToFlip > (int)book.Pages.Length / 2) { book.CurrentPage = (int)(book.Pages.Length / 2) - 1; } else { book.CurrentPage = book.CurrentPage + pagesToFlip; } if (book.BookType == Book.BookTypes.Spellbook) { if (book.attunedID != chr.UniqueID) // do not allow a player to read another player's spellbook { chr.WriteToDisplay("The book is sealed shut."); return(true); } else { List <int> knownSpellIDs = new List <int>(chr.spellDictionary.Keys); List <string> knownSpellChants = new List <string>(chr.spellDictionary.Values); if (book.CurrentPage > chr.spellDictionary.Count) // page is blank { chr.WriteToDisplay("That page is blank."); return(true); } int spellID = knownSpellIDs[book.CurrentPage - 1]; chr.WriteToDisplay("Page " + (book.CurrentPage) + ":"); GameSpell spell = GameSpell.GetSpell(spellID); chr.WriteToDisplay("The incantation for " + spell.Name + " (" + spell.Command + ")"); chr.WriteToDisplay(knownSpellChants[book.CurrentPage - 1]); } } else { chr.WriteToDisplay(book.ReadPage()); } } catch (Exception e) { Utils.Log("Command.flip(" + args + ") by " + chr.GetLogString(), Utils.LogType.CommandFailure); Utils.LogException(e); chr.WriteToDisplay("That page was not found."); return(true); } return(true); }
public bool OnCommand(Character chr, string args) { if (args.IndexOf("book") != -1) // "read book" is the same as "flip book" { return(CommandTasker.ParseCommand(chr, "flip", args)); } bool rightHand = true; if (args == null) { if (chr.RightHand != null && chr.RightHand.baseType == Globals.eItemBaseType.Book) { return(CommandTasker.ParseCommand(chr, "flip", args)); } if (chr.RightHand != null && chr.RightHand.baseType == Globals.eItemBaseType.Scroll) { goto readScroll; } if (chr.LeftHand != null && chr.LeftHand.baseType == Globals.eItemBaseType.Book) { return(CommandTasker.ParseCommand(chr, "flip", args)); } if (chr.LeftHand != null && chr.LeftHand.baseType == Globals.eItemBaseType.Scroll) { rightHand = false; } } readScroll: // verification if ((rightHand && (chr.RightHand == null || chr.RightHand.baseType != Globals.eItemBaseType.Scroll)) || (!rightHand && (chr.LeftHand == null || chr.LeftHand.baseType != Globals.eItemBaseType.Scroll))) { chr.WriteToDisplay("You are unable to read that. Try bringing it to someone who can."); return(true); } Item scroll = rightHand ? chr.RightHand : chr.LeftHand; if ((scroll as Book).Pages == null || (scroll as Book).Pages[0] == "") { if (scroll.spell > -1) { GameSpell scrollSpell = GameSpell.GetSpell(chr.RightHand.spell); if (!scrollSpell.IsClassSpell(chr.BaseProfession)) { chr.WriteToDisplay("The " + scroll.name + " contains runes that are illegible to you."); } else { if (chr.spellDictionary.ContainsKey(scrollSpell.ID)) { chr.WriteToDisplay("The " + chr.RightHand.name + " contains the spell of " + scrollSpell.Name + "."); // TODO: Implement the ability to see how many charges and perhaps how powerful the spell is. } else { chr.WriteToDisplay("The " + scroll.name + " contains a " + Utils.FormatEnumString(chr.BaseProfession.ToString()).ToLower() + " spell that is unfamiliar to you." + (Skills.GetSkillLevel(chr.magic) >= scrollSpell.RequiredLevel ? " With enough effort you believe this scroll could be scribed into your spellbook." : "")); // TODO: Should the player be informed that the spell can be scribed or not? -- added 1/25/2019 Eb } } } else // blank scroll { chr.WriteToDisplay("The scroll is blank."); // TODO: Does this mean a spell can be added to the scroll? } } return(true); }