Ejemplo n.º 1
0
        /// <summary>
        /// Main kernel loop
        /// </summary>
        protected override void Run()
        {
            try
            {
                mDebugger.Send("Run");

                PathTest.Execute(mDebugger);
                DirectoryTest.Execute(mDebugger);
                FileStreamTest.Execute(mDebugger);
                DirectoryInfoTest.Execute(mDebugger);
                StreamWriterStreamReaderTest.Execute(mDebugger);
                BinaryWriterBinaryReaderTest.Execute(mDebugger);
                FileInfoTest.Execute(mDebugger);
                DriveInfoTest.Execute(mDebugger);
                FileTest.Execute(mDebugger);

                TestController.Completed();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception occurred");
                Console.WriteLine(e.ToString());
                mDebugger.Send("Exception occurred: " + e.ToString());
                TestController.Failed();
            }
        }
Ejemplo n.º 2
0
        // args: left/right targetID
        public bool OnPerform(Character chr, string args)
        {
            if (args == null || args == "")
            {
                chr.WriteToDisplay("Who do you want to Battle Charge?");
                return(false);
            }

            if (!MeetsRequirements(chr, null))
            {
                return(false);
            }

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

            Character target = GameSystems.Targeting.TargetAquisition.AcquireTarget(chr, args, GameWorld.Cell.DEFAULT_VISIBLE_DISTANCE, 0);

            // safety net
            if (target == null)
            {
                return(false);
            }

            if (target.CurrentCell != chr.CurrentCell)
            {
                if (!PathTest.SuccessfulPathTest(PathTest.RESERVED_NAME_JUMPKICKCOMMAND, chr.CurrentCell, target.CurrentCell))
                {
                    chr.WriteToDisplay(GameSystems.Text.TextManager.PATH_IS_BLOCKED);
                    return(false);
                }
            }

            if (GameWorld.Cell.GetCellDistance(chr.X, chr.Y, target.X, target.Y) < 1)
            {
                chr.WriteToDisplay("Your target is too close for you to charge into battle.");
                return(false);
            }

            chr.WriteToDisplay("You charge into battle!");
            target.WriteToDisplay(chr.GetNameForActionResult() + " charges you!");

            chr.CommandType = CommandTasker.CommandType.BattleCharge;
            chr.CurrentCell = target.CurrentCell;
            Combat.DoCombat(chr, target, chr.RightHand);
            // TODO: emit battle charge sound

            // Battle charge with a shield does an automatic bash.
            if (chr.HasTalent(GameTalent.TALENTS.Bash) && chr.LeftHand != null && chr.LeftHand.baseType == eItemBaseType.Shield)
            {
                GameTalent gtShieldBash = GameTalent.GameTalentDictionary[GameTalent.TALENTS.Bash.ToString().ToLower()];

                if (gtShieldBash.MeetsPerformanceCost(chr) && gtShieldBash.Handler.OnPerform(chr, args))
                {
                    gtShieldBash.SuccessfulPerformance(chr);
                }
            }

            return(true);
        }
Ejemplo n.º 3
0
    private void OnEnable()
    {
        // 取得實體
        t = (PathTest)target;
        if (t == null)
        {
            return;
        }

        GetVariableProperties();
    }
