Beispiel #1
0
        public static bool CheckParry(CharacterInstance ch, CharacterInstance victim, IRepositoryManager dbManager = null,
                                      IGameManager gameManager = null)
        {
            if (!victim.IsAwake())
            {
                return(false);
            }

            if (victim.IsNpc() && !victim.Defenses.IsSet((int)DefenseTypes.Parry))
            {
                return(false);
            }

            int chances;

            var skill = (dbManager ?? RepositoryManager.Instance).GetEntity <SkillData>("parry");

            if (skill == null)
            {
                throw new ObjectNotFoundException("Skill 'parry' not found");
            }

            if (victim.IsNpc())
            {
                chances = 60.GetLowestOfTwoNumbers(2 * victim.Level);
            }
            else
            {
                if (victim.GetEquippedItem(WearLocations.Wield) == null)
                {
                    return(false);
                }
                chances = (int)Macros.LEARNED(victim, (int)skill.ID) /
                          (gameManager ?? GameManager.Instance).SystemData.ParryMod;
            }

            if (chances != 0 && victim.CurrentMorph != null)
            {
                chances += victim.CurrentMorph.Morph.ParryChances;
            }

            if (!victim.Chance(chances + victim.Level - ch.Level))
            {
                skill.LearnFromFailure(victim);
                return(false);
            }

            if (!victim.IsNpc() && !((PlayerInstance)victim).PlayerData.Flags.IsSet(PCFlags.Gag))
            {
                comm.act(ATTypes.AT_SKILL, "You parry $n's attack.", ch, null, victim, ToTypes.Victim);
            }

            if (!ch.IsNpc() && !((PlayerInstance)ch).PlayerData.Flags.IsSet(PCFlags.Gag))
            {
                comm.act(ATTypes.AT_SKILL, "$N parries your attack.", ch, null, victim, ToTypes.Character);
            }

            skill.LearnFromSuccess(victim);
            return(true);
        }
Beispiel #2
0
        public static bool CheckSaveVsPoisonDeath(this SavingThrowData savingThrow, int level, CharacterInstance victim)
        {
            var save = 50 + (victim.Level - level - savingThrow.SaveVsPoisonDeath) * 5;

            save = save.GetNumberThatIsBetween(5, 95);
            return(victim.Chance(save));
        }
Beispiel #3
0
        public static bool CheckTumble(CharacterInstance ch, CharacterInstance victim, IRepositoryManager dbManager = null,
                                       IGameManager gameManager = null)
        {
            if (victim.CurrentClass != ClassTypes.Thief || !victim.IsAwake())
            {
                return(false);
            }

            var skill = (dbManager ?? RepositoryManager.Instance).GetEntity <SkillData>("tumble");

            if (skill == null)
            {
                throw new ObjectNotFoundException("Skill 'tumble' not found");
            }

            if (!victim.IsNpc() && !(((PlayerInstance)victim).GetLearned((int)skill.ID) > 0))
            {
                return(false);
            }

            int chances;

            if (victim.IsNpc())
            {
                chances = 60.GetLowestOfTwoNumbers(2 * victim.Level);
            }
            else
            {
                chances = (int)Macros.LEARNED(victim, (int)skill.ID) /
                          (gameManager ?? GameManager.Instance).SystemData.TumbleMod +
                          (victim.GetCurrentDexterity() - 13);
            }

            if (chances != 0 && victim.CurrentMorph != null)
            {
                chances += victim.CurrentMorph.Morph.TumbleChances;
            }

            if (!victim.Chance(chances + victim.Level - ch.Level))
            {
                return(false);
            }

            if (!victim.IsNpc() && !((PlayerInstance)victim).PlayerData.Flags.IsSet(PCFlags.Gag))
            {
                comm.act(ATTypes.AT_SKILL, "You tumble away from $n's attack.", ch, null, victim, ToTypes.Victim);
            }

            if (!ch.IsNpc() && !((PlayerInstance)ch).PlayerData.Flags.IsSet(PCFlags.Gag))
            {
                comm.act(ATTypes.AT_SKILL, "$N tumbles away from your attack.", ch, null, victim, ToTypes.Character);
            }

            skill.LearnFromSuccess(victim);
            return(true);
        }
Beispiel #4
0
        public static bool CheckSaveVsWandRod(this SavingThrowData savingThrow, int level, CharacterInstance victim)
        {
            if (victim.Immunity.IsSet(ResistanceTypes.Magic))
            {
                return(true);
            }

            var save = 50 + (victim.Level - level - savingThrow.SaveVsWandRod) * 5;

            save = save.GetNumberThatIsBetween(5, 95);
            return(victim.Chance(save));
        }
