private static object TargetCharacterWithDefensiveSpell(string arg, CharacterInstance ch, bool silence, SkillData skill) { CharacterInstance victim; if (arg.IsNullOrEmpty()) { victim = ch; } else { victim = ch.GetCharacterInRoom(arg); if (CheckFunctions.CheckIfNullObject(ch, victim, !silence ? "They aren't here." : "")) { return(null); } } // Nuisance flag will pick who you are fighting for defensive spells up to 36% of the time if (!ch.IsNpc() && ch.CurrentFighting != null && ((PlayerInstance)ch).PlayerData.Nuisance != null && ((PlayerInstance)ch).PlayerData.Nuisance.Flags > 5 && SmaugRandom.D100() < (((PlayerInstance)ch).PlayerData.Nuisance.Flags - 5) * 8 + 6 * ((PlayerInstance)ch).PlayerData.Nuisance.Power) { victim = ch.GetMyTarget(); } return(CheckFunctions.CheckIfTrue(ch, ch == victim && skill.Flags.IsSet(SkillFlags.NoSelf), !silence ? "You can't cast this on yourself!" : "") ? null : victim); }
public static void do_cast(CharacterInstance ch, string argument) { var pch = (PlayerInstance)ch; switch (pch.SubState) { case CharacterSubStates.TimerDoAbort: if (!CastAbortTimer(pch, argument)) { return; } break; case CharacterSubStates.Pause: if (!CastPause(pch, argument)) { return; } break; default: if (!DefaultCast(ch, argument)) { return; } break; } if (_skill != null && _skill.Name.EqualsIgnoreCase("ventriloquate")) { magic.say_spell(ch, (int)_skill.ID); } if (!_dontWait) { Macros.WAIT_STATE(ch, _skill.Rounds); } if (!magic.process_spell_components(ch, (int)_skill.ID)) { if (ch.IsVampire()) { ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, -1 * 1.GetHighestOfTwoNumbers(_blood / 2)); } else if (ch.Level < LevelConstants.ImmortalLevel) { ch.CurrentMana -= _mana / 2; } //skills.learn_from_failure(ch, (int)_skill.ID); return; } if (!ch.IsNpc() && SmaugRandom.D100() + _skill.difficulty * 5 > pch.PlayerData.GetSkillMastery(_skill.ID)) { } else { } }
public static void AbilityLearnFromSuccess(this SkillData skill, PlayerInstance ch) { var sn = (int)skill.ID; var skillMastery = ch.PlayerData.GetSkillMastery(sn); if (ch.IsNpc() || skillMastery <= 0) { return; } var adept = skill.RaceAdept.ToList()[(int)ch.CurrentRace]; var skillLevel = skill.RaceLevel.ToList()[(int)ch.CurrentRace]; if (skillLevel == 0) { skillLevel = ch.Level; } if (skillMastery < adept) { var schance = skillMastery + 5 * skill.difficulty; var percent = SmaugRandom.D100(); var learn = 1; if (percent >= schance) { learn = 2; } else if (schance - percent > 25) { return; } ch.PlayerData.UpdateSkillMastery(sn, adept.GetLowestOfTwoNumbers(skillMastery + learn)); int gain; if (ch.PlayerData.GetSkillMastery(sn) == adept) { gain = 1000 * skillLevel; ch.SetColor(ATTypes.AT_WHITE); ch.Printf("You are now an adept of %s! You gain %d bonus experience!", skill.Name, gain); } else { gain = 20 * skillLevel; if (ch.CurrentFighting == null) // TODO: Check gsn_hide && gsn_sneak { ch.SetColor(ATTypes.AT_WHITE); ch.Printf("You gain %d experience points from your success!", gain); } } ch.GainXP(gain); } }
private static bool CantSleepDueToMentalState(CharacterInstance ch, int modifier) { if (ch.MentalState > 30 && SmaugRandom.D100() + modifier < ch.MentalState) { ch.SendTo("You just can't seem to calm yourself down enough to sleep."); comm.act(ATTypes.AT_PLAIN, "$n closes $s eyes for a few moments, but just can't seem to go to sleep.", ch, null, null, ToTypes.Room); return(true); } return(false); }
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 bool CheckGrip(CharacterInstance ch, CharacterInstance victim, IRepositoryManager dbManager = null) { if (!victim.IsAwake()) { return(false); } if (victim.IsNpc() && !victim.Defenses.IsSet((int)DefenseTypes.Grip)) { return(false); } var skill = (dbManager ?? RepositoryManager.Instance).GetEntity <SkillData>("grip"); if (skill == null) { throw new ObjectNotFoundException("Skill 'grip' not found"); } int chance; if (victim.IsNpc()) { chance = 60.GetLowestOfTwoNumbers(2 * victim.Level); } else { chance = (int)Macros.LEARNED(victim, (int)skill.ID) / 2; } chance += 2 * (victim.GetCurrentLuck() - 13); if (SmaugRandom.D100() >= chance + victim.Level - ch.Level) { skill.LearnFromFailure(victim); return(false); } comm.act(ATTypes.AT_SKILL, "You evade $n's attempt to disarm you.", ch, null, victim, ToTypes.Victim); comm.act(ATTypes.AT_SKILL, "$N holds $S weapon strongly, and is not disarmed.", ch, null, victim, ToTypes.Character); skill.LearnFromSuccess(victim); return(true); }
private static void GainLearningInSkill(SkillData skill, PlayerInstance ch, int mastery) { var chance = ch.GetLearned((int)skill.ID) + 5 * skill.difficulty; var percent = SmaugRandom.D100(); int learn; if (percent >= chance) { learn = 2; } else if (chance - percent > 25) { return; } else { learn = 1; } mastery.GetLowestOfTwoNumbers((int)(ch.GetLearned(skill.ID) + learn)); }
/// <summary> /// Mental state can affect finding an object, used by get/drop/put/quaff/etc. /// Gets increasingly "freaky" based on mental state and drunkenness /// </summary> /// <param name="ch"></param> /// <returns></returns> public static bool FindObject_CheckMentalState(CharacterInstance ch) { var ms = ch.MentalState; // We're going to be nice and let nothing weird happen unless you're a tad messed up var drunk = 1.GetHighestOfTwoNumbers(ch.IsNpc() ? 0 : ((PlayerInstance)ch).PlayerData.ConditionTable[ConditionTypes.Drunk]); if (Math.Abs(ms) + drunk / 3 < 30) { return(false); } if (SmaugRandom.D100() + (ms < 0 ? 15 : 5) > Math.Abs(ms) / 2 + drunk / 4) { return(false); } var output = ms > 15 ? ObjectMessageLargeMap[SmaugRandom.Between(1.GetHighestOfTwoNumbers(ms / 5 - 15), (ms + 4) / 5)] : ObjectMessageSmallMap[SmaugRandom.Between(1, (Math.Abs(ms) / 2 + drunk).GetNumberThatIsBetween(1, 60) / 10)]; ch.SendTo(output); return(true); }
public static void CheckIfExecute(MobileInstance mob, MudProgTypes type) { foreach (var mprog in mob.MobIndex.MudProgs) { int chance; if (!int.TryParse(mprog.ArgList, out chance)) { throw new InvalidDataException(); } if (mprog.Type != type || SmaugRandom.D100() > chance) { continue; } mprog.Execute(mob); if (type != MudProgTypes.Greet && type != MudProgTypes.GreetAll) { break; } } }
public static void LearnFromFailure(this SkillData skill, CharacterInstance ch) { if (ch.IsNpc()) { return; } var pch = (PlayerInstance)ch; if (pch.PlayerData == null) { return; } var val = pch.GetLearned((int)skill.ID); if (val <= 0) { return; } var chance = pch.GetLearned((int)skill.ID) + 5 * skill.difficulty; if (chance - SmaugRandom.D100() > 25) { return; } int mastery = skill.GetMasteryLevel(pch); if (pch.GetLearned((int)skill.ID) < mastery - 1) { //pch.PlayerData.Learned.ToList().First(x => x == skill.ID) = // mastery.GetLowestOfTwoNumbers((int)(pch.GetLearned(skill.ID) + 1)); } }
public static bool Execute(MobileInstance ch, IManager dbManager) { if (!ch.IsInCombatPosition()) { return(false); } var victim = ch.GetMyTarget(); if (victim == null || (SmaugRandom.D100() > 2 * ch.Level)) { return(false); } comm.act(ATTypes.AT_HIT, "You bite $N!", ch, null, victim, ToTypes.Character); comm.act(ATTypes.AT_ACTION, "$n bites $N!", ch, null, victim, ToTypes.NotVictim); comm.act(ATTypes.AT_POISON, "$n bites you!", ch, null, victim, ToTypes.Victim); var databaseMgr = (IRepositoryManager)(dbManager ?? RepositoryManager.Instance); Spells.Poison.spell_poison((int)databaseMgr.GetEntity <SkillData>("poison").ID, ch.Level, ch, victim); return(true); }
public static void do_drag(CharacterInstance ch, string argument) { if (CheckFunctions.CheckIfNpc(ch, ch, "Only characters can drag.")) { return; } if (CheckFunctions.CheckIfTrue(ch, ch.HasTimer(TimerTypes.PKilled), "You can't drag a player right now.")) { return; } var pch = (PlayerInstance)ch; var firstArg = argument.FirstWord(); if (CheckFunctions.CheckIfEmptyString(pch, firstArg, "Drag whom?")) { return; } var victim = pch.GetCharacterInRoom(firstArg); if (CheckFunctions.CheckIfNullObject(pch, victim, "They aren't here.")) { return; } if (CheckFunctions.CheckIfEquivalent(pch, pch, victim, "You take yourself by the scruff of your neck, but go nowhere.")) { return; } if (CheckFunctions.CheckIfNpc(ch, victim, "You can only drag characters.")) { return; } if (CheckFunctions.CheckIfTrue(ch, !victim.Act.IsSet((int)PlayerFlags.ShoveDrag) || (!victim.IsNpc() && !victim.IsDeadly()), "That character doesn't seem to appreciate your attentions.")) { return; } if (CheckFunctions.CheckIfTrue(ch, victim.HasTimer(TimerTypes.PKilled), "You can't drag that player right now.")) { return; } if (CheckFunctions.CheckIf(ch, HelperFunctions.IsFighting, "You try, but can't get close enough.", new List <object> { ch })) { return; } if (CheckFunctions.CheckIfTrue(ch, !ch.IsNpc() && !victim.IsDeadly() && ch.IsDeadly(), "You can't drag a deadly character.")) { return; } if (CheckFunctions.CheckIfTrue(ch, !ch.IsNpc() && !ch.IsDeadly() && (int)ch.CurrentPosition > 3, "They don't seem to need your assistance.")) { return; } var secondArg = argument.SecondWord(); if (CheckFunctions.CheckIfEmptyString(ch, secondArg, "Drag them in which direction?")) { return; } if (CheckFunctions.CheckIfTrue(ch, Math.Abs(ch.Level - victim.Level) > 5, "There is too great an experience difference for you to even bother.")) { return; } if (CheckFunctions.CheckIfTrue(ch, victim.CurrentRoom.Flags.IsSet(RoomFlags.Safe) && victim.GetTimer(TimerTypes.ShoveDrag) == null, "That character cannot be dragged right now.")) { return; } var exitDir = EnumerationExtensions.GetEnumByName <DirectionTypes>(secondArg); var exit = ch.CurrentRoom.GetExit(exitDir); if (CheckFunctions.CheckIfNullObject(ch, exit, "There's no exit in that direction.")) { return; } if (CheckFunctions.CheckIfTrue(ch, !IsPassable(exit, victim), "There's no exit in that direction.")) { return; } var toRoom = exit.GetDestination(); if (CheckFunctions.CheckIfSet(ch, toRoom.Flags, RoomFlags.Death, "You cannot drag someone into a death trap.")) { return; } if (CheckFunctions.CheckIfTrue(ch, ch.CurrentRoom.Area != toRoom.Area && !toRoom.Area.IsInHardRange(victim), "That character cannot enter that area.")) { victim.CurrentPosition = PositionTypes.Standing; return; } var chance = CalculateChanceToDrag(ch, victim); if (CheckFunctions.CheckIfTrue(ch, chance < SmaugRandom.D100(), "You failed.")) { victim.CurrentPosition = PositionTypes.Standing; return; } if ((int)victim.CurrentPosition < (int)PositionTypes.Standing) { DragIntoNextRoom(ch, victim, exit); return; } ch.SendTo("You cannot do that to someone who is standing."); }
private static object TargetCharacterWithOffensiveSpell(string arg, CharacterInstance ch, bool silence, SkillData skill) { CharacterInstance victim; if (arg.IsNullOrEmpty()) { victim = ch.GetMyTarget(); if (CheckFunctions.CheckIfNullObject(ch, victim, !silence ? "Cast the spell on whom?" : "")) { return(null); } } else { victim = ch.GetCharacterInRoom(arg); if (CheckFunctions.CheckIfNullObject(ch, victim, !silence ? "They aren't here." : "")) { return(null); } } // Nuisance flag will pick who you are fighting for offensive spells up to 92% of the time if (!ch.IsNpc() && ch.CurrentFighting != null && ((PlayerInstance)ch).PlayerData.Nuisance != null && ((PlayerInstance)ch).PlayerData.Nuisance.Flags > 5 && SmaugRandom.D100() < (((PlayerInstance)ch).PlayerData.Nuisance.Flags - 5) * 8 + 6 * ((PlayerInstance)ch).PlayerData.Nuisance.Power) { victim = ch.GetMyTarget(); } if (fight.is_safe(ch, victim, true)) { return(null); } if (ch == victim) { if (CheckFunctions.CheckIfSet(ch, skill.Flags, SkillFlags.NoSelf, !silence ? "You can't cast this on yourself!" : "")) { return(null); } if (!silence) { ch.SendTo("Cast this on yourself? Okay..."); } } if (!ch.IsNpc()) { if (!victim.IsNpc()) { if (CheckFunctions.CheckIfTrue(ch, ch.GetTimer(TimerTypes.PKilled) != null, !silence ? "You have been killed in the last 5 minutes." : "")) { return(null); } if (CheckFunctions.CheckIfTrue(ch, victim.GetTimer(TimerTypes.PKilled) != null, !silence ? "This player has been killed in the last 5 minutes." : "")) { return(null); } if (CheckFunctions.CheckIfTrue(ch, ch.Act.IsSet((int)PlayerFlags.Nice) && ch != victim, !silence ? "You are too nice to attack another player." : "")) { return(null); } if (victim != ch) { if (!silence) { ch.SendTo("You really shouldn't do this to another player..."); } else if (victim.GetMyTarget() != ch) { return(null); } } } if (CheckFunctions.CheckIfTrue(ch, ch.IsAffected(AffectedByTypes.Charm) && ch.Master == victim, !silence ? "You can't do that to your own follower." : "")) { return(null); } } fight.check_illegal_pk(ch, victim); return(victim); }
public static void show_char_to_char_1(CharacterInstance victim, PlayerInstance ch) { if (victim.CanSee(ch) && !ch.IsNpc() && !ch.Act.IsSet((int)PlayerFlags.WizardInvisibility)) { comm.act(ATTypes.AT_ACTION, "$n looks at you.", ch, null, victim, ToTypes.Victim); comm.act(ATTypes.AT_ACTION, victim != ch ? "$n looks at $N." : "$n looks at $mself.", ch, null, victim, ToTypes.NotVictim); } if (!string.IsNullOrEmpty(victim.Description)) { ch.SendTo(victim.CurrentMorph?.Morph != null ? victim.CurrentMorph.Morph.Description : victim.Description); } else { if (victim.CurrentMorph?.Morph != null) { ch.SendTo(victim.CurrentMorph.Morph.Description); } else if (victim.IsNpc()) { comm.act(ATTypes.AT_PLAIN, "You see nothing special about $M.", ch, null, victim, ToTypes.Character); } else if (ch != victim) { comm.act(ATTypes.AT_PLAIN, "$E isn't much to look at...", ch, null, victim, ToTypes.Character); } else { comm.act(ATTypes.AT_PLAIN, "You're not much to look at...", ch, null, null, ToTypes.Character); } } ch.ShowRaceOf(victim); ch.ShowConditionTo(victim); var found = false; for (var i = 0; i < GameConstants.MaximumWearLocations; i++) { var wearLoc = EnumerationExtensions.GetEnum <WearLocations>(i); var obj = victim.GetEquippedItem(wearLoc); if (obj != null && ch.CanSee(obj)) { if (!found) { ch.SendTo("\r\n"); if (victim != ch) { comm.act(ATTypes.AT_PLAIN, "$n is using:", ch, null, victim, ToTypes.Character); } else { comm.act(ATTypes.AT_PLAIN, "You are using:", ch, null, null, ToTypes.Character); } found = true; } if (!victim.IsNpc()) { var race = RepositoryManager.Instance.GetRace(victim.CurrentRace); ch.SendTo(race.WhereNames.ToList()[i]); } else { ch.SendTo(LookupManager.Instance.GetLookup("WhereNames", i)); } ch.SendTo(obj.GetFormattedDescription(ch, true)); ch.SendTo("\r\n"); } } if (ch.IsNpc() || victim == ch) { return; } if (ch.IsImmortal()) { if (victim.IsNpc()) { ch.Printf("\r\nMobile #%d '%s' ", ((MobileInstance)victim).MobIndex.ID, victim.Name); } else { ch.Printf("\r\n%s ", victim.Name); } ch.Printf("is a level %d %s %s.\r\n", victim.Level, RepositoryManager.Instance.GetRace(victim.CurrentRace).Name, RepositoryManager.Instance.GetClass(victim.CurrentClass).Name); } var skill = RepositoryManager.Instance.GetEntity <SkillData>("peek"); if (skill == null) { throw new ObjectNotFoundException("Skill 'peek' not found"); } if (SmaugRandom.D100() < Macros.LEARNED(ch, (int)skill.ID)) { ch.Printf("\r\nYou peek at %s inventory:\r\n", victim.Gender.PossessivePronoun()); show_list_to_char(victim.Carrying.ToList(), ch, true, true); skill.LearnFromSuccess(ch); } else if (ch.PlayerData.GetSkillMastery(skill.ID) > skill.GetMasteryLevel(ch)) { skill.LearnFromFailure(ch); } }
public static CharacterInstance GetShopkeep(CharacterInstance ch, IGameManager gameManager = null) { var keeper = ch.CurrentRoom.Persons.OfType <MobileInstance>() .FirstOrDefault(mob => mob.IsNpc() && mob.MobIndex.Shop != null); if (CheckFunctions.CheckIfNullObject(ch, keeper, "You can't do that here.")) { return(null); } if (DoesKeeperHateKillers(keeper, ch)) { return(null); } if (DoesKeeperHateThieves(keeper, ch)) { return(null); } if (DoesKeeperHateFighting(keeper, ch)) { return(null); } if (IsKeeperFighting(keeper, ch)) { return(null); } if (IsShopClosed(keeper, ch, (gameManager ?? GameManager.Instance).GameTime.Hour)) { return(null); } if (CheckFunctions.CheckIfTrue(ch, keeper.CurrentPosition == PositionTypes.Sleeping, "While they're asleep?")) { return(null); } if (CheckFunctions.CheckIfTrue(ch, (int)keeper.CurrentPosition < (int)PositionTypes.Sleeping, "I don't think they can hear you...")) { return(null); } if (IsVisibleToKeeper(keeper, ch)) { return(null); } var speakswell = keeper.KnowsLanguage(ch.Speaking, ch).GetLowestOfTwoNumbers(ch.KnowsLanguage(ch.Speaking, keeper)); if (SmaugRandom.D100() % 65 > speakswell) { string buffer; if (speakswell > 60) { buffer = $"{ch.Name} Could you repeat that? I didn't quite catch it."; } else if (speakswell > 50) { buffer = $"{ch.Name} Could you say that a little more clearly please?"; } else if (speakswell > 40) { buffer = $"{ch.Name} Sorry... What was that you wanted?"; } else { buffer = $"{ch.Name} I can't understand you."; } Tell.do_tell(keeper, buffer); return(null); } return(keeper); }
public static ReturnTypes move_char(CharacterInstance ch, ExitData pexit, int fall) { var drunk = false; var nuisance = false; string txt; if (!ch.IsNpc()) { var pch = (PlayerInstance)ch; if (ch.IsDrunk(2) && ch.CurrentPosition != PositionTypes.Shove && ch.CurrentPosition != PositionTypes.Drag) { drunk = true; } if (pch.PlayerData.Nuisance != null && pch.PlayerData.Nuisance.Flags > 8 && ch.CurrentPosition != PositionTypes.Shove && ch.CurrentPosition != PositionTypes.Drag && SmaugRandom.D100() > pch.PlayerData.Nuisance.Flags * pch.PlayerData.Nuisance.Power) { nuisance = true; } } int door; ExitData exit = null; // Nuisance flag, makes them walk in random directions 50% of the time if ((nuisance || drunk) && fall == 0) { door = db.number_door(); exit = ch.CurrentRoom.GetExit(door); } #if DEBUG if (exit != null) { LogManager.Instance.Info("{0} to door {1}", ch.Name, pexit.Direction); } #endif if (ch.IsNpc() && ch.Act.IsSet((int)ActFlags.Mounted)) { return(ReturnTypes.None); } var inRoom = ch.CurrentRoom; var fromRoom = inRoom; RoomTemplate toRoom = null; if (exit?.Destination == null) { if (drunk && ch.CurrentPosition != PositionTypes.Mounted && ch.CurrentRoom.SectorType != SectorTypes.ShallowWater && ch.CurrentRoom.SectorType != SectorTypes.DeepWater && ch.CurrentRoom.SectorType != SectorTypes.Underwater && ch.CurrentRoom.SectorType != SectorTypes.OceanFloor) { switch (SmaugRandom.Bits(4)) { default: comm.act(ATTypes.AT_ACTION, "You drunkenly stumble into some obstacle.", ch, null, null, ToTypes.Character); comm.act(ATTypes.AT_ACTION, "$n drunkenly stumbles into a nearby obstacle.", ch, null, null, ToTypes.Room); break; case 3: comm.act(ATTypes.AT_ACTION, "In your drunken stupor you trip over your own feet and tumble to the ground.", ch, null, null, ToTypes.Character); comm.act(ATTypes.AT_ACTION, "$n stumbles drunkenly, trips and tumbles to the ground.", ch, null, null, ToTypes.Room); ch.CurrentPosition = PositionTypes.Resting; break; case 4: comm.act(ATTypes.AT_SOCIAL, "You utter a string of slurred obscenities.", ch, null, null, ToTypes.Character); comm.act(ATTypes.AT_ACTION, "Something blurry and immovable has intercepted you as you stagger along.", ch, null, null, ToTypes.Character); comm.act(ATTypes.AT_HURT, "Oh geez... THAT really hurt. Everything slowly goes dark and numb...", ch, null, null, ToTypes.Character); comm.act(ATTypes.AT_ACTION, "$n drunkenly staggers into something.", ch, null, null, ToTypes.Room); comm.act(ATTypes.AT_SOCIAL, "$n utters a string of slurred obscenities: @*&^%@*&!", ch, null, null, ToTypes.Room); comm.act(ATTypes.AT_ACTION, "$n topples to the ground with a thud.", ch, null, null, ToTypes.Room); ch.CurrentPosition = PositionTypes.Incapacitated; break; } } else if (nuisance) { comm.act(ATTypes.AT_ACTION, "You stare around trying to remember where you where going.", ch, null, null, ToTypes.Character); } else if (drunk) { comm.act(ATTypes.AT_ACTION, "You stare around trying to make sense of things through your drunken stupor.", ch, null, null, ToTypes.Character); } else { ch.SendTo("Alas, you cannot go that way.\r\n"); } return(ReturnTypes.None); } door = (int)exit.Direction; var distance = exit.Distance; // Exit is only a "window", there is no way to travel in that direction unless it's a door with a window in it if (CheckFunctions.CheckIfTrue(ch, exit.Flags.IsSet(ExitFlags.Window) && !exit.Flags.IsSet(ExitFlags.IsDoor), "Alas, you cannot go that way.")) { return(ReturnTypes.None); } if (ch.IsNpc()) { if (exit.Flags.IsSet(ExitFlags.Portal)) { comm.act(ATTypes.AT_PLAIN, "Mobs can't use portals.", ch, null, null, ToTypes.Character); return(ReturnTypes.None); } if (exit.Flags.IsSet(ExitFlags.NoMob) || toRoom.Flags.IsSet(RoomFlags.NoMob)) { comm.act(ATTypes.AT_PLAIN, "Mobs can't enter there.", ch, null, null, ToTypes.Character); return(ReturnTypes.None); } } if (exit.Flags.IsSet(ExitFlags.Closed) && (!ch.IsAffected(AffectedByTypes.PassDoor) || exit.Flags.IsSet(ExitFlags.NoPassDoor))) { if (!exit.Flags.IsSet(ExitFlags.Secret) && !exit.Flags.IsSet(ExitFlags.Dig)) { if (drunk) { comm.act(ATTypes.AT_PLAIN, "$n runs into the $d in $s drunken state.", ch, null, null, ToTypes.Room); comm.act(ATTypes.AT_PLAIN, "You run into the $d in your drunken state.", ch, null, null, ToTypes.Character); } else { comm.act(ATTypes.AT_PLAIN, "The $d is closed.", ch, null, exit.Keywords, ToTypes.Character); } } else { ch.SendTo(drunk ? "You stagger around in your drunken state.\r\n" : "Alas, you cannot go that way.\r\n"); } return(ReturnTypes.None); } // Crazy virtual room idea, created upon demand. if (distance > 1) { toRoom = act_move.generate_exit(inRoom, exit); if (toRoom == null) { ch.SendTo("Alas, you cannot go that way."); } } if (CheckFunctions.CheckIfTrue(ch, fall == 0 && ch.IsAffected(AffectedByTypes.Charm) && ch.Master != null && inRoom == ch.Master.CurrentRoom, "What? And leave your beloved master?")) { return(ReturnTypes.None); } if (CheckFunctions.CheckIfTrue(ch, toRoom.IsPrivate(), "That room is private right now.")) { return(ReturnTypes.None); } if (CheckFunctions.CheckIfNotNullObject(ch, toRoom.IsDoNotDisturb(ch), "That room is \"do not disturb\" right now.")) { return(ReturnTypes.None); } if (!ch.IsImmortal() && !ch.IsNpc() && ch.CurrentRoom.Area != toRoom.Area) { if (ch.Level < toRoom.Area.LowHardRange) { ch.SetColor(ATTypes.AT_TELL); switch (toRoom.Area.LowHardRange - ch.Level) { case 1: ch.SendTo("A voice in your mind says, 'You are nearly ready to go that way...'"); break; case 2: ch.SendTo("A voice in your mind says, 'Soon you shall be ready to travel down this path... soon.'"); break; case 3: ch.SendTo("A voice in your mind says, 'You are not ready to go down that path... yet.'"); break; default: ch.SendTo("A voice in your mind says, 'You are not ready to go down that path.'"); break; } return(ReturnTypes.None); } if (ch.Level > toRoom.Area.HighHardRange) { ch.SetColor(ATTypes.AT_TELL); ch.SendTo("A voice in your mind says, 'There is nothing more for you down that path.'"); return(ReturnTypes.None); } } if (fall == 0 && !ch.IsNpc()) { int move; // Prevent deadlies from entering a nopkill-flagged area from a non-flagged area, // but allow them to move around if already inside a nopkill area. if (toRoom.Area.Flags.IsSet(AreaFlags.NoPlayerVsPlayer) && !ch.CurrentRoom.Area.Flags.IsSet(AreaFlags.NoPlayerVsPlayer) && ch.IsPKill() && !ch.IsImmortal()) { ch.SetColor(ATTypes.AT_MAGIC); ch.SendTo("\r\nA godly force forbids deadly characters from entering that area..."); return(ReturnTypes.None); } if (inRoom.SectorType == SectorTypes.Air || toRoom.SectorType == SectorTypes.Air || exit.Flags.IsSet(ExitFlags.Fly)) { if (CheckFunctions.CheckIfTrue(ch, ch.CurrentMount != null && !ch.CurrentMount.IsAffected(AffectedByTypes.Flying), "Your mount can't fly.")) { return(ReturnTypes.None); } if (CheckFunctions.CheckIfTrue(ch, ch.CurrentMount == null && !ch.IsAffected(AffectedByTypes.Flying), "You'd need to fly to go there.")) { return(ReturnTypes.None); } } if (inRoom.SectorType == SectorTypes.DeepWater || toRoom.SectorType == SectorTypes.DeepWater) { if ((ch.CurrentMount != null && !ch.CurrentMount.IsFloating()) || !ch.IsFloating()) { // Look for a boat. We can use the boat obj for a more detailed description. var boat = ch.GetObjectOfType(ItemTypes.Boat); if (CheckFunctions.CheckIfNullObject(ch, boat, ch.CurrentMount != null ? "Your mount would drown!" : "You'd need a boat to go there.")) { return(ReturnTypes.None); } txt = drunk ? "paddles unevenly" : "paddles"; } } if (exit.Flags.IsSet(ExitFlags.Climb)) { var found = false; if (ch.CurrentMount != null && ch.CurrentMount.IsAffected(AffectedByTypes.Flying)) { found = true; } else if (ch.IsAffected(AffectedByTypes.Flying)) { found = true; } if (!found && ch.CurrentMount == null) { // TODO Climbing } if (CheckFunctions.CheckIfTrue(ch, !found, "You can't climb.")) { return(ReturnTypes.None); } } if (ch.CurrentMount != null) { if (PositionMoveMessage.ContainsKey(ch.CurrentMount.CurrentPosition)) { ch.SendTo(PositionMoveMessage[ch.CurrentMount.CurrentPosition]); return(ReturnTypes.None); } if (!ch.CurrentMount.IsFloating()) { } // TODO } } return(ReturnTypes.None); }
public static CharacterInstance scan_for_victim(CharacterInstance ch, ExitData pexit, string name) { if (ch.IsAffected(AffectedByTypes.Blind) || pexit == null) { return(null); } var was_in_room = ch.CurrentRoom; var max_distance = 8; if (ch.IsVampire() && GameManager.Instance.GameTime.Hour < 21 && GameManager.Instance.GameTime.Hour > 5) { max_distance = 1; } if (ch.Level < 50) { --max_distance; } if (ch.Level < 40) { --max_distance; } if (ch.Level < 30) { --max_distance; } for (int dist = 1; dist <= max_distance; dist++) { if (pexit.Flags.IsSet(ExitFlags.Closed)) { break; } if (pexit.GetDestination().IsPrivate() && ch.Level < LevelConstants.GetLevel(ImmortalTypes.Greater)) { break; } ch.CurrentRoom.RemoveFrom(ch); pexit.GetDestination().AddTo(ch); var victim = ch.GetCharacterInRoom(name); if (victim != null) { ch.CurrentRoom.RemoveFrom(ch); was_in_room.AddTo(ch); return(victim); } switch (ch.CurrentRoom.SectorType) { default: dist++; break; case SectorTypes.Air: if (SmaugRandom.D100() < 80) { dist++; } break; case SectorTypes.Forest: case SectorTypes.City: case SectorTypes.Desert: case SectorTypes.Hills: dist += 2; break; case SectorTypes.ShallowWater: case SectorTypes.DeepWater: dist += 3; break; case SectorTypes.Mountain: case SectorTypes.Underwater: case SectorTypes.OceanFloor: dist += 4; break; } if (dist >= max_distance) { break; } var dir = pexit.Direction; var exit = ch.CurrentRoom.GetExit(dir); if (exit == null) { break; } } ch.CurrentRoom.RemoveFrom(ch); was_in_room.AddTo(ch); return(null); }
public static void do_shove(CharacterInstance ch, string argument) { if (CheckFunctions.CheckIfTrue(ch, ch.IsNpc() || !((PlayerInstance)ch).PlayerData.Flags.IsSet(PCFlags.Deadly), "Only deadly characters can shove.")) { return; } if (CheckFunctions.CheckIfTrue(ch, ch.HasTimer(TimerTypes.PKilled), "You can't shove a player right now.")) { return; } var firstArg = argument.FirstWord(); if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Shove whom?")) { return; } var victim = ch.GetCharacterInRoom(firstArg); if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here.")) { return; } if (CheckFunctions.CheckIfEquivalent(ch, ch, victim, "You shove yourself around, to no avail.")) { return; } if (CheckFunctions.CheckIfTrue(ch, victim.IsNpc() || !((PlayerInstance)victim).PlayerData.Flags.IsSet(PCFlags.Deadly), "You can only shove deadly characters.")) { return; } if (CheckFunctions.CheckIfTrue(ch, ch.Level.GetAbsoluteDifference(victim.Level) > 5, "There is too great an experience difference for you to even bother.")) { return; } if (CheckFunctions.CheckIfNullObject(ch, victim.HasTimer(TimerTypes.PKilled), "You can't shove that player right now.")) { return; } if (victim.CurrentPosition != PositionTypes.Standing) { comm.act(ATTypes.AT_PLAIN, "$N isn't standing up.", ch, null, victim, ToTypes.Character); return; } var secondArg = argument.SecondWord(); if (CheckFunctions.CheckIfEmptyString(ch, secondArg, "Shove them in which direction?")) { return; } if (CheckFunctions.CheckIfTrue(ch, victim.CurrentRoom.Flags.IsSet(RoomFlags.Safe) && !ch.HasTimer(TimerTypes.ShoveDrag), "That character cannot be shoved right now.")) { return; } victim.CurrentPosition = PositionTypes.Shove; var exitDir = EnumerationExtensions.GetEnumByName <DirectionTypes>(secondArg); var exit = ch.CurrentRoom.GetExit(exitDir); if (CheckFunctions.CheckIfNullObject(ch, exit, "There's no exit in that direction.")) { victim.CurrentPosition = PositionTypes.Standing; return; } if (CheckFunctions.CheckIfTrue(ch, exit.Flags.IsSet(ExitFlags.Closed) && (!victim.IsAffected(AffectedByTypes.PassDoor) || exit.Flags.IsSet(ExitFlags.NoPassDoor)), "There's no exit in that direction.")) { victim.CurrentPosition = PositionTypes.Standing; return; } var toRoom = exit.GetDestination(); if (CheckFunctions.CheckIfSet(ch, toRoom.Flags, RoomFlags.Death, "You cannot shove someone into a death trap.")) { victim.CurrentPosition = PositionTypes.Standing; return; } if (CheckFunctions.CheckIfTrue(ch, ch.CurrentRoom.Area != toRoom.Area && !toRoom.Area.IsInHardRange(victim), "That character cannot enter that area.")) { victim.CurrentPosition = PositionTypes.Standing; return; } var chance = GetChanceByCharacterClass(ch); chance += (ch.GetCurrentStrength() - 15) * 3; chance += ch.Level - victim.Level; chance += GetBonusByCharacterRace(ch); if (CheckFunctions.CheckIfTrue(ch, chance < SmaugRandom.D100(), "You failed.")) { victim.CurrentPosition = PositionTypes.Standing; return; } comm.act(ATTypes.AT_ACTION, "You shove $M.", ch, null, victim, ToTypes.Character); comm.act(ATTypes.AT_ACTION, "$n shoves you.", ch, null, victim, ToTypes.Victim); Move.move_char(victim, exit, 0); if (!victim.CharDied()) { victim.CurrentPosition = PositionTypes.Standing; } Macros.WAIT_STATE(ch, 12); if (ch.CurrentRoom.Flags.IsSet(RoomFlags.Safe) && !ch.HasTimer(TimerTypes.ShoveDrag)) { ch.AddTimer(TimerTypes.ShoveDrag, 10); } }
public static bool Execute(CharacterInstance ch, IManager dbManager) { if (!ch.IsAwake()) { return(false); } var thrown = false; var noExit = true; var exit = ch.CurrentRoom.Exits.First(); if (exit != null) { noExit = false; } if (SmaugRandom.D100() <= 50) { return(false); } foreach (var obj in ch.CurrentRoom.Contents .Where(obj => obj.WearFlags.IsSet(ItemWearFlags.Take) && !obj.ExtraFlags.IsSet((int)ItemExtraFlags.Buried)) .Where(obj => obj.ItemType == ItemTypes.Weapon || obj.ItemType == ItemTypes.Armor || obj.ItemType == ItemTypes.Light)) { obj.Split(); comm.act(ATTypes.AT_ACTION, "$n leans over and gets $p.", ch, obj, null, ToTypes.Room); ch.CurrentRoom.RemoveFrom(obj); var trash = obj.AddTo(ch); if (ch.Level < trash.Level) { comm.act(ATTypes.AT_ACTION, "$n tries to use $p, but is too inexperienced.", ch, trash, null, ToTypes.Room); thrown = true; } if (!thrown) { ch.WearItem(trash, false, ItemWearFlags.None); } var found = false; if (!thrown) { foreach (var obj2 in ch.Carrying.Where(obj2 => obj2.WearLocation == WearLocations.None)) { Say.do_say(ch, "Hmm, I can't use this."); trash = obj2; thrown = true; } } if (thrown && !noExit) { while (!found) { var door = db.number_door(); exit = ch.CurrentRoom.GetExitNumber(door); var destRoom = exit?.GetDestination(RepositoryManager.Instance); if (destRoom == null || exit.Flags.IsSet(ExitFlags.Closed) || destRoom.Flags.IsSet(RoomFlags.NoDrop)) { continue; } if (destRoom.Persons.OfType <MobileInstance>().Any(x => x.SpecialFunctionName.EqualsIgnoreCase("spec_wanderer"))) { return(false); } found = true; } } if (noExit || !thrown) { return(true); } handler.set_cur_obj(trash); if (trash.CauseDamageTo() != ReturnTypes.ObjectScrapped) { ThrowScrapAtDirection(ch, trash, exit); } else { Say.do_say(ch, "This thing is junk!"); comm.act(ATTypes.AT_ACTION, "$n growls and breaks $p.", ch, trash, null, ToTypes.Room); } return(true); } return(false); }
/// stops infinite loops from the call to obj_to_room public static void obj_fall(ObjectInstance obj, bool through) { if (obj.InRoom == null || is_falling) { return; } if (fall_count > 30) { LogManager.Instance.Bug("Object falling in loop more than 30 times"); obj.Extract(); fall_count = 0; return; } if (obj.InRoom.Flags.IsSet((int)RoomFlags.NoFloor) && Macros.CAN_GO(obj, (int)DirectionTypes.Down) && !obj.ExtraFlags.IsSet((int)ItemExtraFlags.Magical)) { var exit = obj.InRoom.GetExit(DirectionTypes.Down); var to_room = exit.GetDestination(); if (through) { fall_count++; } else { fall_count = 0; } if (obj.InRoom == to_room) { LogManager.Instance.Bug("Object falling into same room {0}", to_room.ID); obj.Extract(); return; } if (obj.InRoom.Persons.Any()) { comm.act(ATTypes.AT_PLAIN, "$p falls far below...", obj.InRoom.Persons.First(), obj, null, ToTypes.Room); comm.act(ATTypes.AT_PLAIN, "$p falls far below...", obj.InRoom.Persons.First(), obj, null, ToTypes.Character); } obj.InRoom.RemoveFrom(obj); is_falling = true; to_room.AddTo(obj); is_falling = false; if (obj.InRoom.Persons.Any()) { comm.act(ATTypes.AT_PLAIN, "$p falls from above...", obj.InRoom.Persons.First(), obj, null, ToTypes.Room); comm.act(ATTypes.AT_PLAIN, "$p falls from above...", obj.InRoom.Persons.First(), obj, null, ToTypes.Character); } if (!obj.InRoom.Flags.IsSet((int)RoomFlags.NoFloor) && through) { var dam = fall_count * obj.Weight / 2; // Damage players in room if (obj.InRoom.Persons.Any() && SmaugRandom.D100() > 15) { foreach (var rch in obj.InRoom.Persons) { comm.act(ATTypes.AT_WHITE, "$p falls on $n!", rch, obj, null, ToTypes.Room); comm.act(ATTypes.AT_WHITE, "$p falls on you!", rch, obj, null, ToTypes.Character); if (rch.IsNpc() && rch.Act.IsSet((int)ActFlags.Hardhat)) { comm.act(ATTypes.AT_WHITE, "$p bounces harmlessly off your head!", rch, obj, null, ToTypes.Character); } else { rch.CauseDamageTo(rch, dam * rch.Level, -1); } } } // Damage the falling object switch (obj.ItemType) { case ItemTypes.Weapon: case ItemTypes.Armor: if (obj.Values.CurrentAC - dam <= 0) { if (obj.InRoom.Persons.Any()) { comm.act(ATTypes.AT_PLAIN, "$p is destroyed in the fall!", obj.InRoom.Persons.First(), obj, null, ToTypes.Room); comm.act(ATTypes.AT_PLAIN, "$p is destroyed in the fall!", obj.InRoom.Persons.First(), obj, null, ToTypes.Character); } ObjectFactory.CreateScraps(obj); } else { obj.Values.CurrentAC -= dam; } break; default: if (dam * 15 > obj.GetResistance()) { if (obj.InRoom.Persons.Any()) { comm.act(ATTypes.AT_PLAIN, "$p is destroyed in the fall!", obj.InRoom.Persons.First(), obj, null, ToTypes.Room); comm.act(ATTypes.AT_PLAIN, "$p is destroyed in the fall!", obj.InRoom.Persons.First(), obj, null, ToTypes.Character); } ObjectFactory.CreateScraps(obj); } break; } } } obj_fall(obj, true); }
public static void talk_channel(CharacterInstance ch, string argument, ChannelTypes channel, string verb) { #if !SCRAMBLE var speaking = -1; /*foreach (int key in GameConstants.LanguageTable.Keys * .Where(key => (key & ch.Speaking) > 0)) * { * speaking = key; * break; * }*/ #endif if (ch.IsNpc()) { var message = string.Empty; switch (channel) { case ChannelTypes.Clan: message = "Mobs can't be in clans.\r\n"; break; case ChannelTypes.Order: message = "Mobs can't be in orders.\r\n"; break; case ChannelTypes.Guild: message = "Mobs can't be in guilds.\r\n"; break; case ChannelTypes.Council: message = "Mobs can't be in councils.\r\n"; break; default: if (ch.IsAffected(AffectedByTypes.Charm)) { if (ch.Master != null) { ch.Master.SendTo("I don't think so..."); return; } } break; } if (!string.IsNullOrEmpty(message)) { ch.SendTo(message); return; } } if (!ch.IsPKill() && channel == ChannelTypes.WarTalk && !ch.IsImmortal()) { ch.SendTo("Peacefuls have no need to use wartalk."); return; } if (ch.CurrentRoom.Flags.IsSet(RoomFlags.Silence)) { ch.SendTo("You can't do that here."); return; } if (!ch.IsNpc() && ch.Act.IsSet((int)PlayerFlags.Silence)) { ch.Printf("You can't %s.\r\n", verb); return; } if (string.IsNullOrEmpty(argument)) { ch.SendTo($"{verb} what?\r\n".CapitalizeFirst()); return; } ch.Deaf.RemoveBit((int)channel); ch.SetColor(GetColorForChannelTalk(channel)); var buffer = string.Empty; switch (channel) { case ChannelTypes.RaceTalk: ch.Printf("You %s '%s'\r\n", verb, argument); buffer = $"$n {verb}s '$t'"; break; case ChannelTypes.Traffic: ch.Printf("You %s: %s\r\n", verb, argument); buffer = $"$n {verb}s: $t"; break; case ChannelTypes.WarTalk: ch.Printf("You %s '%s'\r\n", verb, argument); buffer = $"$n {verb}s '$t'"; break; case ChannelTypes.AvTalk: case ChannelTypes.ImmTalk: { var position = ch.CurrentPosition; comm.act(ATTypes.AT_IMMORT, $"$n{(channel == ChannelTypes.ImmTalk ? '>' : ':')} $t", ch, argument, null, ToTypes.Character); ch.CurrentPosition = position; } break; default: ch.Printf("You %s '%s'\r\n", verb, argument); buffer = $"$n {verb}s '$t'"; break; } if (ch.CurrentRoom.Flags.IsSet(RoomFlags.LogSpeech)) { db.append_to_file(SystemConstants.GetSystemFile(SystemFileTypes.Log), $"{(ch.IsNpc() ? ch.ShortDescription : ch.Name)}: {argument} ({verb})"); } foreach (var d in db.DESCRIPTORS) { var och = d.Original ?? d.Character; var vch = d.Character; if (d.ConnectionStatus == ConnectionTypes.Playing && vch != ch && !och.Deaf.IsSet((int)channel)) { var sbuf = argument; if (och.IsIgnoring(ch) && (ch.Trust <= och.Trust)) { continue; } if (channel != ChannelTypes.Newbie && och.IsNotAuthorized()) { continue; } if (channel == ChannelTypes.ImmTalk && !och.IsImmortal()) { continue; } if (channel == ChannelTypes.WarTalk && och.IsNotAuthorized()) { continue; } if (channel == ChannelTypes.AvTalk && !och.IsHero()) { continue; } if (channel == ChannelTypes.Highgod && och.Trust < GameManager.Instance.SystemData.GetMinimumLevel(PlayerPermissionTypes.MuseLevel)) { continue; } if (channel == ChannelTypes.High && och.Trust < GameManager.Instance.SystemData.GetMinimumLevel(PlayerPermissionTypes.ThinkLevel)) { continue; } if (channel == ChannelTypes.Traffic && !och.IsImmortal() && !ch.IsImmortal()) { if ((ch.IsHero() && !och.IsHero()) || (!ch.IsHero() && och.IsHero())) { continue; } } if (channel == ChannelTypes.Newbie && !och.IsImmortal() && !och.IsNotAuthorized() && !(och.PlayerData.Council != null && och.PlayerData.Council.Name.Equals("Newbie Council"))) { continue; } if (vch.CurrentRoom.Flags.IsSet((int)RoomFlags.Silence)) { continue; } if (channel == ChannelTypes.Yell && vch.CurrentRoom.Area != ch.CurrentRoom.Area) { continue; } if ((channel == ChannelTypes.Clan || channel == ChannelTypes.Order || channel == ChannelTypes.Guild) && (vch.IsNpc() || vch.PlayerData.Clan != ((PlayerInstance)ch).PlayerData.Clan)) { continue; } if (channel == ChannelTypes.Council && (vch.IsNpc() || vch.PlayerData.Council != ((PlayerInstance)ch).PlayerData.Council)) { continue; } if (channel == ChannelTypes.RaceTalk && vch.CurrentRace != ch.CurrentRace) { continue; } var lbuf = string.Empty; if (ch.Act.IsSet((int)PlayerFlags.WizardInvisibility) && vch.CanSee(ch) && vch.IsImmortal()) { lbuf = $"({(!ch.IsNpc() ? ((PlayerInstance)ch).PlayerData.WizardInvisible : ch.MobInvisible)})"; } var position = vch.CurrentPosition; if (channel != ChannelTypes.Shout && channel != ChannelTypes.Yell) { vch.CurrentPosition = PositionTypes.Standing; } #if !SCRAMBLE /*if (speaking != -1 && (!ch.IsNpc() || ch.Speaking > 0)) * { * int speakswell = vch.KnowsLanguage(ch.Speaking, ch).GetLowestOfTwoNumbers(ch.KnowsLanguage(ch.Speaking, vch)); * if (speakswell < 85) * sbuf = act_comm.TranslateLanguage(speakswell, argument, GameConstants.LanguageTable[speaking]); * }*/ #else if (KnowsLanguage(vch, ch.Speaking, ch) == 0 && (!ch.IsNpc() || ch.Speaking != 0)) { sbuf = ScrambleText(argument, ch.Speaking); } #endif if (!ch.IsNpc() && ((PlayerInstance)ch).PlayerData.Nuisance != null && ((PlayerInstance)ch).PlayerData.Nuisance.Flags > 7 && (SmaugRandom.D100() < (((PlayerInstance)ch).PlayerData.Nuisance.Flags - 7) * 10 * ((PlayerInstance)ch).PlayerData.Nuisance.Power)) { sbuf = argument.Scramble(SmaugRandom.Between(1, 10)); } if (!vch.IsNpc() && vch.PlayerData.Nuisance != null && vch.PlayerData.Nuisance.Flags > 7 && (SmaugRandom.D100() < (vch.PlayerData.Nuisance.Flags - 7) * 10 * vch.PlayerData.Nuisance.Power)) { sbuf = argument.Scramble(SmaugRandom.Between(1, 10)); } // TODO Toggle global mobtrigger flag lbuf = lbuf + buffer; switch (channel) { case ChannelTypes.ImmTalk: case ChannelTypes.AvTalk: comm.act(ATTypes.AT_IMMORT, lbuf, ch, sbuf, vch, ToTypes.Victim); break; case ChannelTypes.WarTalk: comm.act(ATTypes.AT_WARTALK, lbuf, ch, sbuf, vch, ToTypes.Victim); break; case ChannelTypes.RaceTalk: comm.act(ATTypes.AT_RACETALK, lbuf, ch, sbuf, vch, ToTypes.Victim); break; default: comm.act(ATTypes.AT_GOSSIP, lbuf, ch, sbuf, vch, ToTypes.Victim); break; } vch.CurrentPosition = position; } } }
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 bool chance_attrib(CharacterInstance ch, short percent, short attrib) { return(SmaugRandom.D100() - ch.GetCurrentLuck() + 13 - attrib + 13 + (ch.IsDevoted() ? ((PlayerInstance)ch).PlayerData.Favor / -500 : 0) <= percent); }
private static bool PotionWasFumbled(CharacterInstance ch) { return(SmaugRandom.D100() > ch.GetCurrentDexterity() * 2 + 48); }
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 void do_aid(CharacterInstance ch, string argument) { if (CheckFunctions.CheckIfTrue(ch, ch.IsNpc() && ch.IsAffected(AffectedByTypes.Charm), Resources.CANNOT_CONCENTRATE)) { return; } var arg = argument.FirstWord(); if (CheckFunctions.CheckIfEmptyString(ch, arg, Resources.AID_WHO)) { return; } var victim = ch.GetCharacterInRoom(arg); if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here.")) { return; } if (CheckFunctions.CheckIfNpc(ch, victim, "Not on mobs.")) { return; } if (CheckFunctions.CheckIfNotNullObject(ch, ch.CurrentMount, "You can't do that while mounted.")) { return; } if (CheckFunctions.CheckIfEquivalent(ch, ch, victim, "Aid yourself?")) { return; } if ((int)victim.CurrentPosition >= (int)PositionTypes.Stunned) { comm.act(ATTypes.AT_PLAIN, "$N doesn't need your help.", ch, null, victim, ToTypes.Character); return; } if (victim.CurrentHealth <= -6) { comm.act(ATTypes.AT_PLAIN, "$N's condition is beyond your aiding ability.", ch, null, victim, ToTypes.Character); return; } var percent = SmaugRandom.D100() - ch.GetCurrentLuck() - 13; var skill = RepositoryManager.Instance.GetEntity <SkillData>("aid"); if (skill == null) { throw new ObjectNotFoundException("Skill 'aid' was not found."); } Macros.WAIT_STATE(ch, skill.Rounds); if (!ch.CanUseSkill(percent, skill)) { ch.SendTo("You fail."); skill.LearnFromFailure((PlayerInstance)ch); return; } comm.act(ATTypes.AT_SKILL, "You aid $N!", ch, null, victim, ToTypes.Character); comm.act(ATTypes.AT_SKILL, "$n aids $N!", ch, null, victim, ToTypes.Room); skill.LearnFromSuccess((PlayerInstance)ch); ((PlayerInstance)ch).AdjustFavor(DeityFieldTypes.Aid, 1); if (victim.CurrentHealth < 1) { victim.CurrentHealth = 1; } victim.UpdatePositionByCurrentHealth(); comm.act(ATTypes.AT_SKILL, "$n aids you!", ch, null, victim, ToTypes.Victim); }
public static void char_update() { //lc = trworld_create(TR_CHAR_WORLD_BACK) foreach (var ch in RepositoryManager.Instance.CHARACTERS.Values) { handler.CurrentCharacter = ch; if (!ch.IsNpc()) { MudProgHandler.ExecuteRoomProg(MudProgTypes.Random, ch); } if (ch.CharDied()) { continue; } if (ch.IsNpc()) { MudProgHandler.ExecuteMobileProg(MudProgTypes.Time, ch); } if (ch.CharDied()) { continue; } MudProgHandler.ExecuteRoomProg(MudProgTypes.Time, ch); if (ch.CharDied()) { continue; } CharacterInstance ch_save = null; if (!ch.IsNpc() && (((PlayerInstance)ch).Descriptor == null || ((PlayerInstance)ch).Descriptor.ConnectionStatus == ConnectionTypes.Playing) && ch.Level >= 2 && CheckSaveFrequency(ch)) { ch_save = ch; } if ((int)ch.CurrentPosition >= (int)PositionTypes.Stunned) { if (ch.CurrentHealth < ch.MaximumHealth) { ch.CurrentHealth += ch.HealthGain(); } if (ch.CurrentMana < ch.MaximumMana) { ch.CurrentMana += ch.ManaGain(); } if (ch.CurrentMovement < ch.MaximumMovement) { ch.CurrentMovement += ch.MovementGain(); } } if (ch.CurrentPosition == PositionTypes.Stunned) { ch.UpdatePositionByCurrentHealth(); } // TODO Variables if (ch.CurrentMorph?.timer > 0) { --ch.CurrentMorph.timer; if (ch.CurrentMorph.timer == 0) { UnmorphChar.do_unmorph_char(ch, string.Empty); } } // TODO Nuisance if (!ch.IsNpc() && ch.Level < LevelConstants.ImmortalLevel) { var obj = ch.GetEquippedItem(WearLocations.Light); if (obj != null && obj.ItemType == ItemTypes.Light && obj.Value.ToList()[2] > 0) { ProcessLightObject(ch, obj); } if (++ch.Timer >= 12) { ProcessIdle(ch); } if (((PlayerInstance)ch).PlayerData.GetConditionValue(ConditionTypes.Drunk) > 8) { ((PlayerInstance)ch).WorsenMentalState(((PlayerInstance)ch).PlayerData.GetConditionValue(ConditionTypes.Drunk) / 8); } if (((PlayerInstance)ch).PlayerData.GetConditionValue(ConditionTypes.Full) > 1) { // todo fix this //IEnumerable<MentalStateAttribute> attribs = // ch.CurrentPosition.GetAttributes<MentalStateAttribute>(); //if (attribs.Any()) //{ // MentalStateAttribute attrib = // attribs.FirstOrDefault(x => x.Condition.HasFlag(ConditionTypes.Full)); // ch.ImproveMentalState(attrib == null ? 1 : attrib.ModValue); //} } if (((PlayerInstance)ch).PlayerData.GetConditionValue(ConditionTypes.Thirsty) > 1) { // todo fix this //IEnumerable<MentalStateAttribute> attribs = // ch.CurrentPosition.GetAttributes<MentalStateAttribute>(); //if (attribs.Any()) //{ // MentalStateAttribute attrib = // attribs.FirstOrDefault(x => x.Condition.HasFlag(ConditionTypes.Thirsty)); // ch.ImproveMentalState(attrib == null ? 1 : attrib.ModValue); //} } ch.CheckAlignment(); ((PlayerInstance)ch).GainCondition(ConditionTypes.Drunk, -1); var race = RepositoryManager.Instance.GetRace(ch.CurrentRace); ((PlayerInstance)ch).GainCondition(ConditionTypes.Full, -1 + race.HungerMod); if (ch.IsVampire() && ch.Level >= 10) { if (GameManager.Instance.GameTime.Hour < 21 && GameManager.Instance.GameTime.Hour >= 10) { ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, -1); } } if (ch.CanPKill() && ((PlayerInstance)ch).PlayerData.GetConditionValue(ConditionTypes.Thirsty) - 9 > 10) { ((PlayerInstance)ch).GainCondition(ConditionTypes.Thirsty, -9); } // TODO Nuisance } if (!ch.IsNpc() && !ch.IsImmortal() && ((PlayerInstance)ch).PlayerData.release_date > DateTime.MinValue && ((PlayerInstance)ch).PlayerData.release_date <= DateTime.Now) { var location = RepositoryManager.Instance.ROOMS.Get(((PlayerInstance)ch).PlayerData.Clan?.RecallRoom ?? VnumConstants.ROOM_VNUM_TEMPLE) ?? ch.CurrentRoom; ch.CurrentRoom.RemoveFrom(ch); location.AddTo(ch); ch.SendTo("The gods have released you from hell as your sentence is up!"); Look.do_look(ch, "auto"); ((PlayerInstance)ch).PlayerData.helled_by = string.Empty; ((PlayerInstance)ch).PlayerData.release_date = DateTime.MinValue; save.save_char_obj(ch); } if (!ch.CharDied()) { if (ch.IsAffected(AffectedByTypes.Poison)) { comm.act(ATTypes.AT_POISON, "$n shivers and suffers.", ch, null, null, ToTypes.Room); comm.act(ATTypes.AT_POISON, "You shiver and suffer.", ch, null, null, ToTypes.Character); var minMentalState = CalculateMinMentalStateWhilePoisoned(ch); ch.MentalState = 20.GetNumberThatIsBetween(minMentalState, 100); ch.CauseDamageTo(ch, 6, RepositoryManager.Instance.LookupSkill("poison")); } else { switch (ch.CurrentPosition) { case PositionTypes.Incapacitated: ch.CauseDamageTo(ch, 1, Program.TYPE_UNDEFINED); break; case PositionTypes.Mortal: ch.CauseDamageTo(ch, 4, Program.TYPE_UNDEFINED); break; } } if (ch.CharDied()) { continue; } if (ch.IsAffected(AffectedByTypes.RecurringSpell)) { var died = false; var found = false; foreach (var paf in ch.Affects.Where(x => x.Location == ApplyTypes.RecurringSpell)) { found = true; if (Macros.IS_VALID_SN(paf.Modifier)) { var skill = RepositoryManager.Instance.SKILLS.Get(paf.Modifier); if (skill == null || skill.Type != SkillTypes.Spell) { continue; } var retCode = skill.SpellFunction.Value.Invoke(paf.Modifier, ch.Level, ch, ch); if (retCode == ReturnTypes.CharacterDied || ch.CharDied()) { died = true; break; } } } if (died) { continue; } if (!found) { ch.AffectedBy.RemoveBit((int)AffectedByTypes.RecurringSpell); } } if (ch.MentalState >= 30) { var val = (ch.MentalState + 5) / 10; if (HighMentalStateTable.ContainsKey(val)) { ch.SendTo(HighMentalStateTable[val].Key); comm.act(ATTypes.AT_ACTION, HighMentalStateTable[val].Value, ch, null, null, ToTypes.Room); } } if (ch.MentalState <= -30) { var val = (Math.Abs(ch.MentalState) + 5) / 10; if (LowMentalStateTable.ContainsKey(val)) { if (val > 7) { if ((int)ch.CurrentPosition > (int)PositionTypes.Sleeping) { if ((ch.CurrentPosition == PositionTypes.Standing || (int)ch.CurrentPosition < (int)PositionTypes.Fighting) && (SmaugRandom.D100() + (100 - val * 10) + 10 < Math.Abs(ch.MentalState))) { Sleep.do_sleep(ch, string.Empty); } else { ch.SendTo(LowMentalStateTable[val]); } } } else { if ((int)ch.CurrentPosition > (int)PositionTypes.Resting) { ch.SendTo(LowMentalStateTable[val]); } } } } if (ch.Timer > 24) { Quit.do_quit(ch, string.Empty); } else if (ch == ch_save && GameManager.Instance.SystemData.SaveFlags.IsSet(AutoSaveFlags.Auto)) { save.save_char_obj(ch); } } } //trowlrd_dispose }
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); }