Ejemplo n.º 4
0
        public bool OnPerform(Character chr, string args)
        {
            if (args == null || args == "")
            {
                chr.WriteToDisplay("Who do you want to attack?");
                return(false);
            }

            if (Rules.GetEncumbrance(chr) > Globals.eEncumbranceLevel.Lightly)
            {
                chr.WriteToDisplay("You are too encumbered to perform a Flying Fury maneuver.");
                return(false);
            }

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

            Character target = GameSystems.Targeting.TargetAquisition.AcquireTarget(chr, args, GameWorld.Cell.DEFAULT_VISIBLE_DISTANCE, 2);

            // safety net
            if (target == null)
            {
                int id = 0;

                if (args.StartsWith("-") || Int32.TryParse(args, out id))
                {
                    chr.WriteToDisplay("You do not see your target nearby.");
                }
                else
                {
                    chr.WriteToDisplay("You do not see a " + args + " nearby.");
                }
                return(false);
            }

            if (GameWorld.Cell.GetCellDistance(chr.X, chr.Y, target.X, target.Y) < 1)
            {
                chr.WriteToDisplay("Your target is too close for a Flying Fury maneuver.");
                return(false);
            }

            if (target != null && target.CurrentCell != chr.CurrentCell)
            {
                PathTest pathTest = new PathTest(PathTest.RESERVED_NAME_JUMPKICKCOMMAND, chr.CurrentCell);

                if (!pathTest.SuccessfulPathTest(target.CurrentCell))
                {
                    chr.WriteToDisplay(GameSystems.Text.TextManager.PATH_IS_BLOCKED);
                    pathTest.RemoveFromWorld();
                    return(false);
                }

                pathTest.RemoveFromWorld();
            }

            // Two jumpkicks then two fist attacks.

            chr.CommandType = CommandTasker.CommandType.Jumpkick;

            Combat.DoJumpKick(chr, target);

            if (target != null && !target.IsDead)
            {
                Combat.DoJumpKick(chr, target);
            }

            chr.CommandsProcessed.RemoveAll((cmdType) => { return(cmdType == CommandTasker.CommandType.Jumpkick); });

            chr.CommandType = CommandTasker.CommandType.Attack;

            if (target != null && !target.IsDead)
            {
                Combat.DoCombat(chr, target, chr.RightHand);
            }
            if (target != null && !target.IsDead)
            {
                Combat.CheckDoubleAttack(chr, target, chr.RightHand);
            }
            if (target != null && !target.IsDead)
            {
                Combat.DoCombat(chr, target, chr.RightHand);
            }
            if (target != null && !target.IsDead)
            {
                Combat.CheckDoubleAttack(chr, target, chr.RightHand);
            }

            if (target != null && target.CurrentCell != null)
            {
                chr.CurrentCell = target.CurrentCell;
            }

            // TODO: emit flying fury sound

            return(true);
        }
 public void Init()
 {
     test = new PathTest();
 }
 public void Init()
 {
     test = new PathTest();
 }
Ejemplo n.º 7
0
        public bool OnPerform(Character chr, string args)
        {
            if (args == null || args == "")
            {
                chr.WriteToDisplay("Leg Sweep what?");
                return(false);
            }

            if (Rules.GetEncumbrance(chr) > Globals.eEncumbranceLevel.Lightly)
            {
                chr.WriteToDisplay("You are too encumbered to perform a Leg Sweep.");
                return(false);
            }

            int maxDistance = 0;

            // if first command is movement and bash skill level is less than 12 (Expert) then fail a move and bash attempt
            if (chr.CommandsProcessed.Contains(CommandTasker.CommandType.Movement) && Skills.GetSkillLevel(chr.unarmed) < MOVE_AND_LEGSWEEP_LEVEL)
            {
                chr.WriteToDisplay("You are not skilled enough to move and Leg Sweep.");
                return(false);
            }
            else
            {
                maxDistance = GameWorld.Cell.DEFAULT_VISIBLE_DISTANCE;  // can move 3 and leg sweep
            }
            int skillLevel = Skills.GetSkillLevel(chr, Globals.eSkillType.Unarmed);

            if (skillLevel < MOVE_AND_LEGSWEEP_LEVEL)
            {
                maxDistance = 0;
            }

            Character target = GameSystems.Targeting.TargetAquisition.AcquireTarget(chr, args.Split(" ".ToCharArray()), maxDistance, 0);

            // safety net
            if (target == null)
            {
                chr.WriteToDisplay(GameSystems.Text.TextManager.NullTargetMessage(args));
                return(false);
            }

            // Check pathing from Character to target.
            PathTest pathTest = new PathTest(PathTest.RESERVED_NAME_JUMPKICKCOMMAND, chr.CurrentCell);

            if (target != null && pathTest.SuccessfulPathTest(target.CurrentCell))
            {
                chr.CommandsProcessed.Add(CommandTasker.CommandType.Leg_Sweep); // Currently this is only done for damage adjustments in Combat.DoDamage.

                // Make sure the Martial Artist has moved to the target's Cell since a pathtest was performed and a check was already done to confirm proper skill level.
                if (chr.CurrentCell != target.CurrentCell)
                {
                    chr.CurrentCell = target.CurrentCell;
                }

                foreach (Character _targ in chr.CurrentCell.Characters.Values)
                {
                    if (_targ == null || _targ.IsDead || _targ == chr)
                    {
                        continue;
                    }

                    if (_targ.Alignment == target.Alignment || _targ == target || ((_targ is NPC) && (_targ as NPC).MostHated == chr))
                    {
                        skillLevel--;
                        Combat.DoCombat(chr, _targ, chr.GetInventoryItem(Globals.eWearLocation.Feet));
                    }

                    if (skillLevel <= 0)
                    {
                        break;
                    }
                }
            }
            else
            {
                chr.WriteToDisplay("You cannot reach your target to perform a Leg Sweep.");
                return(false);
            }

            return(true);
        }