Beispiel #5
0
        private static ReturnTypes ObscureSpellAction(SkillData skill, int level, CharacterInstance ch, ObjectInstance obj)
        {
            var percent = !string.IsNullOrEmpty(skill.Dice) ? magic.ParseDiceExpression(ch, skill.Dice) : 20;

            if (CheckFunctions.CheckIfTrueCasting(
                    obj.ExtraFlags.IsSet((int)ItemExtraFlags.Invisible) || ch.Chance(percent), skill, ch))
            {
                return(ReturnTypes.SpellFailed);
            }

            ch.SuccessfulCast(skill, null, obj);
            obj.ExtraFlags.SetBit((int)ItemExtraFlags.Invisible);
            return(ReturnTypes.None);
        }
Beispiel #6
0
        public static ReturnTypes spell_acid_breath(int sn, int level, CharacterInstance ch, object vo)
        {
            var victim = (CharacterInstance)vo;

            int chance;

            checked
            {
                chance = 2 * level;
            }

            if (ch.Chance(chance) && !victim.SavingThrows.CheckSaveVsBreath(level, victim))
            {
                foreach (var obj in victim.Carrying.Where(obj => SmaugRandom.Bits(2) == 0))
                {
                    switch (obj.ItemType)
                    {
                    case ItemTypes.Armor:
                        CheckDamageArmor(obj, victim);
                        break;

                    case ItemTypes.Container:
                        CheckDamageContainer(obj, victim);
                        break;
                    }
                }
            }

            var hpChange = 10.GetHighestOfTwoNumbers(ch.CurrentHealth);
            var damage   = SmaugRandom.Between(hpChange / 16 + 1, hpChange / 8);

            if (victim.SavingThrows.CheckSaveVsBreath(level, victim))
            {
                damage /= 2;
            }
            return(ch.CauseDamageTo(victim, damage, sn));
        }
Beispiel #7
0
        public static ReturnTypes spell_animate_dead(int sn, int level, CharacterInstance ch, object vo)
        {
            var corpse =
                ch.CurrentRoom.Contents.FirstOrDefault(x => x.ItemType == ItemTypes.NpcCorpse && x.Cost != -5);

            if (CheckFunctions.CheckIfNullObject(ch, corpse, "You cannot find a suitable corpse here"))
            {
                return(ReturnTypes.SpellFailed);
            }

            var skill = RepositoryManager.Instance.GetEntity <SkillData>(sn);

            var template = RepositoryManager.Instance.MOBILETEMPLATES.Get(VnumConstants.MOB_VNUM_ANIMATED_CORPSE);

            if (template == null)
            {
                throw new ObjectNotFoundException("Animated Corpse VNUM template was not found.");
            }

            // TODO Get the template using the corpse cost?  huh?

            if (CheckFunctions.CheckIfEquivalent(ch, template,
                                                 RepositoryManager.Instance.MOBILETEMPLATES.Get(VnumConstants.MOB_VNUM_DEITY),
                                                 "You can't animate the corpse of a deity's Avatar."))
            {
                return(ReturnTypes.SpellFailed);
            }

            if (!ch.IsNpc())
            {
                if (ch.IsVampire())
                {
                    if (CheckFunctions.CheckIfTrue(ch,
                                                   !ch.IsImmortal() &&
                                                   ((PlayerInstance)ch).PlayerData.GetConditionValue(ConditionTypes.Bloodthirsty) - template.Level / 3 < 0,
                                                   "You don't have the power to reanimate this corpse."))
                    {
                        return(ReturnTypes.SpellFailed);
                    }

                    ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, template.Level / 3);
                }
                else if (ch.CurrentMana - template.Level / 4 < 0)
                {
                    ch.SendTo("You do not have enough mana to reanimate this corpse.");
                    return(ReturnTypes.SpellFailed);
                }
                else
                {
                    ch.CurrentMana -= template.Level * 4;
                }
            }

            if (ch.IsImmortal() || (ch.Chance(75) && template.Level - ch.Level < 10))
            {
                return(AnimateCorpse(level, ch, template, corpse));
            }

            ch.FailedCast(skill);
            return(ReturnTypes.SpellFailed);
        }
