예제 #1
0
        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);
            }
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        public static bool RemoveTimer(this CharacterInstance ch, TimerTypes type)
        {
            TimerData timer = ch.GetTimer(type);

            return(timer != null && ch.Timers.ToList().Remove(timer));
        }
예제 #4
0
        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);
        }
예제 #5
0
        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();
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }