Exemple #1
0
        public bool OnCast(Character caster, string args)
        {
            if (Map.IsNextToWall(caster))
            {
                if (!Rules.BreakHideSpell(caster))
                {
                    bool giveXP = false;
                    if (!caster.IsHidden && caster.BaseProfession == Character.ClassType.Thief)
                    {
                        giveXP = true;
                    }

                    Effect.CreateCharacterEffect(Effect.EffectTypes.Hide_in_Shadows, 1, caster, 0, caster);
                    caster.WriteToDisplay("You fade into the shadows.");

                    if (giveXP)
                    {
                        Skills.GiveSkillExp(caster, Skills.GetSkillLevel(caster.thievery) * 25, Globals.eSkillType.Thievery);
                    }
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                caster.WriteToDisplay("You must be in the shadows to hide.");
            }

            return(true);
        }
Exemple #2
0
        public bool OnCommand(Character chr, string args)
        {
            if (chr.CommandWeight > 3)
            {
                return(true);
            }

            if (args == null || args == "")
            {
                if (!chr.CurrentCell.IsBalmFountain && !Map.IsNextToBalmFountain(chr))
                {
                    chr.WriteToDisplay("What do you want to drink?");
                    return(true);
                }
                else
                {
                    goto balmFountain;
                }
            }

            if (chr.RightHand != null && chr.RightHand.itemType == Globals.eItemType.Potable)
            {
                if (chr.RightHand.baseType == Globals.eItemBaseType.Bottle)
                {
                    Bottle.DrinkBottle((Bottle)chr.RightHand, chr);
                    return(true);
                }
            }
            else if (chr.LeftHand != null && chr.LeftHand.itemType == Globals.eItemType.Potable)
            {
                if (chr.LeftHand.baseType == Globals.eItemBaseType.Bottle)
                {
                    Bottle.DrinkBottle((Bottle)chr.LeftHand, chr);
                    return(true);
                }
            }
            else //TODO: expand here to allow drinking from a fluid source (eg: fountains)
            {
                chr.WriteToDisplay("You are not holding a bottle.");
                return(true);
            }

balmFountain:
            if (chr.CurrentCell.IsBalmFountain || Map.IsNextToBalmFountain(chr))
            {
                chr.WriteToDisplay("You drink your fill of the refreshing fluid seeping from the balm tree.");

                int effectAmount = chr.HitsFull - chr.Hits;
                if (effectAmount < 0)
                {
                    effectAmount = 0;
                }

                Effect.CreateCharacterEffect(Effect.EffectTypes.Balm, effectAmount, chr, -1, chr);
            }

            return(true);
        }
Exemple #3
0
        public bool OnCast(Character caster, string args)
        {
            args = args.Replace(" at ", "");

            Character target = ReferenceSpell.FindAndConfirmSpellTarget(caster, args);

            int duration = 3; // 3 rounds, base

            if (caster.species == Globals.eSpecies.Arachnid || Autonomy.EntityBuilding.EntityLists.ARACHNID.Contains(caster.entity))
            {
                duration += caster.Level / 2;
            }
            else if (caster.IsSpellWarmingProfession && caster.preppedSpell == GameSpell.GetSpell((int)GameSpell.GameSpellID.Create_Web))
            {
                duration += Skills.GetSkillLevel(caster.magic) / 3;
            }

            duration += Rules.Dice.Next(-1, 1);

            if (target == null)
            {
                Cell targetCell = Map.GetCellRelevantToCell(caster.CurrentCell, args, false);

                if (targetCell != null)
                {
                    AreaEffect effect = new AreaEffect(Effect.EffectTypes.Web, Cell.GRAPHIC_WEB, Skills.GetSkillLevel(caster.magic), duration, caster, targetCell);
                    targetCell.EmitSound(ReferenceSpell.SoundFile);
                }
            }
            else
            {
                AreaEffect effect = new AreaEffect(Effect.EffectTypes.Web, Cell.GRAPHIC_WEB, Skills.GetSkillLevel(caster.magic), duration, caster, target.CurrentCell);
                if (target.CurrentCell != null)
                {
                    target.CurrentCell.EmitSound(ReferenceSpell.SoundFile);
                }
            }

            if (target == null)
            {
                caster.WriteToDisplay("You cast " + ReferenceSpell.Name + ".");
            }
            else
            {
                caster.WriteToDisplay("You cast " + ReferenceSpell.Name + " at " + target.GetNameForActionResult(true).Replace("The ", "the "));
            }
            return(true);
        }
        public bool OnCast(Character caster, string args)
        {
            args = args.Replace(ReferenceSpell.Command, "");
            args = args.Trim();

            Character target = ReferenceSpell.FindAndConfirmSpellTarget(caster, args);
            Cell      dCell  = null;

            if (target == null)
            {
                dCell = Map.GetCellRelevantToCell(caster.CurrentCell, args, false);
            }
            else
            {
                dCell = target.CurrentCell;
            }

            if (dCell == null && target == null)
            {
                return(false);
            }

            //var tCell = Map.GetCellRelevantToCell(caster.CurrentCell, args, true);

            if (dCell != null)
            {
                // destroy all but attuned items
                foreach (var item in new List <Item>(dCell.Items))
                {
                    if (item.attunedID <= 0 && !item.IsArtifact() && !((item is Corpse) && (item as Corpse).IsPlayerCorpse))
                    {
                        dCell.Remove(item);
                    }
                }

                // do spell damage
                foreach (Character chr in dCell.Characters.Values)
                {
                    if (Combat.DoSpellDamage(caster, chr, null, Skills.GetSkillLevel(caster.magic) * 10, ReferenceSpell.Name.ToLower()) == 1)
                    {
                        Rules.GiveAEKillExp(caster, chr);
                    }
                }

                // destroy walls for a while
                if (!dCell.IsMagicDead)
                {
                    if (dCell.DisplayGraphic == Cell.GRAPHIC_WALL)
                    {
                        var newDispGraphic = Rules.RollD(1, 20) >= 10 ? Cell.GRAPHIC_RUINS_LEFT : Cell.GRAPHIC_RUINS_RIGHT;

                        var effect = new AreaEffect(Effect.EffectTypes.Illusion, newDispGraphic, 0, (int)Skills.GetSkillLevel(caster.magic) * 6, caster, dCell);
                        dCell.SendShout("a wall crumbling.");
                    }
                    else if (dCell.DisplayGraphic == Cell.GRAPHIC_RUINS_LEFT || dCell.DisplayGraphic == Cell.GRAPHIC_RUINS_RIGHT)
                    {
                        var newDispGraphic = Rules.RollD(1, 20) >= 10 ? Cell.GRAPHIC_BARREN_LEFT : Cell.GRAPHIC_BARREN_RIGHT;

                        var effect = new AreaEffect(Effect.EffectTypes.Illusion, newDispGraphic, 0, (int)Skills.GetSkillLevel(caster.magic) * 6, caster, dCell);
                        dCell.SendShout("stone crumbling to dust.");
                    }
                }
            }

            ReferenceSpell.SendGenericCastMessage(caster, null, true);

            return(true);
        }
Exemple #5
0
        public bool OnCommand(Character chr, string args)
        {
            if (chr.CommandWeight > 3)
            {
                return(true);
            }

            // args are null, send explanation of the dump command
            if (args == null)
            {
                chr.WriteToDisplay("Usage for the dump command:");
                chr.WriteToDisplay("\"dump <item>\" - dump one <item> from sack onto ground");
                chr.WriteToDisplay("\"dump <item> on <counter | altar>\" - dump one <item> from sack onto counter or altar");
                chr.WriteToDisplay("\"dump <item> in locker\" - dump one <item> from sack into locker");
                chr.WriteToDisplay("\"dump all <items>\" - dump all <items> from sack onto ground");
                chr.WriteToDisplay("\"dump all <items> on <counter | altar>\" - dump all items from sack onto counter or altar");
                chr.WriteToDisplay("\"dump all <items> in locker\" - dump all items from sack into locker");
                return(true);
            }

            String[] sArgs = args.Split(" ".ToCharArray());

            int upperBound = chr.sackList.Count;

            try
            {
                #region dump <item>
                if (sArgs.Length == 1)  // "dump <item>" should just dump one item on the ground or send error message, then return
                {
                    bool itemDumped = false;

                    foreach (Item item in new System.Collections.Generic.List <Item>(chr.sackList))
                    {
                        if (item.name == sArgs[0].Remove(sArgs[0].Length - 1, 1) || item.name == sArgs[0])
                        {
                            chr.CurrentCell.Add(item);
                            chr.sackList.Remove(item);
                            if (item.itemType == Globals.eItemType.Coin)
                            {
                                if (item.coinValue > 1)
                                {
                                    chr.WriteToDisplay("You dumped " + item.coinValue + " coins on the ground.");
                                }
                                else
                                {
                                    chr.WriteToDisplay("You dumped " + item.coinValue + " coin on the ground.");
                                }
                            }
                            else
                            {
                                chr.WriteToDisplay("You dumped " + item.shortDesc + " on the ground.");
                            }
                            itemDumped = true;
                            break; // dump only one item then break out of here
                        }
                    }

                    if (!itemDumped)
                    {
                        chr.WriteToDisplay("You do not have any " + sArgs[0] + " in your sack.");
                    }

                    return(true);
                }
                #endregion

                #region dump all <item> || dump all <item> <prep> <location>
                // "dump all <item>" or "dump all <item> <prep> <location>"
                if (sArgs.Length >= 2 && sArgs[0] == "all")
                {
                    double counter = 0; // counter is used to determine how many, if any, items were dumped (for result message)

                    // "dump all <item>" will dump all <item> on ground
                    if (sArgs.Length == 2)
                    {
                        for (int x = upperBound - 1; x >= 0; x--)
                        {
                            Item item = (Item)chr.sackList[x];

                            // argument matches
                            if (item.name == sArgs[1].Remove(sArgs[1].Length - 1, 1) || item.name == sArgs[1])
                            {
                                chr.CurrentCell.Add(item);
                                chr.sackList.RemoveAt(x);
                                if (item.itemType == Globals.eItemType.Coin)
                                {
                                    counter = item.coinValue;
                                    break;
                                }
                                else
                                {
                                    counter++;
                                }
                            }
                        }

                        // send result message
                        if (counter == 0)
                        {
                            chr.WriteToDisplay("You do not have any " + sArgs[1] + " in your sack.");
                        }
                        else
                        {
                            string plural = "";
                            if (counter > 1 && !sArgs[1].EndsWith("s"))
                            {
                                plural = "s";
                            }
                            chr.WriteToDisplay("You dumped " + counter + " " + sArgs[1] + plural + " on the ground.");
                        }
                        return(true);
                    }
                    else
                    {
                        Item item       = null;
                        Item dumpedItem = null;

                        switch (sArgs[2])
                        {
                        case "on":     // dump all <item> on counter/altar

                            // if not standing near a counter or altar send error message and return
                            if (!Map.IsNextToCounter(chr))
                            {
                                chr.WriteToDisplay("You are not standing near a counter or altar.");
                                return(true);
                            }

                            // iterate through sackList
                            for (int x = upperBound - 1; x >= 0; x--)
                            {
                                item = (Item)chr.sackList[x];

                                if (item.name == sArgs[1].Remove(sArgs[1].Length - 1, 1) || item.name == sArgs[1])
                                {
                                    Map.PutItemOnCounter(chr, item);
                                    dumpedItem = item;
                                    chr.sackList.RemoveAt(x);
                                    counter++;
                                }
                            }

                            if (dumpedItem != null && dumpedItem.itemType == Globals.eItemType.Coin)
                            {
                                if (dumpedItem.coinValue > 1)
                                {
                                    chr.WriteToDisplay("You dumped " + dumpedItem.coinValue + " coins on the " + sArgs[3] + ".");
                                }
                                else
                                {
                                    chr.WriteToDisplay("You dumped " + dumpedItem.coinValue + " coin on the " + sArgs[3] + ".");
                                }
                            }
                            else
                            {
                                if (counter == 0)
                                {
                                    chr.WriteToDisplay("You do not have any " + sArgs[1] + " in your sack.");
                                }
                                else if (counter == 1)
                                {
                                    chr.WriteToDisplay("You dumped " + counter + " " + sArgs[1] + " on the " + sArgs[3] + ".");
                                }
                                else
                                {
                                    string plural = "";
                                    if (!sArgs[1].EndsWith("s"))
                                    {
                                        plural = "s";
                                    }
                                    chr.WriteToDisplay("You dumped " + counter + " " + sArgs[1] + plural + " on the " + sArgs[3] + ".");
                                }
                            }
                            break;

                        case "in":     // dump all <item> in locker -- currently (4/5/2013) lockers are the only thing you can dump items IN
                            if (!chr.CurrentCell.IsLocker)
                            {
                                chr.WriteToDisplay("You are not standing next to your locker.");
                                return(true);
                            }
                            else
                            {
                                for (int x = upperBound - 1; x >= 0; x--)
                                {
                                    item = (Item)chr.sackList[x];

                                    // argument match
                                    if (item.name == sArgs[1].Remove(sArgs[1].Length - 1, 1) || item.name == sArgs[1])
                                    {
                                        if (item.itemType == Globals.eItemType.Coin)
                                        {
                                            chr.WriteToDisplay("You cannot store coins in your locker.");
                                            return(true);
                                        }
                                        if (chr.lockerList.Count < Character.MAX_LOCKER)
                                        {
                                            chr.lockerList.Add(item);
                                            chr.sackList.RemoveAt(x);
                                            counter++;
                                        }
                                        else
                                        {
                                            string plural = "";
                                            if (!sArgs[1].EndsWith("s"))
                                            {
                                                plural = "s";
                                            }
                                            chr.WriteToDisplay("You dumped " + counter + " " + sArgs[1] + plural + " into your locker. Your locker is full.");
                                            return(true);
                                        }
                                    }
                                }
                                chr.WriteToDisplay("You dumped " + counter + " " + sArgs[1] + "s into your locker.");
                            }
                            break;

                        default:     // by default, "dump all <item>" will dump all items to current cell
                            for (int x = upperBound - 1; x >= 0; x--)
                            {
                                item = (Item)chr.sackList[x];
                                if (item.name == sArgs[0].Remove(sArgs[0].Length - 1, 1) || item.name == sArgs[0])
                                {
                                    chr.CurrentCell.Add(item);
                                    chr.sackList.RemoveAt(x);
                                    counter++;
                                }
                            }
                            string plurals = "";
                            if (!sArgs[1].EndsWith("s"))
                            {
                                plurals = "s";
                            }
                            chr.WriteToDisplay("You dumped " + counter + " " + sArgs[1] + plurals + " on the ground.");
                            break;
                        }
                    }
                    return(true);
                }
                #endregion

                #region dump <item> <prep> <location>
                switch (sArgs[1])
                {
                case "on":
                    for (int x = upperBound - 1; x >= 0; x--)
                    {
                        Item item = (Item)chr.sackList[x];

                        // argument match
                        if (item.name == sArgs[0].Remove(sArgs[0].Length - 1, 1) || item.name == sArgs[0])
                        {
                            if (Map.IsNextToCounter(chr))
                            {
                                Map.PutItemOnCounter(chr, item);
                                chr.sackList.RemoveAt(x);
                                chr.WriteToDisplay("You dumped " + item.shortDesc + " on the " + sArgs[2] + ".");
                                break;     // stop at one item because first argument is not "all"
                            }
                            else
                            {
                                chr.CurrentCell.Add(item);
                                chr.sackList.RemoveAt(x);
                                chr.WriteToDisplay("You dumped " + item.shortDesc + " on the ground.");
                                break;     // stop at one item because first argument is not "all"
                            }
                        }
                    }
                    break;

                case "in":     // dump <item> in locker -- currently (4/5/2013) lockers are the only thing you can dump items IN
                    if (!chr.CurrentCell.IsLocker)
                    {
                        chr.WriteToDisplay("You are not standing next to your locker.");
                        return(true);
                    }
                    else
                    {
                        if (chr.lockerList.Count >= Character.MAX_LOCKER)
                        {
                            chr.WriteToDisplay("Your locker is full.");
                            return(true);
                        }

                        for (int x = upperBound - 1; x >= 0; x--)
                        {
                            Item item = (Item)chr.sackList[x];

                            // argument match
                            if (item.name == sArgs[0].Remove(sArgs[0].Length - 1, 1) || item.name == sArgs[0])
                            {
                                if (item.itemType == Globals.eItemType.Coin)
                                {
                                    chr.WriteToDisplay("You cannot store coins in your locker.");
                                    break;
                                }
                                chr.lockerList.Add(item);
                                chr.sackList.RemoveAt(x);
                                chr.WriteToDisplay("You dumped " + item.shortDesc + " in your locker.");
                                break;
                            }
                        }
                    }
                    break;

                default:     // default is to dump item on the ground
                    for (int x = upperBound - 1; x >= 0; x--)
                    {
                        Item item = (Item)chr.sackList[x];

                        if (item.name == sArgs[0].Remove(sArgs[0].Length - 1, 1) || item.name == sArgs[0])
                        {
                            chr.CurrentCell.Add(item);
                            chr.sackList.RemoveAt(x);
                            chr.WriteToDisplay("You dumped " + item.shortDesc + " on the ground.");
                            break;     // stop at one item because argument 1 was not "all"
                        }
                    }
                    break;
                }
                #endregion
            }
            catch (Exception e)
            {
                Utils.Log("Command.dump(" + args + ") by " + chr.GetLogString(), Utils.LogType.CommandFailure);
                Utils.LogException(e);
            }

            return(true);
        }
Exemple #6
0
        public bool OnCommand(Character chr, string args)
        {
            if (args == null)
            {
                chr.WriteToDisplay("Climb what?");
            }
            else if (chr is NPC || (chr is PC && (chr as PC).ImpLevel > Globals.eImpLevel.USER) || chr.CommandWeight == 2)
            {
                chr.CommandType = CommandTasker.CommandType.Climb;

                string[] sArgs = args.Split(" ".ToCharArray());
                if (sArgs[0].ToLower() == "up" || sArgs[0].ToLower() == "u")
                {
                    if (chr.CurrentCell.IsOneHandClimbUp)
                    {
                        if (chr.RightHand == null || chr.LeftHand == null)
                        {
                            Map.MoveCharacter(chr, "climb up", "");
                        }
                        else
                        {
                            chr.WriteToDisplay("You have slipped and fallen!");
                        }
                    }
                    else if (chr.CurrentCell.IsTwoHandClimbUp)
                    {
                        if (chr.RightHand == null && chr.LeftHand == null)
                        {
                            Map.MoveCharacter(chr, "climb up", "");
                        }
                        else
                        {
                            chr.WriteToDisplay("You have slipped and fallen!");
                        }
                    }
                    else
                    {
                        chr.WriteToDisplay("There is nothing to climb here.");
                        return(true);
                    }
                }
                else if (sArgs[0].ToLower() == "down" || sArgs[0].ToLower() == "d")
                {
                    if (chr.CurrentCell.IsOneHandClimbDown)
                    {
                        if (chr.RightHand == null || chr.LeftHand == null)
                        {
                            Map.MoveCharacter(chr, "climb down", "");
                        }
                        else
                        {
                            chr.WriteToDisplay("You have slipped and fallen!");
                        }
                    }
                    else if (chr.CurrentCell.IsTwoHandClimbDown)
                    {
                        if (chr.RightHand == null && chr.LeftHand == null)
                        {
                            Map.MoveCharacter(chr, "climb down", "");
                        }
                        else
                        {
                            chr.WriteToDisplay("Both hands must be empty to climb down here.");
                        }
                    }
                    else
                    {
                        chr.WriteToDisplay("There is nothing to climb here.");
                    }
                }
                else
                {
                    chr.WriteToDisplay("You can't climb that!");
                }
            }

            return(true);
        }
Exemple #7
0
        public bool OnPerform(Character chr, string args)
        {
            if (args == null)
            {
                chr.WriteToDisplay("Assasinate who?");
                return(false);
            }

            string[] sArgs = args.Split(" ".ToCharArray());

            Character target = TargetAcquisition.AcquireTarget(chr, args, GameWorld.Cell.DEFAULT_VISIBLE_DISTANCE, 0);

            // failed to find the target
            if (target == null)
            {
                chr.WriteToDisplay("You don't see a " + (sArgs.Length >= 2 ? sArgs[0] + " " + sArgs[1] : sArgs[0]) + " here.");
                return(false);
            }

            if (target.CurrentCell != chr.CurrentCell)
            {
                if (!PathTest.SuccessfulPathTest(PathTest.RESERVED_NAME_JUMPKICKCOMMAND, chr.CurrentCell, target.CurrentCell))
                {
                    return(false);
                }
            }

            if (target.IsPC)
            {
                chr.WriteToDisplay("Fellow players may not be assassinated, yet.");
                return(false);
            }

            if (target is NPC && (target as NPC).lairCritter)
            {
                chr.WriteToDisplay("Your target has a lair and is on guard for assassination attempts.");
                return(false);
            }

            if (target.seenList.Contains(chr) && (target is PC || ((target is NPC) && (target as NPC).enemyList.Contains(chr))))
            {
                chr.WriteToDisplay("Your intended target is aware of your presence.");
                return(false);
            }

            if (target is NPC && (target as NPC).friendList.Count > 0)
            {
                if ((target as NPC).friendList.Count == 1 && (target as NPC).friendList.Contains(chr))
                {
                    // continue, thief was visible briefly and appeared as a friend
                }
                else
                {
                    chr.WriteToDisplay("Your target has allies nearby. An assassination target must be alone.");
                    return(false);
                }
            }

            if (target is NPC && (target as NPC).enemyList.Count > 0)
            {
                chr.WriteToDisplay("Your target has visible enemies nearby. An assassination target must be alone.");
                return(false);
            }

            // Only humans, humanoids and giantkin may be assassinated.
            if (!Autonomy.EntityBuilding.EntityLists.IsHumanOrHumanoid(target) &&
                !Autonomy.EntityBuilding.EntityLists.IsGiantKin(target))
            {
                chr.WriteToDisplay("Only humans, humanoids and giantkin may be the target of an assassination.");
                return(false);
            }

            // Unique entities cannot be assassinated.
            if (Autonomy.EntityBuilding.EntityLists.UNIQUE.Contains(target.entity))
            {
                chr.WriteToDisplay("Unique entities cannot be assassinated. They have a level of perception that keeps them aware of such attempts.");
                return(false);
            }

            // Assassination requires Speed.
            if (!chr.HasSpeed)
            {
                chr.WriteToDisplay("You must be enchanted with Speed to carry out an assassination.");
                return(false);
            }

            int distance           = DragonsSpine.GameWorld.Cell.GetCellDistance(chr.X, chr.Y, target.X, target.Y);
            int thieverySkillLevel = Skills.GetSkillLevel(chr.thievery);

            // check minimum thievery skill requirement for allowed distance
            if (distance > 2 && (thieverySkillLevel < MoveThreeAndAssassinateSkillRequirement))
            {
                chr.WriteToDisplay("Your intended target is too far away. Improve your thievery skill.");
                return(false);
            }

            // verify path is not blocked
            if (distance > 0)
            {
                if (!PathTest.SuccessfulPathTest(PathTest.RESERVED_NAME_COMMANDSUFFIX, chr.CurrentCell, target.CurrentCell))
                {
                    chr.WriteToDisplay(GameSystems.Text.TextManager.PATH_IS_BLOCKED);
                    return(false);
                }
            }

            Item weapon = null;

            if (chr.RightHand != null && chr.RightHand.itemType == Globals.eItemType.Weapon)
            {
                weapon = chr.RightHand;
            }
            else if (chr.LeftHand != null && chr.LeftHand.itemType == Globals.eItemType.Weapon)
            {
                weapon = chr.LeftHand;
            }

            if (weapon == null)
            {
                return(false);
            }

            chr.CommandType = CommandTasker.CommandType.Assassinate;
            chr.CurrentCell = target.CurrentCell;
            chr.updateMap   = true;
            Combat.DoCombat(chr, target, weapon);

            chr.CommandsProcessed.RemoveAll(cmdType => cmdType == CommandTasker.CommandType.Assassinate);

            // give skill experience
            Skills.GiveSkillExp(chr, Skills.GetSkillLevel(chr.thievery) * 75, Globals.eSkillType.Thievery);

            if (!chr.HasSpeed || !Map.IsNextToWall(chr) || !Rules.FullStatCheck(chr, Globals.eAbilityStat.Dexterity))
            {
                chr.IsHidden = false;
            }
            else if (thieverySkillLevel < RemainHiddenAfterAssassinate && !Rules.FullStatCheck(chr, Globals.eAbilityStat.Dexterity))
            {
                Map.CheckHiddenStatus(chr);
            }

            if (chr.IsHidden && !chr.EffectsList[Effect.EffectTypes.Hide_in_Shadows].IsPermanent)
            {
                chr.WriteToDisplay(GameSystems.Text.TextManager.REMAINED_HIDDEN);
            }

            return(true);
        }
Exemple #8
0
        public bool OnPerform(Character chr, string args)
        {
            if (args == null)
            {
                chr.WriteToDisplay("Backstab who?");
                return(false);
            }

            if (chr.RightHand == null && chr.LeftHand == null)
            {
                chr.WriteToDisplay("You are not holding a weapon to backstab with.");
                return(false);
            }

            if (Rules.GetEncumbrance(chr) > Globals.eEncumbranceLevel.Moderately)
            {
                chr.WriteToDisplay("You are too encumbered to backstab.");
                return(false);
            }

            Item weapon = null;

            if (chr.RightHand != null && chr.RightHand.itemType == Globals.eItemType.Weapon)
            {
                weapon = chr.RightHand;
            }
            else if (chr.LeftHand != null && chr.LeftHand.itemType == Globals.eItemType.Weapon)
            {
                weapon = chr.LeftHand;
            }

            if (weapon == null)
            {
                chr.WriteToDisplay("You are not holding a weapon you can backstab with.");
                return(false);
            }

            if (!AllowedBackstabItemBaseTypes.Contains(weapon.baseType))
            {
                chr.WriteToDisplay("You are not holding a weapon you can backstab with.");
                return(false);
            }

            string[] sArgs = args.Split(" ".ToCharArray());

            Character target = TargetAcquisition.AcquireTarget(chr, args, GameWorld.Cell.DEFAULT_VISIBLE_DISTANCE, 0);

            // failed to find the target
            if (target == null)
            {
                chr.WriteToDisplay("You don't see a " + (sArgs.Length >= 2 ? sArgs[0] + " " + sArgs[1] : sArgs[0]) + " here.");
                return(false);
            }

            if (target.seenList.Contains(chr))
            {
                chr.WriteToDisplay("Your intended target is aware of your presence.");
                return(false);
            }

            if (!chr.HasSpeed)
            {
                chr.WriteToDisplay("You must be enchanted with Speed to perform a backstab.");
                return(false);
            }

            int distance           = DragonsSpine.GameWorld.Cell.GetCellDistance(chr.X, chr.Y, target.X, target.Y);
            int thieverySkillLevel = Skills.GetSkillLevel(chr.thievery);

            // check minimum thievery skill requirement
            if (distance > 2 && (thieverySkillLevel < MoveThreeAndBackstabSkillRequirement))
            {
                chr.WriteToDisplay("Your intended target is too far away. Improve your thievery skill.");
                return(false);
            }

            // verify path is not blocked
            if (distance > 0)
            {
                if (!PathTest.SuccessfulPathTest(PathTest.RESERVED_NAME_COMMANDSUFFIX, chr.CurrentCell, target.CurrentCell))
                {
                    chr.WriteToDisplay(GameSystems.Text.TextManager.PATH_IS_BLOCKED);
                    return(false);
                }
            }

            chr.CommandType = CommandTasker.CommandType.Backstab;
            chr.CurrentCell = target.CurrentCell;
            chr.updateMap   = true;
            Combat.DoCombat(chr, target, weapon);

            chr.CommandsProcessed.RemoveAll(cmdType => cmdType == CommandTasker.CommandType.Backstab);

            // give skill experience
            Skills.GiveSkillExp(chr, Skills.GetSkillLevel(chr.thievery) * 50, Globals.eSkillType.Thievery);

            if (thieverySkillLevel < RemainHiddenAfterBackstabWithSpeed && !Rules.FullStatCheck(chr, Globals.eAbilityStat.Dexterity))
            {
                chr.IsHidden = false;
            }
            else if (!chr.HasSpeed || !Map.IsNextToWall(chr) || !Rules.FullStatCheck(chr, Globals.eAbilityStat.Dexterity))
            {
                chr.IsHidden = false;
            }
            else
            {
                Map.CheckHiddenStatus(chr);
            }

            if (chr.IsHidden && !chr.EffectsList[Effect.EffectTypes.Hide_in_Shadows].IsPermanent)
            {
                chr.WriteToDisplay(GameSystems.Text.TextManager.REMAINED_HIDDEN);
            }

            return(true);
        }