Beispiel #8
0
        public static ReturnTypes ObjectCastSpell(this CharacterInstance ch, int sn, int level,
                                                  CharacterInstance victim = null, ObjectInstance obj = null)
        {
            var skill = RepositoryManager.Instance.GetEntity <SkillData>(sn);

            if (skill?.SpellFunction == null)
            {
                return(ReturnTypes.Error);
            }

            if (ch.CurrentRoom.Flags.IsSet(RoomFlags.NoMagic) ||
                (ch.CurrentRoom.Flags.IsSet(RoomFlags.Safe) &&
                 skill.Target == TargetTypes.OffensiveCharacter))
            {
                ch.SetColor(ATTypes.AT_MAGIC);
                ch.SendTo("Nothing seems to happen...");
                return(ReturnTypes.None);
            }

            // Reduces the number of level 5 players using level 40 scrolls in battle
            var levelDiff = ch.Level - level;

            if ((skill.Target == TargetTypes.OffensiveCharacter || SmaugRandom.Bits(7) == 1) &&
                skill.Type != SkillTypes.Herb &&
                ch.Chance(95 + levelDiff))
            {
                switch (SmaugRandom.Bits(2))
                {
                case 0:
                case 2:
                    ch.FailedCast(skill, victim);
                    break;

                case 1:
                case 3:
                    comm.act(ATTypes.AT_MAGIC, "The $t spell backfires!", ch, skill.Name, victim, ToTypes.Character);
                    if (victim != null)
                    {
                        comm.act(ATTypes.AT_MAGIC, "$n's $t spell backfires!", ch, skill.Name, victim,
                                 ToTypes.Victim);
                    }
                    comm.act(ATTypes.AT_MAGIC, "$n's $t spell backfires!", ch, skill.Name, victim, ToTypes.Room);
                    return(ch.CauseDamageTo(ch, SmaugRandom.Between(1, level), Program.TYPE_UNDEFINED));
                }

                return(ReturnTypes.None);
            }

            object vo;

            switch (skill.Target)
            {
            default:
                LogManager.Instance.Bug("Bad target for sn {0}", sn);
                return(ReturnTypes.Error);

            case TargetTypes.Ignore:
                vo = null;
                if (victim != null)
                {
                    Cast.TargetName = victim.Name;
                }
                else if (obj != null)
                {
                    Cast.TargetName = obj.Name;
                }
                break;

            case TargetTypes.OffensiveCharacter:
                if (victim != ch)
                {
                    if (victim == null)
                    {
                        victim = ch.GetMyTarget();
                    }
                    if (CheckFunctions.CheckIfTrue(ch, victim == null || (!victim.IsNpc() && !victim.IsInArena()),
                                                   "You can't do that."))
                    {
                        return(ReturnTypes.None);
                    }
                }
                if (ch != victim && fight.is_safe(ch, victim, true))
                {
                    return(ReturnTypes.None);
                }
                vo = victim;
                break;

            case TargetTypes.DefensiveCharacter:
                if (victim == null)
                {
                    victim = ch;
                }
                vo = victim;
                if (CheckFunctions.CheckIfTrueCasting(
                        skill.Type != SkillTypes.Herb && victim.Immunity.IsSet(ResistanceTypes.Magic),
                        skill, ch, CastingFunctionType.Immune, victim))
                {
                    return(ReturnTypes.None);
                }
                break;

            case TargetTypes.Self:
                vo = ch;
                if (CheckFunctions.CheckIfTrueCasting(
                        skill.Type != SkillTypes.Herb && ch.Immunity.IsSet(ResistanceTypes.Magic),
                        skill, ch, CastingFunctionType.Immune, victim))
                {
                    return(ReturnTypes.None);
                }
                break;

            case TargetTypes.InventoryObject:
                if (CheckFunctions.CheckIfNullObject(ch, obj, "You can't do that!"))
                {
                    return(ReturnTypes.None);
                }

                vo = obj;
                break;
            }

            var start   = DateTime.Now;
            var retcode = skill.SpellFunction.Value.Invoke(sn, level, ch, vo);

            skill.UseHistory.Use(ch, DateTime.Now.Subtract(start));

            if (retcode == ReturnTypes.SpellFailed)
            {
                retcode = ReturnTypes.None;
            }

            if (retcode == ReturnTypes.CharacterDied || retcode == ReturnTypes.Error)
            {
                return(retcode);
            }

            if (ch.CharDied())
            {
                return(ReturnTypes.CharacterDied);
            }

            if (skill.Target == TargetTypes.OffensiveCharacter &&
                victim != ch &&
                !victim.CharDied())
            {
                foreach (
                    var vch in
                    ch.CurrentRoom.Persons.Where(
                        vch => victim == vch && vch.CurrentFighting == null && vch.Master != ch))
                {
                    retcode = fight.multi_hit(vch, ch, Program.TYPE_UNDEFINED);
                    break;
                }
            }

            return(retcode);
        }