Ejemplo n.º 8
0
        public bool OnCommand(Character chr, string args)
        {
            if (chr.CommandWeight > 3)
            {
                chr.WriteToDisplay("Command weight limit exceeded. Jumpkick command not processed.");
                return(true);
            }

            if (args == null || args == "")
            {
                chr.WriteToDisplay("Jumpkick who?");
                return(true);
            }

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

            if (sArgs[0] == null)
            {
                chr.WriteToDisplay("Who do you want to jumpkick?");
                return(true);
            }

            Character target        = null;
            bool      includeHidden = chr.IsImmortal;

            if (sArgs.Length == 2)
            {
                int countTo = 0;

                try
                {
                    countTo = Convert.ToInt32(sArgs[0]);
                    target  = TargetAcquisition.FindTargetInView(chr, sArgs[1].ToLower(), countTo);
                }
                catch
                {
                    target = TargetAcquisition.FindTargetInView(chr, sArgs[0].ToLower(), false, includeHidden);
                }
            }
            else
            {
                target = TargetAcquisition.FindTargetInView(chr, sArgs[0].ToLower(), false, includeHidden);
            }

            if (target == null)
            {
                chr.WriteToDisplay(GameSystems.Text.TextManager.NullTargetMessage(sArgs[0]));
            }
            else
            {
                if (target.CurrentCell != chr.CurrentCell)
                {
                    PathTest pathTest = new PathTest(PathTest.RESERVED_NAME_JUMPKICKCOMMAND, chr.CurrentCell);

                    if (!pathTest.SuccessfulPathTest(target.CurrentCell))
                    {
                        chr.WriteToDisplay(GameSystems.Text.TextManager.PATH_IS_BLOCKED);
                        pathTest.RemoveFromWorld();
                        return(true);
                    }
                    pathTest.RemoveFromWorld();
                }

                chr.CommandType = CommandTasker.CommandType.Jumpkick;

                chr.Stamina -= Cell.GetCellDistance(chr.X, chr.Y, target.X, target.Y);

                Globals.eEncumbranceLevel encumbDesc = Rules.GetEncumbrance(chr);
                if (encumbDesc == Globals.eEncumbranceLevel.Moderately)
                {
                    chr.Stamina -= 2;
                }
                else if (encumbDesc == Globals.eEncumbranceLevel.Heavily)
                {
                    chr.Stamina -= 4;
                }
                else if (encumbDesc == Globals.eEncumbranceLevel.Severely)
                {
                    chr.Stamina -= 6;
                }

                if (chr.Stamina < 0)
                {
                    Combat.DoDamage(chr, chr, Math.Abs(chr.Stamina), false);
                    chr.Stamina = 0;
                }

                chr.CurrentCell = target.CurrentCell;

                chr.updateMap = true;

                Combat.DoJumpKick(chr, target);
            }

            return(true);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        public bool OnPerform(Character chr, string args)
        {
            if (args == null || args == "")
            {
                chr.WriteToDisplay("Cleave what?");
                return(false);
            }

            if (!MeetsRequirements(chr, null))
            {
                return(false);
            }

            int maxDistance = 0;

            // if first command is movement and bash skill level is less than 12 (Expert) then fail a move and bash attempt
            if (chr.CommandsProcessed.Contains(CommandTasker.CommandType.Movement) && Skills.GetSkillLevel(chr, chr.RightHand.skillType) < MOVE_AND_CLEAVE_LEVEL)
            {
                chr.WriteToDisplay("You are not skilled enough with " + chr.RightHand.shortDesc + " to move and Cleave.");
                return(false);
            }
            else
            {
                maxDistance = GameWorld.Cell.DEFAULT_VISIBLE_DISTANCE;  // can move 3 and cleave
            }
            if (Skills.GetSkillLevel(chr, chr.RightHand.skillType) < MOVE_AND_CLEAVE_LEVEL)
            {
                maxDistance = 0;
            }

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

            Character target = GameSystems.Targeting.TargetAquisition.AcquireTarget(chr, sArgs, maxDistance, 0);

            if (target == null)
            {
                chr.WriteToDisplay(GameSystems.Text.TextManager.NullTargetMessage(args));
                return(false);
            }

            if (PathTest.SuccessfulPathTest(PathTest.RESERVED_NAME_JUMPKICKCOMMAND, chr.CurrentCell, target.CurrentCell))
            {
                chr.CommandsProcessed.Add(CommandTasker.CommandType.Cleave); // Currently this is only done for damage adjustments in Combat.DoDamage.

                // Make sure the Fighter has moved to the target's Cell since a pathtest was performed and a check was already done to confirm proper skill level.
                if (chr.CurrentCell != target.CurrentCell)
                {
                    chr.CurrentCell = target.CurrentCell;
                }

                foreach (Character _targ in chr.CurrentCell.Characters.Values)
                {
                    if (_targ == null || _targ.IsDead)
                    {
                        continue;
                    }

                    // Could fumble? Make sure right hand is not empty.
                    if (_targ.Alignment == target.Alignment || _targ == target)
                    {
                        if (chr.RightHand != null)
                        {
                            // Do combat.
                            Combat.DoCombat(chr, _targ, chr.RightHand);
                        }

                        if (_targ == null || _targ.IsDead)
                        {
                            continue;              // redundancy
                        }
                        if (chr.RightHand != null) // possible loss of weapon (fumble)
                        // Check double attack.
                        {
                            Combat.CheckDoubleAttack(chr, _targ, chr.RightHand);
                        }

                        if (_targ == null || _targ.IsDead)
                        {
                            continue;              // redundancy
                        }
                        if (chr.RightHand != null) // possible loss of weapon (fumble)
                        // Hummingbird special attribute is an extra attack.
                        {
                            Combat.CheckSpecialWeaponAttack(chr, _targ, chr.RightHand);
                        }

                        if (_targ == null || _targ.IsDead)
                        {
                            continue;                                // redundancy
                        }
                        // Make sure left hand weapon is a cleaving weapon.
                        if (chr.LeftHand != null && CleavingWeapons.Contains(chr.LeftHand.baseType))
                        {
                            // Check dual wield. Double attack is checked again for dual wielded weapon. Dual wielded hummingbird longsword is also checked here.
                            Combat.CheckDualWield(chr, _targ, chr.LeftHand);
                        }
                    }
                }
            }
            else
            {
                chr.WriteToDisplay("You cannot reach your target to perform a Cleave.");
                return(false);
            }

            return(true);
        }
Ejemplo n.º 11
0
        public bool OnCast(Character caster, string args)
        {
            try
            {
                Character target = ReferenceSpell.FindAndConfirmSpellTarget(caster, args);
                Cell      cell   = null;
                if (target == null)
                {
                    cell = Map.GetCellRelevantToCell(caster.CurrentCell, args, false);
                }
                else
                {
                    cell = target.CurrentCell;
                }

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

                #region Path testing.
                PathTest pathTest = new PathTest(PathTest.RESERVED_NAME_AREAEFFECT + PathTest.RESERVED_NAME_COMMANDSUFFIX, caster.CurrentCell);

                if (!pathTest.SuccessfulPathTest(cell))
                {
                    cell = caster.CurrentCell;
                }

                pathTest.RemoveFromWorld();
                #endregion

                cell.SendShout("a thunder clap!");
                cell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.ThunderClap));

                List <Character> theAffected = new List <Character>(cell.Characters.Values);

                if (theAffected.Count > 0)
                {
                    int dmgMultiplier = 6;

                    if (caster is PC)
                    {
                        dmgMultiplier = 8;
                    }
                    int damage = 0;
                    if (Skills.GetSkillLevel(caster.magic) >= 4)
                    {
                        damage = Skills.GetSkillLevel(caster.magic) * dmgMultiplier + GameSpell.GetSpellDamageModifier(caster);
                    }
                    else
                    {
                        damage = 6 * dmgMultiplier + GameSpell.GetSpellDamageModifier(caster);
                    }

                    if (!caster.IsPC)
                    {
                        if (caster.species == Globals.eSpecies.LightningDrake)
                        {
                            damage = Rules.RollD(Skills.GetSkillLevel(caster.magic), 14);
                        }
                    }

                    foreach (Character affected in new List <Character>(theAffected))
                    {
                        if (Combat.DoSpellDamage(caster, affected, null, damage, "lightning") == 1)
                        {
                            Rules.GiveAEKillExp(caster, affected);
                            Skills.GiveSkillExp(caster, affected, Globals.eSkillType.Magic);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Utils.LogException(e);
                return(false);
            }
            return(true);
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
 void Awake()
 {
     Instance = this;
 }
Ejemplo n.º 14
0
        public bool OnCommand(Character chr, string args)
        {
            if (chr.CommandWeight > 3)
            {
                chr.WriteToDisplay("Command weight limit exceeded. Chase command not processed.");
                return(true);
            }

            if (args == null || args == "")
            {
                chr.WriteToDisplay("Chase who?");
                return(true);
            }
            else
            {
                string[]  sArgs  = args.Split(" ".ToCharArray());
                Character target = null;

                if (sArgs.Length == 2)
                {
                    int countTo = 0;
                    try
                    {
                        countTo = Convert.ToInt32(sArgs[0]);
                        target  = TargetAcquisition.FindTargetInView(chr, sArgs[1].ToLower(), countTo);
                    }
                    catch
                    {
                        target = TargetAcquisition.FindTargetInView(chr, sArgs[0].ToLower(), false, false);
                    }
                }
                else
                {
                    target = TargetAcquisition.FindTargetInView(chr, sArgs[0].ToLower(), false, false);
                }

                if (target == null)
                {
                    chr.WriteToDisplay(GameSystems.Text.TextManager.NullItemMessage(sArgs[0]));
                    return(true);
                }
                else
                {
                    chr.FollowID = target.UniqueID;
                    if (chr.CurrentCell != target.CurrentCell)
                    {
                        if (!PathTest.SuccessfulPathTest(PathTest.RESERVED_NAME_COMMANDSUFFIX, chr.CurrentCell, target.CurrentCell))
                        {
                            if (chr is NPC)
                            {
                                NPC chaser = chr as NPC;
                                chaser.AIGotoXYZ(target.CurrentCell.X, target.CurrentCell.Y, target.CurrentCell.Z);
                            }
                            return(false);
                        }
                        else
                        {
                            chr.CurrentCell = target.CurrentCell;
                        }
                    }
                    chr.CommandType = CommandTasker.CommandType.Movement;
                }
            }

            return(true);
        }
Ejemplo n.º 15
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);
        }