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); }
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)); }
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); }
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)); }
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); }
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)); }
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); }
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); }