public static void RemoveFrom(this RoomTemplate room, CharacterInstance ch) { if (ch.CurrentRoom != room) { throw new RoomMismatchException("Character {0} is not in Room {1}", ch.Name, room.ID); } ch.Affects.ToList().ForEach(room.RemoveAffect); foreach (var affect in room.Affects.Where(af => (af.Location & ApplyTypes.IsNotRemovable) > 0)) { ch.RemoveAffect(affect); } room.Persons.Remove(ch); ch.PreviousRoom = room; ch.CurrentRoom = null; if (!ch.IsNpc() && ch.GetTimer(TimerTypes.ShoveDrag) != null) { ch.RemoveTimer(TimerTypes.ShoveDrag); } }
public static void AddTo(this RoomTemplate room, CharacterInstance ch, IRepositoryManager dbManager = null) { if (ch == null) { throw new ArgumentNullException(nameof(ch)); } var localRoom = room; var databaseMgr = dbManager ?? RepositoryManager.Instance; if (databaseMgr.ROOMS.CastAs <Repository <long, RoomTemplate> >().Get(room.ID) == null) { LogManager.Instance.Bug("{0} -> NULL room! Putting char in limbo ({1})", ch.Name, VnumConstants.ROOM_VNUM_LIMBO); localRoom = databaseMgr.ROOMS.CastAs <Repository <long, RoomTemplate> >().Get(VnumConstants.ROOM_VNUM_LIMBO); } ch.CurrentRoom = localRoom; if (ch.HomeVNum < 1) { ch.HomeVNum = localRoom.ID; } localRoom.Persons.Add(ch); if (!ch.IsNpc()) { if (localRoom.Area.NumberOfPlayers > localRoom.Area.MaximumPlayers) { localRoom.Area.MaximumPlayers = localRoom.Area.NumberOfPlayers; } } foreach (var affect in localRoom.Affects.Where(x => (x.Location & ApplyTypes.IsNotRemovable) > 0)) { ch.AddAffect(affect); } foreach (var affect in localRoom.PermanentAffects.Where(x => (x.Location & ApplyTypes.IsNotRemovable) > 0)) { ch.AddAffect(affect); } foreach (var affect in ch.Affects) { localRoom.AddAffect(affect); } if (!ch.IsNpc() && localRoom.Flags.IsSet(RoomFlags.Safe) && ch.GetTimer(TimerTypes.ShoveDrag) == null) { ch.AddTimer(TimerTypes.ShoveDrag, 10); } if (localRoom.Flags.IsSet(RoomFlags.Teleport) && localRoom.TeleportDelay > 0) { if (db.TELEPORT.Exists(x => x.Room == localRoom)) { return; } db.TELEPORT.Add(new TeleportData { Room = localRoom, Timer = (short)localRoom.TeleportDelay }); } if (ch.PreviousRoom == null) { ch.PreviousRoom = ch.CurrentRoom; } }
public static bool RemoveTimer(this CharacterInstance ch, TimerTypes type) { TimerData timer = ch.GetTimer(type); return(timer != null && ch.Timers.ToList().Remove(timer)); }
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 void interpret(CharacterInstance ch, string argument) { Validation.IsNotNull(ch, "ch"); if (ch.CurrentRoom == null) { throw new NullReferenceException("Null room reference"); } var logLine = string.Empty; CommandData foundCmd = null; if (((PlayerInstance)ch).SubState == CharacterSubStates.RepeatCommand) { var fun = ch.LastCommand; if (fun == null) { ((PlayerInstance)ch).SubState = CharacterSubStates.None; throw new InvalidDataException("CharacterSubStates.RepeatCommand with null LastCommand"); } foreach (var cmd in RepositoryManager.Instance.COMMANDS.Values) { if (cmd.DoFunction == fun) { foundCmd = cmd; break; } } if (foundCmd == null) { throw new InvalidDataException("CharacterSubStates.RepeatCommand: LastCommand was invalid"); } logLine = $"({foundCmd.Name}) {argument}"; } if (foundCmd == null) { // TODO } var lastPlayerCmd = $"{ch.Name} used {logLine}"; if (foundCmd != null && foundCmd.Log == LogAction.Never) { logLine = "XXXXXXXX XXXXXXXX XXXXXXXX"; } if (!ch.IsNpc() && ((PlayerInstance)ch).Descriptor != null && valid_watch(logLine)) { if (foundCmd != null && foundCmd.Flags.IsSet(CommandFlags.Watch)) { // TODO Write the watch } else if (((PlayerInstance)ch).PlayerData.Flags.IsSet(PCFlags.Watch)) { // TODO Write the watch } } // TODO Some more logging/snooping stuff var timer = ch.GetTimer(TimerTypes.DoFunction); if (timer != null) { var substate = ((PlayerInstance)ch).SubState; ((PlayerInstance)ch).SubState = CharacterSubStates.TimerDoAbort; timer.Action.Value.Invoke(ch, string.Empty); if (ch.CharDied()) { return; } if (((PlayerInstance)ch).SubState != CharacterSubStates.TimerDoAbort) { ((PlayerInstance)ch).SubState = substate; // TODO Extract timer } else { ((PlayerInstance)ch).SubState = substate; return; } } // TODO Look for command in skill/social table if (!check_pos(ch, foundCmd.Position)) { return; } var buf = check_cmd_flags(ch, foundCmd); if (!buf.IsNullOrEmpty()) { ch.SendTo(buf); return; } // TODO Nuisance ch.PreviousCommand = ch.LastCommand; ch.LastCommand = foundCmd.DoFunction; // TODO Timer // tail_chain(); }
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 get_obj(CharacterInstance ch, ObjectInstance obj, ObjectInstance container) { if (CheckFunctions.CheckIfTrue(ch, !obj.WearFlags.IsSet(ItemWearFlags.Take) && (ch.Level < GameManager.Instance.SystemData.GetMinimumLevel(PlayerPermissionTypes.LevelGetObjectNoTake)), "You can't take that.")) { return; } if (obj.MagicFlags.IsSet(ItemMagicFlags.PKDisarmed) && !ch.IsNpc()) { var timer = ch.GetTimer(TimerTypes.PKilled); if (ch.CanPKill() && timer == null) { if (ch.Level - obj.Value.ToList()[5] > 5 || obj.Value.ToList()[5] - ch.Level > 5) { ch.SendTo("\r\n&bA godly force freezes your outstretched hand."); return; } obj.MagicFlags.RemoveBit(ItemMagicFlags.PKDisarmed); obj.Value.ToList()[5] = 0; } } else { ch.SendTo("\r\n&BA godly force freezes your outstretched hand."); return; } if (CheckFunctions.CheckIfTrue(ch, obj.ExtraFlags.IsSet((int)ItemExtraFlags.Prototype) && !ch.CanTakePrototype(), "A godly force prevents you from getting close to it.")) { return; } if (ch.CarryNumber + obj.ObjectNumber > ch.CanCarryN()) { comm.act(ATTypes.AT_PLAIN, "$d: you can't carry that many items.", ch, null, obj.ShortDescription, ToTypes.Character); return; } var weight = obj.ExtraFlags.IsSet((int)ItemExtraFlags.Covering) ? obj.Weight : obj.GetWeight(); if (obj.ItemType != ItemTypes.Money) { if (obj.InObject != null) { var tObject = obj.InObject; var inobj = 1; var checkweight = tObject.ItemType == ItemTypes.Container && tObject.ExtraFlags.IsSet((int)ItemExtraFlags.Magical); while (tObject.InObject != null) { tObject = tObject.InObject; inobj++; checkweight = tObject.ItemType == ItemTypes.Container && tObject.ExtraFlags.IsSet((int)ItemExtraFlags.Magical); } if (tObject.CarriedBy == null || tObject.CarriedBy != ch || checkweight) { if (ch.CarryWeight + weight > ch.CanCarryMaxWeight()) { comm.act(ATTypes.AT_PLAIN, "$d: you can't carry that much weight.", ch, null, obj.ShortDescription, ToTypes.Character); return; } } } else if (ch.CarryWeight + weight > ch.CanCarryMaxWeight()) { comm.act(ATTypes.AT_PLAIN, "$d: you can't carry that much weight.", ch, null, obj.ShortDescription, ToTypes.Character); return; } } if (container != null) { GetObjectFromContainer(ch, obj, container); } else { GetObjectFromRoom(ch, obj); } if (ch.CurrentRoom.Flags.IsSet(RoomFlags.ClanStoreroom) && (container?.CarriedBy == null)) { foreach (var clan in RepositoryManager.Instance.CLANS.Values) { if (clan.StoreRoom == ch.CurrentRoom.ID) { save_clan_storeroom(ch, clan); } } } if (obj.ItemType != ItemTypes.Container) { ch.CheckObjectForTrap(obj, TrapTriggerTypes.Get); } if (ch.CharDied()) { return; } if (obj.ItemType == ItemTypes.Money) { int amt = obj.Values.NumberOfCoins * obj.Count; ch.CurrentCoin += amt; obj.Extract(); } else { obj = obj.AddTo(ch); } if (ch.CharDied() || handler.obj_extracted(obj)) { return; } MudProgHandler.ExecuteObjectProg(MudProgTypes.Get, ch, obj); }
public static bool IsSafe(this CharacterInstance ch, CharacterInstance victim, bool showMessage) { if (victim == null) { return(true); } if (victim.CurrentRoom == null) { return(true); } if (victim.CharDied() || ch.CharDied()) { return(true); } if (ch.CurrentFighting.Who == ch) { return(false); } if (victim.CurrentRoom.Flags.IsSet((int)RoomFlags.Safe)) { if (showMessage) { ch.SetColor(ATTypes.AT_MAGIC); ch.SendTo("A magical force prevents you from attackking."); } return(true); } if (ch.IsPacifist()) { if (showMessage) { ch.SetColor(ATTypes.AT_MAGIC); ch.SendTo("You are a pacifist and will not fight."); } return(true); } if (victim.IsPacifist()) { if (showMessage) { ch.SetColor(ATTypes.AT_MAGIC); ch.SendTo($"{victim.ShortDescription.CapitalizeFirst()} is a pacifist and will not fight."); } return(true); } if (!ch.IsNpc() && ch.IsImmortal()) { return(false); } if (!ch.IsNpc() && !victim.IsNpc() && ch != victim && victim.CurrentRoom.Area.Flags.IsSet(AreaFlags.NoPlayerVsPlayer)) { if (showMessage) { ch.SetColor(ATTypes.AT_IMMORT); ch.SendTo("The gods have forbidden player killing in this area."); } return(true); } if (ch.IsNpc() || victim.IsNpc()) { return(false); } // TODO age (fight.c lines 2507 to 2525) if (ch.Level - victim.Level > 5 | victim.Level - ch.Level > 5) { if (showMessage) { ch.SetColor(ATTypes.AT_IMMORT); ch.SendTo("The gods do not allow murder when there is such a difference in level."); } return(true); } if (victim.GetTimer(TimerTypes.PKilled) != null) { if (showMessage) { ch.SetColor(ATTypes.AT_GREEN); ch.SendTo("That character has died within the last 5 minutes."); } return(true); } if (ch.GetTimer(TimerTypes.PKilled) != null) { if (showMessage) { ch.SetColor(ATTypes.AT_GREEN); ch.SendTo("You have been killed within the last 5 minutes."); } return(true); } return(false); }