private static void ExecuteCastingType(CastingFunctionType castingType, SkillData skill, CharacterInstance ch, CharacterInstance victim = null, ObjectInstance obj = null) { switch (castingType) { case CastingFunctionType.Success: ch.SuccessfulCast(skill, victim, obj); break; case CastingFunctionType.Immune: ch.ImmuneCast(skill, victim, obj); break; default: ch.FailedCast(skill, victim, obj); break; } }
private static ReturnTypes PurifySpellAction(SkillData skill, CharacterInstance ch, ObjectInstance obj) { switch (obj.ItemType) { case ItemTypes.Cook: case ItemTypes.Food: case ItemTypes.DrinkContainer: obj.Split(); obj.Value.ToList()[3] = 0; ch.SuccessfulCast(skill, null, obj); break; default: ch.FailedCast(skill, null, obj); break; } return(ReturnTypes.None); }
public static ReturnTypes spell_blindness(int sn, int level, CharacterInstance ch, object vo) { var victim = (CharacterInstance)vo; var skill = RepositoryManager.Instance.GetEntity <SkillData>(sn); var tmp = skill.Flags.IsSet(SkillFlags.PKSensitive) ? level / 2 : level; if (victim.IsImmune(ResistanceTypes.Magic)) { ch.ImmuneCast(skill, victim); return(ReturnTypes.SpellFailed); } if (ch.IsAffected(AffectedByTypes.Blind) || ch.SavingThrows.CheckSaveVsSpellStaff(tmp, victim)) { ch.FailedCast(skill, victim); return(ReturnTypes.SpellFailed); } var af = new AffectData { SkillNumber = sn, Location = ApplyTypes.HitRoll, Modifier = -4, Duration = GetDuration(level) }; victim.AddAffect(af); victim.SetColor(ATTypes.AT_MAGIC); victim.SendTo("You are blinded!"); if (ch != victim) { comm.act(ATTypes.AT_MAGIC, "You weave a spell of blindness around $N.", ch, null, victim, ToTypes.Character); comm.act(ATTypes.AT_MAGIC, "$n weaves a spell of blindness about $N.", ch, null, victim, ToTypes.NotVictim); } return(ReturnTypes.None); }
public static ReturnTypes spell_dispel_magic(int sn, int level, CharacterInstance ch, object vo) { var victim = (CharacterInstance)vo; var skill = RepositoryManager.Instance.GetEntity <SkillData>(sn); ch.SetColor(ATTypes.AT_MAGIC); if (CheckFunctions.CheckIfTrueCasting(victim.Immunity.IsSet(ResistanceTypes.Magic), skill, ch, CastingFunctionType.Immune, victim)) { return(ReturnTypes.SpellFailed); } if (CheckFunctions.CheckIfTrueCasting(victim.IsNpc() && victim.IsAffected(AffectedByTypes.Possess), skill, ch, CastingFunctionType.Immune, victim)) { return(ReturnTypes.SpellFailed); } if (ch == victim) { return(DispelSelf(ch, victim)); } var isMage = ch.IsNpc() || ch.CurrentClass == ClassTypes.Mage; if (!isMage && !ch.IsAffected(AffectedByTypes.DetectMagic)) { ch.SendTo("You don't sense a magical aura to dispel."); return(ReturnTypes.Error); } int chance = ch.GetCurrentIntelligence() - victim.GetCurrentIntelligence(); if (isMage) { chance += 5; } else { chance -= 15; } bool twice = false, three = false; if (SmaugRandom.D100() > 75 - chance) { twice = true; if (SmaugRandom.D100() > 75 - chance) { three = true; } } bool continueOuterLoop = true; int affectedBy; bool found = false; int cnt = 0, times = 0; while (continueOuterLoop) { AffectData paf = null; // grab affected_by from mobs first if (victim.IsNpc() && victim.AffectedBy.IsEmpty()) { for (; ;) { affectedBy = SmaugRandom.Between(0, EnumerationFunctions.MaximumEnumValue <AffectedByTypes>() - 1); if (victim.IsAffectedBy(affectedBy)) { found = true; break; } if (cnt++ > 30) { found = false; break; } } // is it a spell? if (found) { foreach (var af in victim.Affects) { paf = af; if (paf.Type.IsSet(affectedBy)) { break; } } // its a spell, remove it if (paf != null) { if (level < victim.Level || victim.SavingThrows.CheckSaveVsSpellStaff(level, victim)) { if (magic.dispel_casting(paf, ch, victim, 0, false) != 0) { ch.FailedCast(skill, victim); } return(ReturnTypes.SpellFailed); } if (skill.Flags.IsSet(SkillFlags.NoDispel)) { if (magic.dispel_casting(paf, ch, victim, 0, false) != 0 && times == 0) { ch.FailedCast(skill, victim); } return(ReturnTypes.SpellFailed); } if (magic.dispel_casting(paf, ch, victim, 0, true) != 0 && times == 0) { ch.SuccessfulCast(skill, victim); } victim.RemoveAffect(paf); if ((twice && times < 1) || (three && times < 2)) { times++; continue; } return(ReturnTypes.None); } // not a spell, just remove the bit (for mobs only) else { if (level < victim.Level || victim.SavingThrows.CheckSaveVsSpellStaff(level, victim)) { if (magic.dispel_casting(null, ch, victim, affectedBy, false) != 0) { ch.FailedCast(skill, victim); } return(ReturnTypes.SpellFailed); } if (magic.dispel_casting(null, ch, victim, affectedBy, true) != 0 && times == 0) { ch.SuccessfulCast(skill, victim); } victim.AffectedBy.RemoveBit(affectedBy); if ((twice && times < 1) || (three && times < 2)) { times++; continue; } return(ReturnTypes.None); } } } // mob has no affectedBys or we didn't catch them if (!victim.Affects.Any()) { ch.FailedCast(skill, victim); return(ReturnTypes.SpellFailed); } // randomize the affects cnt = victim.Affects.Count; paf = victim.Affects.First(); int affectNum; int i = 0; for (affectNum = SmaugRandom.Between(0, cnt - 1); affectNum > 0; affectNum--) { paf = victim.Affects.ToList()[i]; } if (level < victim.Level || victim.SavingThrows.CheckSaveVsSpellStaff(level, victim)) { if (magic.dispel_casting(paf, ch, victim, 0, false) != 0) { ch.FailedCast(skill, victim); } return(ReturnTypes.SpellFailed); } // make sure we have an affect and it isn't a dispel if (paf == null || paf.Type.IsSet(SkillFlags.NoDispel)) { if (magic.dispel_casting(paf, ch, victim, 0, false) != 0) { ch.FailedCast(skill, victim); } return(ReturnTypes.SpellFailed); } if (magic.dispel_casting(null, ch, victim, 0, true) != 0 && times == 0) { ch.SuccessfulCast(skill, victim); } victim.RemoveAffect(paf); if ((twice && times < 1) || (three && times < 2)) { times++; continue; } } if (!victim.IsNpc()) { victim.update_aris(); } return(ReturnTypes.None); }
public static bool CheckAbility(CharacterInstance ch, string command, string argument, IRepositoryManager databaseManager = null) { var sn = ch.GetIDOfSkillCharacterKnows(command); if (sn == -1) { return(false); } var skill = (databaseManager ?? RepositoryManager.Instance).GetEntity <SkillData>(sn); if (skill.SkillFunction == null || skill.SpellFunction == null || ch.CanUseSkill(0, sn)) { return(false); } if (!interp.check_pos(ch, skill.MinimumPosition)) { return(true); } if (CheckFunctions.CheckIf(ch, HelperFunctions.IsCharmedOrPossessed, "For some reason, you seem unable to perform that...", new List <object> { ch })) { comm.act(ATTypes.AT_GREY, "$n wanders around aimlessly.", ch, null, null, ToTypes.Room); return(true); } //// Check if mana is required int mana = 0, blood = 0; if (skill.MinimumMana > 0) { mana = ch.IsNpc() ? 0 : skill.MinimumMana .GetHighestOfTwoNumbers(100 / (2 + ch.Level - skill.RaceLevel.ToList()[(int)ch.CurrentRace])); if (CheckFunctions.CheckIf(ch, HelperFunctions.HasSufficientBloodPower, "You don't have enough blood power.", new List <object> { ch, blood })) { return(true); } if (CheckFunctions.CheckIf(ch, HelperFunctions.HasSufficientMana, "You don't have enough mana.", new List <object> { ch, mana })) { return(true); } } DateTime start, end; //// Is this a real d-fun or just a spell? if (skill.SkillFunction == null) { CharacterInstance victim = null; ObjectInstance obj = null; var targetName = string.Empty; object vo; switch (skill.Target) { default: LogManager.Instance.Bug("Bad target to Skill {0}", sn); ch.SendTo("Something went wrong..."); return(true); case TargetTypes.Ignore: vo = null; victim = ch.GetMyTarget(); targetName = argument.IsNullOrEmpty() && victim != null ? victim.Name : argument; break; case TargetTypes.OffensiveCharacter: victim = ch.GetMyTarget(); if (argument.IsNullOrEmpty() && victim == null) { ch.Printf("Confusion overcomes you as your '%s' has no target.\r\n", skill.Name); return(true); } victim = ch.GetCharacterInRoom(argument); if (CheckFunctions.CheckIfTrue(ch, !argument.IsNullOrEmpty() && victim == null, "They aren't here.")) { return(true); } if (fight.is_safe(ch, victim, true)) { return(true); } if (CheckFunctions.CheckIfTrue(ch, ch == victim && skill.Flags.IsSet(SkillFlags.NoSelf), "You can't target yourself!")) { return(true); } if (!ch.IsNpc()) { if (!victim.IsNpc()) { if (CheckFunctions.CheckIfNotNullObject(ch, ch.GetTimer(TimerTypes.PKilled), "You have been killed in the last five minutes.")) { return(true); } if (CheckFunctions.CheckIfNotNullObject(ch, victim.GetTimer(TimerTypes.PKilled), "This player has been killed in the last five minutes.")) { return(true); } if (CheckFunctions.CheckIfEquivalent(ch, ch, victim, "You really shouldn't do this to another player...")) { return(true); } } if (CheckFunctions.CheckIfTrue(ch, ch.IsAffected(AffectedByTypes.Charm) && ch.Master == victim, "You can't do that on your own follower.")) { return(true); } } if (CheckFunctions.CheckIfTrue(ch, fight.check_illegal_pk(ch, victim), "You can't do that to another player!")) { return(true); } vo = victim; break; case TargetTypes.DefensiveCharacter: victim = ch.GetCharacterInRoom(argument); if (CheckFunctions.CheckIfTrue(ch, !argument.IsNullOrEmpty() && victim == null, "They aren't here.")) { return(true); } if (CheckFunctions.CheckIfTrue(ch, ch == victim && skill.Flags.IsSet(SkillFlags.NoSelf), "You can't target yourself!")) { return(true); } vo = victim; break; case TargetTypes.Self: victim = ch; vo = ch; break; case TargetTypes.InventoryObject: obj = ch.GetCarriedObject(argument); if (CheckFunctions.CheckIfNullObject(ch, obj, "You can't find that.")) { return(true); } vo = obj; break; } Macros.WAIT_STATE(ch, skill.Rounds); //// Check for failure if (SmaugRandom.D100() + skill.difficulty * 5 > (ch.IsNpc() ? 75 : Macros.LEARNED(ch, (int)skill.ID))) { ch.FailedCast(skill, victim, obj); skill.LearnFromFailure((PlayerInstance)ch); if (mana > 0) { if (ch.IsVampire()) { ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, -blood / 2); } else { ch.CurrentMana -= mana / 2; } } return(true); } if (mana > 0) { if (ch.IsVampire()) { ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, -blood); } else { ch.CurrentMana -= mana; } } start = DateTime.Now; var retcode = skill.SpellFunction.Value.Invoke((int)skill.ID, ch.Level, ch, vo); end = DateTime.Now; skill.UseHistory.Use(ch, end.Subtract(start)); if (retcode == ReturnTypes.CharacterDied || retcode == ReturnTypes.Error || ch.CharDied()) { return(true); } if (retcode == ReturnTypes.SpellFailed) { skill.LearnFromFailure((PlayerInstance)ch); retcode = ReturnTypes.None; } else { skill.AbilityLearnFromSuccess((PlayerInstance)ch); } if (skill.Target == TargetTypes.OffensiveCharacter && victim != ch && !victim.CharDied()) { if (ch.CurrentRoom.Persons.Any(vch => victim == vch && victim.CurrentFighting == null && victim.Master != ch)) { retcode = fight.multi_hit(victim, ch, Program.TYPE_UNDEFINED); } } return(true); } if (mana > 0) { if (ch.IsVampire()) { ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, -blood); } else { ch.CurrentMana -= mana; } } ch.LastCommand = skill.SkillFunction; start = DateTime.Now; skill.SkillFunction.Value.Invoke(ch, argument); end = DateTime.Now; skill.UseHistory.Use(ch, end.Subtract(start)); // TODO: Tail chain? return(true); }
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); }
public static ReturnTypes spell_charm_person(int sn, int level, CharacterInstance ch, object vo) { var victim = (CharacterInstance)vo; var skill = RepositoryManager.Instance.GetEntity <SkillData>(sn); if (CheckFunctions.CheckIfEquivalent(ch, ch, victim, "You like yourself even better!")) { return(ReturnTypes.SpellFailed); } if (CheckFunctions.CheckIfTrueCasting(victim.IsImmune(ResistanceTypes.Magic) || victim.IsImmune(ResistanceTypes.Charm), skill, ch, CastingFunctionType.Immune, victim)) { return(ReturnTypes.SpellFailed); } if (!victim.IsNpc() && !ch.IsNpc()) { ch.SendTo("I don't think so..."); victim.SendTo("You feel charmed..."); return(ReturnTypes.SpellFailed); } var schance = victim.ModifySavingThrowWithResistance(level, ResistanceTypes.Charm); if (victim.IsAffected(AffectedByTypes.Charm) || schance == 1000 || ch.IsAffected(AffectedByTypes.Charm) || level < victim.Level || victim.IsCircleFollowing(ch) || !ch.CanCharm() || victim.SavingThrows.CheckSaveVsSpellStaff(schance, victim)) { ch.FailedCast(skill, victim); return(ReturnTypes.SpellFailed); } if (victim.Master != null) { victim.StopFollower(); } victim.AddFollower(ch); var af = new AffectData { SkillNumber = sn, Duration = GetDuration(level) }; victim.AddAffect(af); ch.SuccessfulCast(skill, victim); if (!ch.IsNpc()) { ((PlayerInstance)ch).PlayerData.NumberOfCharmies++; } if (!victim.IsNpc()) { return(ReturnTypes.None); } var mob = (MobileInstance)victim; mob.StartHating(ch); mob.StartHunting(ch); return(ReturnTypes.None); }