public static ReturnTypes SpringTheTrap(this CharacterInstance ch, ObjectInstance obj) { var level = obj.Value.ToList()[2]; var txt = string.Empty; var trapType = TrapTypes.None; DescriptorAttribute attrib = null; try { trapType = EnumerationExtensions.GetEnum <TrapTypes>(obj.Value.ToList()[1]); attrib = trapType.GetAttribute <DescriptorAttribute>(); txt = attrib.Messages.FirstOrDefault(); } catch (ArgumentException) { txt = TrapTypeLookupDefault; } var dam = SmaugRandom.Between(obj.Value.ToList()[2], obj.Value.ToList()[2] * 2); comm.act(ATTypes.AT_HITME, $"You are {txt}!", ch, null, null, ToTypes.Character); comm.act(ATTypes.AT_ACTION, $"$n is {txt}.", ch, null, null, ToTypes.Room); --obj.Value.ToList()[0]; if (obj.Value.ToList()[0] <= 0) { obj.Extract(); } var returnCode = ReturnTypes.None; if (!string.IsNullOrEmpty(attrib?.Messages.ToList()[1])) { var skill = RepositoryManager.Instance.GetEntity <SkillData>(attrib.Messages.ToList()[1]); returnCode = ch.ObjectCastSpell((int)skill.ID, level, ch); } if (trapType == TrapTypes.Blade || trapType == TrapTypes.ElectricShock) { returnCode = ch.CauseDamageTo(ch, dam, Program.TYPE_UNDEFINED); } if ((trapType == TrapTypes.PoisonArrow || trapType == TrapTypes.PoisonDagger || trapType == TrapTypes.PoisonDart || trapType == TrapTypes.PoisonNeedle) && returnCode == ReturnTypes.None) { returnCode = ch.CauseDamageTo(ch, dam, Program.TYPE_UNDEFINED); } return(returnCode); }
private static ReturnTypes ConditionBloodthirsty(CharacterInstance ch, int conditionValue) { ReturnTypes retcode = ReturnTypes.None; if (ch.Level < LevelConstants.AvatarLevel) { color.set_char_color(ATTypes.AT_BLOOD, ch); DescriptorAttribute attrib = ConditionTypes.Bloodthirsty.GetAttribute <DescriptorAttribute>(); color.send_to_char(attrib.Messages[conditionValue * 2], ch); if (conditionValue < 2) { comm.act(ATTypes.AT_HUNGRY, attrib.Messages[(conditionValue * 2) + 1], ch, null, null, ToTypes.Room); if (conditionValue == 0) { ch.WorsenMentalState(2); retcode = ch.CauseDamageTo(ch, ch.MaximumHealth / 20, (int)SkillNumberTypes.Undefined); } else { ch.WorsenMentalState(1); } } } return(retcode); }
public static ReturnTypes spell_attack(int sn, int level, CharacterInstance ch, object vo) { var skill = RepositoryManager.Instance.SKILLS.Get(sn); var vch = (CharacterInstance)vo; var saved = skill.CheckSave(level, ch, vch); if (CheckFunctions.CheckIfTrueCasting( saved && Macros.SPELL_SAVE(skill) == (int)SpellSaveEffectTypes.Negate, skill, ch, CastingFunctionType.Failed, vch)) { return(ReturnTypes.SpellFailed); } var damage = GetBaseDamage(level, ch, skill); if (saved) { var spellSaveType = EnumerationExtensions.GetEnum <SpellSaveEffectTypes>(Macros.SPELL_SAVE(skill)); switch (spellSaveType) { case SpellSaveEffectTypes.ThreeQuartersDamage: damage = GetThreeQuartersDamage(damage); break; case SpellSaveEffectTypes.HalfDamage: damage = GetHalfDamage(damage); break; case SpellSaveEffectTypes.QuarterDamage: damage = GetQuarterDamage(damage); break; case SpellSaveEffectTypes.EighthDamage: damage = GetEighthDamage(damage); break; case SpellSaveEffectTypes.Absorb: AbsorbDamage(ch, skill, vch, damage); return(ReturnTypes.None); case SpellSaveEffectTypes.Reflect: return(spell_attack(sn, level, vch, ch)); } } var retcode = ch.CauseDamageTo(vch, damage, sn); if (retcode == ReturnTypes.None && !ch.CharDied() && !vch.CharDied() && (!vch.IsAffectedBy(sn) || skill.Flags.IsSet(SkillFlags.Accumulative) || skill.Flags.IsSet(SkillFlags.ReCastable))) { retcode = AffectCharacter.spell_affectchar(sn, level, ch, vch); } return(retcode); }
private static ReturnTypes ConditionThirsty(CharacterInstance ch, int conditionValue) { ReturnTypes retcode = ReturnTypes.None; if (ch.Level < LevelConstants.AvatarLevel && ch.CurrentClass != ClassTypes.Vampire) { color.set_char_color(ATTypes.AT_THIRSTY, ch); DescriptorAttribute attrib = ConditionTypes.Thirsty.GetAttribute <DescriptorAttribute>(); color.send_to_char(attrib.Messages[conditionValue * 2], ch); if (conditionValue < 2) { comm.act(ATTypes.AT_THIRSTY, attrib.Messages[(conditionValue * 2) + 1], ch, null, null, ToTypes.Room); if (conditionValue == 0) { ch.WorsenMentalState(ch.IsPKill() ? 1 : 2); retcode = ch.CauseDamageTo(ch, 2, (int)SkillNumberTypes.Undefined); } else { ch.WorsenMentalState(1); } } } return(retcode); }
public static ReturnTypes spell_area_attack(int sn, int level, CharacterInstance ch, object vo) { var skill = RepositoryManager.Instance.SKILLS.Get(sn); if (CheckFunctions.CheckIfTrueCasting(ch.CurrentRoom.Flags.IsSet(RoomFlags.Safe), skill, ch)) { return(ReturnTypes.SpellFailed); } if (string.IsNullOrEmpty(skill.HitCharacterMessage)) { comm.act(ATTypes.AT_MAGIC, skill.HitCharacterMessage, ch, null, null, ToTypes.Character); } if (string.IsNullOrEmpty(skill.HitRoomMessage)) { comm.act(ATTypes.AT_MAGIC, skill.HitRoomMessage, ch, null, null, ToTypes.Room); } foreach (var vch in ch.CurrentRoom.Persons .Where(x => x.IsNpc() || !x.Act.IsSet((int)PlayerFlags.WizardInvisibility) || ((PlayerInstance)x).PlayerData.WizardInvisible < LevelConstants.ImmortalLevel) .Where(x => x != ch) .Where(x => !fight.is_safe(ch, x, false)) .Where(x => ch.IsNpc() || x.IsNpc() || ch.IsInArena() || (ch.IsPKill() && x.IsPKill()))) { var saved = skill.CheckSave(level, ch, vch); if (saved && CheckFunctions.CheckIfTrueCasting(Macros.SPELL_SAVE(skill) == (int)SpellSaveEffectTypes.Negate, skill, ch, CastingFunctionType.Failed, vch)) { continue; } var damage = GetBaseDamage(level, ch, skill); if (saved) { damage = GetDamageIfSaved(sn, level, ch, skill, vch, damage); } var retcode = ch.CauseDamageTo(vch, damage, sn); if (retcode == ReturnTypes.None && !ch.CharDied() && !vch.CharDied() && (!vch.IsAffectedBy(sn) || skill.Flags.IsSet(SkillFlags.Accumulative) || skill.Flags.IsSet(SkillFlags.ReCastable))) { retcode = AffectCharacter.spell_affectchar(sn, level, ch, vch); } if (retcode == ReturnTypes.CharacterDied || ch.CharDied()) { break; } } return(ReturnTypes.None); }
private static void Bash(CharacterInstance actor, SkillData skill, string arg) { comm.act(ATTypes.AT_SKILL, "WHAAAAM!!! You bash against the $d, but it doesn't budge.", actor, null, arg, ToTypes.Character); comm.act(ATTypes.AT_SKILL, "WHAAAAM!!! $n bashes against the $d, but it holds strong.", actor, null, arg, ToTypes.Room); var damage = actor.MaximumHealth / 20 + 10; actor.CauseDamageTo(actor, damage, (int)skill.ID); skill.LearnFromFailure(actor); }
public static ReturnTypes spell_acetum_primus(int sn, int level, CharacterInstance ch, object vo) { var victim = (CharacterInstance)vo; var lvl = 0.GetHighestOfTwoNumbers(level); var damage = (int)(1.3f * (2 * lvl * SmaugRandom.D4() + 7)); if (victim.SavingThrows.CheckSaveVsSpellStaff(lvl, victim)) { damage = 3 * damage / 4; } return(ch.CauseDamageTo(victim, damage, sn)); }
public static ReturnTypes spell_acid_blast(int sn, int level, CharacterInstance ch, object vo) { var victim = vo.CastAs <CharacterInstance>(); var damage = SmaugRandom.D6(level); if (victim.SavingThrows.CheckSaveVsSpellStaff(level, victim)) { damage /= 2; } return(ch.CauseDamageTo(victim, damage, sn)); }
public static ReturnTypes spell_sulfurous_spray(int sn, int level, CharacterInstance ch, object vo) { var victim = (CharacterInstance)vo; var lvl = 0.GetHighestOfTwoNumbers(level); lvl = 19.GetLowestOfTwoNumbers(lvl); var damage = (int)(1.3f * (2 * lvl * SmaugRandom.Roll(7, 1) + 11)); if (victim.SavingThrows.CheckSaveVsSpellStaff(lvl, victim)) { damage /= 4; } return(ch.CauseDamageTo(victim, damage, sn)); }
private static void BashSomething(CharacterInstance actor, ExitData exit, SkillData skill, string arg) { if (CheckFunctions.CheckIfSet(actor, exit.Flags, ExitFlags.Closed, "Calm down. It is already open.")) { return; } Macros.WAIT_STATE(actor, skill.Rounds); var keyword = exit.Flags.IsSet(ExitFlags.Secret) ? "wall" : exit.Keywords; var chance = !actor.IsNpc() ? Macros.LEARNED(actor, (int)skill.ID) / 2 : 90; if (exit.Flags.IsSet(ExitFlags.Locked)) { chance /= 3; } if (exit.Flags.IsSet(ExitFlags.BashProof) || actor.CurrentMovement < 15 || SmaugRandom.D100() >= chance + 4 * (actor.GetCurrentStrength() - 19)) { Bash(actor, skill, arg); return; } BashExit(exit); comm.act(ATTypes.AT_SKILL, "Crash! You bashed open the $d!", actor, null, keyword, ToTypes.Character); comm.act(ATTypes.AT_SKILL, "$n bashes open the $d!", actor, null, keyword, ToTypes.Room); skill.LearnFromSuccess(actor); var reverseExit = exit.GetReverse(); BashExit(reverseExit); var destination = exit.GetDestination(RepositoryManager.Instance); foreach (var ch in destination.Persons) { comm.act(ATTypes.AT_SKILL, "The $d crashes open!", ch, null, reverseExit.Keywords, ToTypes.Character); } actor.CauseDamageTo(actor, actor.CurrentHealth / 20, (int)skill.ID); }
public static ReturnTypes spell_caustic_fount(int sn, int level, CharacterInstance ch, object vo) { var victim = (CharacterInstance)vo; var lvl = 0.GetHighestOfTwoNumbers(level); lvl = 42.GetLowestOfTwoNumbers(lvl); var damage = (int)(1.3f * (2 * lvl * SmaugRandom.D6() - 31)); damage = 0.GetHighestOfTwoNumbers(damage); if (victim.SavingThrows.CheckSaveVsSpellStaff(lvl, victim)) { damage = damage * 1 / 2; } return(ch.CauseDamageTo(victim, damage, sn)); }
public static ReturnTypes spell_black_hand(int sn, int level, CharacterInstance ch, object vo) { var lvl = 0.GetHighestOfTwoNumbers(level); lvl = 5.GetLowestOfTwoNumbers(lvl); var dam = (int)(1.3f * (lvl * SmaugRandom.D6() + 3)); var victim = (CharacterInstance)vo; if (victim.SavingThrows.CheckSaveVsSpellStaff(lvl, victim)) { dam /= 4; } return(ch.CauseDamageTo(victim, dam, sn)); }
public static ReturnTypes spell_colour_spray(int sn, int level, CharacterInstance ch, object vo) { var victim = (CharacterInstance)vo; var modLevel = level.GetLowestOfTwoNumbers(DamageValues.Length * 2 / 2 - 1); modLevel = modLevel.GetHighestOfTwoNumbers(0); if (DamageValues.Length >= modLevel) { throw new InvalidDataException( $"ModLevel {modLevel} is larger than the Damage Array size of {DamageValues.Length}"); } var dam = SmaugRandom.Between(DamageValues[modLevel] / 2, DamageValues[modLevel] * 2); if (victim.SavingThrows.CheckSaveVsSpellStaff(modLevel, victim)) { dam /= 2; } return(ch.CauseDamageTo(victim, dam, sn)); }
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_dispel_evil(int sn, int level, CharacterInstance ch, object vo) { var victim = (CharacterInstance)vo; var skill = RepositoryManager.Instance.GetEntity <SkillData>(sn); if (!ch.IsNpc() && ch.IsEvil()) { victim = ch; } if (victim.IsGood()) { comm.act(ATTypes.AT_MAGIC, "Thoric protects $N.", ch, null, victim, ToTypes.Room); return(ReturnTypes.SpellFailed); } if (victim.IsNeutral()) { comm.act(ATTypes.AT_MAGIC, "$N does not seem to be affected.", ch, null, victim, ToTypes.Character); return(ReturnTypes.SpellFailed); } if (CheckFunctions.CheckIfTrueCasting(victim.IsImmune(ResistanceTypes.Magic), skill, ch, CastingFunctionType.Immune, victim)) { return(ReturnTypes.SpellFailed); } var damage = SmaugRandom.Roll(level, 4); if (victim.SavingThrows.CheckSaveVsSpellStaff(level, victim)) { damage /= 2; } return(ch.CauseDamageTo(victim, damage, sn)); }
public static ReturnTypes ranged_got_target(CharacterInstance ch, CharacterInstance victim, ObjectInstance weapon, ObjectInstance projectile, int dist, int dt, string stxt, ATTypes color) { if (ch.CurrentRoom.Flags.IsSet(RoomFlags.Safe)) { if (projectile != null) { ch.PrintfColor("Your %s is blasted from existence by a godly presence.", projectile); comm.act(color, "A godly presence smites $p!", ch, projectile, null, ToTypes.Room); projectile.Extract(); } else { ch.Printf("Your %s is blasted from existence by a godly presence.", stxt); comm.act(color, "A godly presence smites $t!", ch, stxt.AddArticle(ArticleAppendOptions.TheToFront), null, ToTypes.Room); } return(ReturnTypes.None); } var skill = RepositoryManager.Instance.GetEntity <SkillData>("MissileWeapons"); if (victim.IsNpc() && victim.Act.IsSet((int)ActFlags.Sentinel) && ch.CurrentRoom != victim.CurrentRoom) { if (projectile == null) { return(ch.CauseDamageTo(victim, 0, dt)); } skill.LearnFromFailure(ch); if (SmaugRandom.D100() < 50) { projectile.Extract(); } else { if (projectile.InObject != null) { projectile.RemoveFrom(projectile.InObject); } if (projectile.CarriedBy != null) { projectile.RemoveFrom(); } victim.CurrentRoom.AddTo(projectile); } return(ch.CauseDamageTo(victim, 0, dt)); } if (SmaugRandom.D100() > 50 || (projectile != null && weapon != null && ch.CanUseSkill(SmaugRandom.D100(), skill))) { return(projectile != null?fight.projectile_hit(ch, victim, weapon, projectile, dist) : Attack.spell_attack(dt, ch.Level, ch, victim)); } skill.LearnFromFailure(ch); var returnCode = ch.CauseDamageTo(victim, 0, dt); if (projectile == null) { return(returnCode); } if (SmaugRandom.D100() < 50) { projectile.Extract(); } else { if (projectile.InObject != null) { projectile.RemoveFrom(projectile.InObject); } if (projectile.CarriedBy != null) { projectile.RemoveFrom(); } victim.CurrentRoom.AddTo(projectile); } return(returnCode); }
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); }