示例#1
0
        /// <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);
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        /// <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);
        }
示例#8
0
        //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
        }
示例#9
0
        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);
        }
示例#10
0
        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);
        }
示例#11
0
        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);
        }
示例#12
0
        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);
        }