Пример #1
0
        public static void do_consider(CharacterInstance ch, string argument)
        {
            var arg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, arg, "Consider killing whom?"))
            {
                return;
            }

            var victim = ch.GetCharacterInRoom(arg);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "They're not here."))
            {
                return;
            }
            if (CheckFunctions.CheckIfEquivalent(ch, ch, victim,
                                                 "You decide you're pretty sure you could take yourself in a fight."))
            {
                return;
            }

            var levelDiff = victim.Level - ch.Level;

            var msg = GetLevelConsiderMessage(levelDiff);

            comm.act(ATTypes.AT_CONSIDER, msg, ch, null, victim, ToTypes.Character);

            levelDiff = (victim.MaximumHealth - ch.MaximumHealth) / 6;
            msg       = GetHealthConsiderMessage(levelDiff);
            comm.act(ATTypes.AT_CONSIDER, msg, ch, null, victim, ToTypes.Character);
        }
Пример #2
0
        public static void do_dismiss(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Dismiss whom?"))
            {
                return;
            }

            var victim = ch.GetCharacterInRoom(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here."))
            {
                return;
            }

            if (victim.IsAffected(AffectedByTypes.Charm) &&
                victim.IsNpc() && victim.Master == ch)
            {
                victim.StopFollower();
                ((MobileInstance)victim).StopHating();
                ((MobileInstance)victim).StopHunting();
                ((MobileInstance)victim).StopFearing();
                comm.act(ATTypes.AT_ACTION, "$n dismisses $N.", ch, null, victim, ToTypes.NotVictim);
                comm.act(ATTypes.AT_ACTION, "You dismiss $N.", ch, null, victim, ToTypes.Character);
                return;
            }

            ch.SendTo("You cannot dismiss them.");
        }
Пример #3
0
        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);
        }
Пример #4
0
        public static void do_follow(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Follow whom?"))
            {
                return;
            }


            var victim = ch.GetCharacterInRoom(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here."))
            {
                return;
            }

            if (ch.IsAffected(AffectedByTypes.Charm) && ch.Master != null)
            {
                comm.act(ATTypes.AT_PLAIN, "But you'd rather follow $N!", ch, null, ch.Master, ToTypes.Character);
                return;
            }

            if (victim == ch)
            {
                if (CheckFunctions.CheckIfNullObject(ch, ch.Master, "You already follow yourself."))
                {
                    return;
                }

                ch.StopFollower();
                return;
            }

            if ((ch.Level - victim.Level < -10 ||
                 ch.Level - victim.Level > 10) &&
                !ch.IsHero() && !(ch.Level < 15 && !victim.IsNpc() &&
                                  ((PlayerInstance)victim).PlayerData.Council != null &&
                                  !((PlayerInstance)victim).PlayerData.Council.Name.Equals("Newbie Council")))
            {
                ch.SendTo("You are not of the right caliber to follow.");
                return;
            }

            if (CheckFunctions.CheckIfTrue(ch, ch.IsCircleFollowing(victim),
                                           "Following in loops is not allowed... sorry."))
            {
                return;
            }

            if (ch.Master != null)
            {
                ch.StopFollower();
            }

            ch.AddFollower(victim);
        }
Пример #5
0
        private static void group_player(CharacterInstance ch, string argument)
        {
            var victim = ch.GetCharacterInRoom(argument);

            if (victim == null)
            {
                ch.SendTo("They aren't here.");
                return;
            }

            if (ch.Master != null || (ch.Leader != null && ch.Leader != ch))
            {
                ch.SendTo("But you are following someone else!");
                return;
            }

            if (victim.Master != ch && ch != victim)
            {
                comm.act(ATTypes.AT_PLAIN, "$N isn't following you.", ch, null, victim, ToTypes.Character);
                return;
            }

            if (victim == ch)
            {
                comm.act(ATTypes.AT_PLAIN, "You can't group yourself.", ch, null, victim, ToTypes.Character);
                return;
            }

            if (victim.IsSameGroup(ch) && ch != victim)
            {
                victim.Leader = null;
                comm.act(ATTypes.AT_ACTION, "$n removes $N from $s group.", ch, null, victim, ToTypes.NotVictim);
                comm.act(ATTypes.AT_ACTION, "$n removes you from $s group.", ch, null, victim, ToTypes.Victim);
                comm.act(ATTypes.AT_ACTION, "You remove $N from your group.", ch, null, victim, ToTypes.Character);
                return;
            }

            if (ch.Level - victim.Level < -8 ||
                ch.Level - victim.Level > 8 ||
                (ch.IsPKill() != victim.IsPKill()))
            {
                comm.act(ATTypes.AT_PLAIN, "$N cannot join $n's group.", ch, null, victim, ToTypes.NotVictim);
                comm.act(ATTypes.AT_PLAIN, "You cannot join $n's group.", ch, null, victim, ToTypes.Victim);
                comm.act(ATTypes.AT_PLAIN, "$N cannot join your group.", ch, null, victim, ToTypes.Character);
                return;
            }

            victim.Leader = ch;
            comm.act(ATTypes.AT_ACTION, "$N oins $n's group.", ch, null, victim, ToTypes.NotVictim);
            comm.act(ATTypes.AT_ACTION, "You join $n's group.", ch, null, victim, ToTypes.Victim);
            comm.act(ATTypes.AT_ACTION, "$N joins your group.", ch, null, victim, ToTypes.Character);
        }
Пример #6
0
        public static void do_kill(CharacterInstance ch, string argument)
        {
            if (CheckFunctions.CheckIfEmptyString(ch, argument, "Kill whom?"))
            {
                return;
            }

            var firstArg = argument.FirstWord();
            var victim   = ch.GetCharacterInRoom(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here."))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, victim.IsNpc() && victim.CurrentMorph != null,
                                           "This creature appears strange to you. Look upon it more closely before attempting to kill it."))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, !victim.IsNpc() && !victim.Act.IsSet((int)PlayerFlags.Killer) &&
                                           !victim.Act.IsSet((int)PlayerFlags.Thief), "You must MURDER a player."))
            {
                return;
            }
            if (CheckFunctions.CheckIfEquivalent(ch, ch, victim, "You hit yourself.  Ouch!"))
            {
                fight.multi_hit(ch, ch, Program.TYPE_UNDEFINED);
                return;
            }
            if (fight.is_safe(ch, victim, true))
            {
                return;
            }

            if (ch.IsAffected(AffectedByTypes.Charm) && ch.Master == victim)
            {
                comm.act(ATTypes.AT_PLAIN, "$N is your beloved master.", ch, null, victim, ToTypes.Character);
                return;
            }

            if (CheckFunctions.CheckIfTrue(ch, ch.IsInCombatPosition(), "You do the best you can!"))
            {
                return;
            }

            Macros.WAIT_STATE(ch, 1 * GameConstants.GetSystemValue <int>("PulseViolence"));
            ch.CheckAttackForAttackerFlag(victim);
            fight.multi_hit(ch, victim, Program.TYPE_UNDEFINED);
        }
Пример #7
0
        public static void do_glance(CharacterInstance ch, string argument)
        {
            if (CheckFunctions.CheckIfNullObject(ch, ((PlayerInstance)ch).Descriptor))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, (int)ch.CurrentPosition < (int)PositionTypes.Sleeping,
                                           "You can't see anything but stars!"))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, ch.CurrentPosition == PositionTypes.Sleeping,
                                           "You can't see anything, you're sleeping!"))
            {
                return;
            }
            if (CheckFunctions.CheckIfBlind(ch, "You can't see a thing!"))
            {
                return;
            }

            ch.SetColor(ATTypes.AT_ACTION);

            var firstWord = argument.FirstWord();

            if (string.IsNullOrEmpty(firstWord))
            {
                GlanceAtRoom(ch);
                return;
            }

            var victim = ch.GetCharacterInRoom(firstWord);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "They're not here."))
            {
                return;
            }

            if (victim.CanSee(ch))
            {
                comm.act(ATTypes.AT_ACTION, "$n glances at you.", ch, null, victim, ToTypes.Victim);
                comm.act(ATTypes.AT_ACTION, "$n glances at $N.", ch, null, victim, ToTypes.NotVictim);
            }

            if (ch.IsImmortal() && victim != ch)
            {
                GlanceFromImmortal(ch, victim);
            }
        }
Пример #8
0
        public static void do_mpapply(CharacterInstance ch, string argument)
        {
            if (CheckFunctions.CheckIfTrue(ch,
                                           !ch.IsNpc() || ((PlayerInstance)ch).Descriptor != null || ch.IsAffected(AffectedByTypes.Charm), "Huh?"))
            {
                return;
            }

            if (CheckFunctions.CheckIfEmptyString(ch, argument, "Mpapply - bad syntax"))
            {
                return;
            }

            var victim = ch.GetCharacterInRoom(argument);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "Mpapply - no such player in room."))
            {
                return;
            }

            if (CheckFunctions.CheckIfNullObject(ch, !victim.IsNpc() && ((PlayerInstance)victim).Descriptor != null, "Not on link-dead players"))
            {
                return;
            }

            if (!victim.IsNotAuthorized())
            {
                return;
            }
            if (!victim.IsNpc() && ((PlayerInstance)victim).PlayerData.AuthState != AuthorizationStates.None)
            {
                return;
            }

            var buf =
                $"{victim.Name}@{(victim.IsNpc() ? string.Empty : ((PlayerInstance)victim).Descriptor.host)} new {victim.CurrentRace.GetName()} {victim.CurrentClass.GetName()} {(victim.IsPKill() ? "(Deadly)" : "(Peaceful)")} applying...";

            ChatManager.to_channel(buf, ChannelTypes.Auth, "Auth", LevelConstants.ImmortalLevel);
            if (!victim.IsNpc())
            {
                ((PlayerInstance)victim).PlayerData.AuthState = AuthorizationStates.None;
            }
        }
Пример #9
0
        public static void do_wake(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (string.IsNullOrEmpty(firstArg))
            {
                interp.interpret(ch, "stand");
                interp.interpret(ch, "look auto");
                return;
            }

            if (CheckFunctions.CheckIfTrue(ch, !ch.IsAwake(), "You are asleep yourself!"))
            {
                return;
            }

            var victim = ch.GetCharacterInRoom(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here."))
            {
                return;
            }

            if (victim.IsAwake())
            {
                comm.act(ATTypes.AT_PLAIN, "$N is already awake.", ch, null, victim, ToTypes.Character);
                return;
            }

            if (victim.IsAffected(AffectedByTypes.Sleep) || (int)victim.CurrentPosition < (int)PositionTypes.Sleeping)
            {
                comm.act(ATTypes.AT_PLAIN, "You can't seem to wake $M!", ch, null, victim, ToTypes.Character);
                return;
            }

            comm.act(ATTypes.AT_ACTION, "You wake $M.", ch, null, victim, ToTypes.Character);
            victim.CurrentPosition = PositionTypes.Standing;
            comm.act(ATTypes.AT_ACTION, "$n wakes you.", ch, null, victim, ToTypes.Victim);
            interp.interpret(victim, "look auto");
        }
Пример #10
0
        public static void do_slay(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Slay whom?"))
            {
                return;
            }

            var victim = ch.GetCharacterInRoom(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here."))
            {
                return;
            }
            if (CheckFunctions.CheckIfEquivalent(ch, ch, victim, "Suicide is a mortal sin."))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, !victim.IsNpc() && victim.Trust >= ch.Trust, "You failed."))
            {
                return;
            }

            var secondArg = argument.SecondWord();

            if (SlayTable.ContainsKey(secondArg.ToLower()))
            {
                SlayTable[secondArg.ToLower()].Invoke(ch, victim);
            }
            else
            {
                Default(ch, victim);
            }

            handler.set_cur_char(victim);
            ch.RawKill(victim);
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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);
        }
Пример #13
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);
        }
Пример #14
0
        public static void do_murder(CharacterInstance ch, string argument)
        {
            if (CheckFunctions.CheckIfEmptyString(ch, argument, "Murder whom?"))
            {
                return;
            }

            var firstArg = argument.FirstWord();
            var victim   = ch.GetCharacterInRoom(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here."))
            {
                return;
            }
            if (CheckFunctions.CheckIfEquivalent(ch, ch, victim, "Suicide is a mortal sin."))
            {
                return;
            }

            if (fight.is_safe(ch, victim, true))
            {
                return;
            }

            if (ch.IsAffected(AffectedByTypes.Charm))
            {
                if (ch.Master == victim)
                {
                    comm.act(ATTypes.AT_PLAIN, "$N is your beloeved master.", ch, null, victim, ToTypes.Character);
                    return;
                }

                ch.Master?.Act.SetBit((int)PlayerFlags.Attacker);
            }

            if (CheckFunctions.CheckIfTrue(ch, ch.IsInCombatPosition(), "You do the best you can!"))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, !victim.IsNpc() && ch.Act.IsSet((int)PlayerFlags.Nice),
                                           "You feel too nice to do that!"))
            {
                return;
            }

            // TODO Log the murder

            Macros.WAIT_STATE(ch, 1 & GameConstants.GetSystemValue <int>("PulseViolence"));

            var buf = $"Help!  I am being attacked by {(ch.IsNpc() ? ch.ShortDescription : ch.Name)}!";

            if (victim.IsPKill())
            {
                Wartalk.do_wartalk(victim, buf);
            }
            else
            {
                Yell.do_yell(victim, buf);
            }

            fight.check_illegal_pk(ch, victim);
            ch.CheckAttackForAttackerFlag(victim);
            fight.multi_hit(ch, victim, Program.TYPE_UNDEFINED);
        }
Пример #15
0
        public static void do_whisper(CharacterInstance ch, string argument)
        {
#if !SCRAMBLE
            var speaking = -1;

            /*foreach (int key in GameConstants.LanguageTable.Keys
             *                           .Where(key => (key & ch.Speaking) > 0))
             * {
             *  speaking = key;
             *  break;
             * }*/
#endif

            ch.Deaf.RemoveBit((int)ChannelTypes.Whisper);
            var firstArgument  = argument.FirstWord();
            var argumentString = argument.RemoveWord(1);
            if (string.IsNullOrWhiteSpace(argumentString))
            {
                ch.SendTo("Whisper to whom what?");
                return;
            }

            var victim = ch.GetCharacterInRoom(firstArgument);
            if (victim == null)
            {
                ch.SendTo("They aren't here.");
                return;
            }

            if (ch == victim)
            {
                ch.SendTo("You have a nice little chat with yourself.");
                return;
            }

            if (!victim.IsNpc() && victim.Switched != null &&
                !victim.Switched.IsAffected(AffectedByTypes.Possess))
            {
                ch.SendTo("That player is switched.");
                return;
            }

            if (!victim.IsNpc() && ((PlayerInstance)victim).Descriptor == null)
            {
                ch.SendTo("That player is link-dead.");
                return;
            }

            if (!victim.IsNpc() && victim.Act.IsSet((int)PlayerFlags.AwayFromKeyboard))
            {
                ch.SendTo("That player is afk.");
                return;
            }

            if (victim.Deaf.IsSet(ChannelTypes.Whisper) &&
                (!ch.IsImmortal() || (ch.Trust < victim.Trust)))
            {
                comm.act(ATTypes.AT_PLAIN, "$E has $S whispers turned off.", ch, null, victim,
                         ToTypes.Character);
                return;
            }

            if (!victim.IsNpc() && victim.Act.IsSet((int)PlayerFlags.Silence))
            {
                ch.SendTo("That player is silenced.  They will receive your message but cannot respond.");
            }

            if (((PlayerInstance)victim).Descriptor != null &&
                (((PlayerInstance)victim).Descriptor.ConnectionStatus == ConnectionTypes.Editing) &&
                (ch.Trust < LevelConstants.GetLevel(ImmortalTypes.God)))
            {
                comm.act(ATTypes.AT_PLAIN, "$E is currently in a writing buffer.  Please try again in a few minutes.",
                         ch, 0, victim, ToTypes.Character);
                return;
            }

            if (victim.IsIgnoring(ch))
            {
                if (!ch.IsImmortal() || victim.Trust > ch.Trust)
                {
                    ch.SetColor(ATTypes.AT_IGNORE);
                    ch.Printf("%s is ignoring you.\r\n", victim.Name);
                    return;
                }

                victim.SetColor(ATTypes.AT_IGNORE);
                victim.Printf("You attempt to ignore %s, but are unable to do so.\r\n", ch.Name);
            }

            comm.act(ATTypes.AT_WHISPER, "You whisper to $N '$t'", ch, argumentString, victim, ToTypes.Character);
            var position = victim.CurrentPosition;
            victim.CurrentPosition = PositionTypes.Standing;

#if !SCRAMBLE
            /* if (speaking != -1 && (!ch.IsNpc() || ch.Speaking > 0))
             * {
             *   int speakswell = victim.KnowsLanguage(ch.Speaking, ch).GetLowestOfTwoNumbers(ch.KnowsLanguage(ch.Speaking, victim));
             *   if (speakswell < 85)
             *       comm.act(ATTypes.AT_WHISPER, "$n whispers to you '$t'",
             *                ch, act_comm.TranslateLanguage(speakswell, argumentString,
             *                              GameConstants.LanguageTable[speaking]), victim, ToTypes.Victim);
             *   else
             *       comm.act(ATTypes.AT_WHISPER, "$n whispers to you '$t'",
             *                ch, argumentString, victim, ToTypes.Victim);
             * }
             * else
             *   comm.act(ATTypes.AT_WHISPER, "$n whispers to you '$t'", ch, argument, victim, ToTypes.Victim);*/
#else
            int speakswell = SmaugCS.Common.Check.Minimum(KnowsLanguage(victim, ch.Speaking, ch),
                                                          KnowsLanguage(ch, ch.Speaking, victim));

            if (act_comm.KnowsLanguage(victim, ch.Speaking, ch) == 0 &&
                (!ch.IsNpc() || ch.Speaking != 0))
            {
                comm.act(ATTypes.AT_WHISPER, "$n whispers to you '$t'", ch,
                         TranslateLanguage(speakswell, argument, GameConstants.LanguageTable[speaking]),
                         victim, ToTypes.Victim);
            }
            else
            {
                comm.act(ATTypes.AT_WHISPER, "$n whispers something to $N.",
                         ch, argument, victim, ToTypes.NotVictim);
            }
#endif

            if (!ch.CurrentRoom.Flags.IsSet((int)RoomFlags.LogSpeech))
            {
                db.append_to_file(SystemConstants.GetSystemFile(SystemFileTypes.Log),
                                  $"{(ch.IsNpc() ? ch.ShortDescription : ch.Name)}: {argument} (whisper to) {(victim.IsNpc() ? victim.ShortDescription : victim.Name)}");
            }

            MudProgHandler.ExecuteMobileProg(MudProgTypes.Tell, argument, ch);
        }
Пример #16
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);
        }
Пример #17
0
        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);
        }
Пример #18
0
        public static void do_order(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Order whom to do what?"))
            {
                return;
            }

            if (CheckFunctions.CheckIfTrue(ch, ch.IsAffected(AffectedByTypes.Charm),
                                           "You feel like taking, not giving, orders."))
            {
                return;
            }

            if (CheckFunctions.CheckIfTrue(ch, firstArg.EqualsIgnoreCase("mp"), "No... I don't think so."))
            {
                return;
            }

            var all = false;
            CharacterInstance victim = null;

            var secondArg = argument.SecondWord();

            if (secondArg.EqualsIgnoreCase("all"))
            {
                all = true;
            }
            else
            {
                victim = ch.GetCharacterInRoom(secondArg);
                if (CheckFunctions.CheckIfNullObject(ch, victim, "They aren't here."))
                {
                    return;
                }
                if (CheckFunctions.CheckIfEquivalent(ch, ch, victim, "Aye aye, right away!"))
                {
                    return;
                }
                if (CheckFunctions.CheckIfTrue(ch, !victim.IsAffected(AffectedByTypes.Charm) || victim.Master != ch,
                                               "Do it yourself!"))
                {
                    return;
                }
            }

            var found = false;

            foreach (var och in ch.CurrentRoom.Persons
                     .Where(och => och.IsAffected(AffectedByTypes.Charm) &&
                            och.Master == ch && (all || och == victim)))
            {
                found = true;
                comm.act(ATTypes.AT_ACTION, "$n orders you to '$t'", ch, firstArg, och, ToTypes.Victim);
                interp.interpret(och, firstArg);
            }

            if (CheckFunctions.CheckIfTrue(ch, !found, "You have no followers here."))
            {
                return;
            }

            LogManager.Instance.Info("{0}: order {1}.", ch.Name, string.Format(argument, (int)LogTypes.Info, ch.Level));
            ch.SendTo("Ok.");
            Macros.WAIT_STATE(ch, 12);
        }
Пример #19
0
        public static void do_advance(CharacterInstance ch, string argument)
        {
            ch.SetColor(ATTypes.AT_IMMORT);

            string firstArg  = argument.FirstWord();
            string secondArg = argument.SecondWord();

            if (CheckFunctions.CheckIf(ch,
                                       () => string.IsNullOrEmpty(firstArg) || string.IsNullOrEmpty(secondArg) || !secondArg.IsNumeric(),
                                       "Syntax:  advance <character> <Level>"))
            {
                return;
            }

            var victim = ch.GetCharacterInRoom(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, victim, "That character is not in the room."))
            {
                return;
            }
            if (CheckFunctions.CheckIfNpc(ch, victim, "You cannot advance a non-player-character."))
            {
                return;
            }
            if (CheckFunctions.CheckIf(ch, () => ch.Trust <= victim.Trust || ch == victim, "You can't do that."))
            {
                return;
            }

            var level = Convert.ToInt32(secondArg);

            if (CheckFunctions.CheckIf(ch, () => level < 1 || level > GameConstants.GetConstant <int>("MaximumLevel"),
                                       $"Level range is 1 to {GameConstants.GetConstant<int>("MaximumLevel")}."))
            {
                return;
            }
            if (CheckFunctions.CheckIf(ch, () => level > ch.Trust, "Level limited to your trust level."))
            {
                return;
            }

            if (level <= victim.Level)
            {
                LowerVictimLevel(ch, victim, level);
            }
            else
            {
                RaiseVictimLevel(ch, victim, level);
            }

            for (int i = victim.Level; i < level; i++)
            {
                if (level < LevelConstants.ImmortalLevel)
                {
                    victim.SendTo("You raise a level!");
                }
                victim.Level += 1;
                if (victim is PlayerInstance)
                {
                    ((PlayerInstance)victim).AdvanceLevel();
                }
            }

            victim.Experience = victim.GetExperienceLevel(victim.Level);
            victim.Trust      = 0;
        }
Пример #20
0
        public static void do_apply(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Apply what?"))
            {
                return;
            }

            var secondArg = argument.SecondWord();

            if (CheckFunctions.CheckIfNotNullObject(ch, ch.CurrentFighting, "You're too busy fighting..."))
            {
                return;
            }
            if (handler.FindObject_CheckMentalState(ch))
            {
                return;
            }

            var salve = ch.GetCarriedObject(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, salve, "You do not have that."))
            {
                return;
            }

            CharacterInstance victim;
            ObjectInstance    obj = null;

            if (string.IsNullOrEmpty(secondArg))
            {
                victim = ch;
            }
            else
            {
                victim = ch.GetCharacterInRoom(secondArg);
                obj    = ch.GetObjectOnMeOrInRoom(secondArg);

                if (CheckFunctions.CheckIfTrue(ch, victim == null && obj == null, "Apply it to what or whom?"))
                {
                    return;
                }
            }

            if (CheckFunctions.CheckIfNotNullObject(ch, obj, "You can't do that... yet."))
            {
                return;
            }
            if (CheckFunctions.CheckIfNotNullObject(ch, victim.CurrentFighting,
                                                    "Wouldn't work very well while they're fighting..."))
            {
                return;
            }

            if (salve.ItemType != ItemTypes.Salve)
            {
                ApplyNonSalve(salve, ch, victim);
                return;
            }

            salve.Split();
            salve.Values.Charges -= 1;

            if (!MudProgHandler.ExecuteObjectProg(MudProgTypes.Use, ch, salve, null, null))
            {
                UseSalve(salve, ch, victim);
            }

            Macros.WAIT_STATE(ch, salve.Values.Delay);
            var retcode = ch.ObjectCastSpell((int)salve.Values.Skill1ID, (int)salve.Values.SpellLevel, victim);

            if (retcode == ReturnTypes.None)
            {
                retcode = ch.ObjectCastSpell((int)salve.Values.Skill2ID, (int)salve.Values.SpellLevel, victim);
            }
            if (retcode == ReturnTypes.CharacterDied || retcode == ReturnTypes.BothDied)
            {
                throw new CharacterDiedException("Salve {0}, Actor {1}, Victim {2}", salve.ID, ch.ID, victim.ID);
            }

            if (!handler.obj_extracted(salve) && salve.Values.Charges <= 0)
            {
                salve.Extract();
            }
        }
Пример #21
0
        public static ReturnTypes ranged_attack(CharacterInstance ch, string argument, ObjectInstance weapon,
                                                ObjectInstance projectile, int sn, int range)
        {
            var firstArg  = argument.FirstWord();
            var secondArg = argument.SecondWord();

            if (firstArg.IsNullOrEmpty())
            {
                ch.SendTo("Where?  At whom?");
                return(ReturnTypes.None);
            }

            CharacterInstance victim = null;
            var exit = ch.CurrentRoom.GetExit(firstArg);

            if (exit == null)
            {
                victim = ch.GetCharacterInRoom(firstArg);
                if (victim == null)
                {
                    ch.SendTo("Aim in what direction?");
                    return(ReturnTypes.None);
                }

                if (ch.CurrentFighting.Who == victim)
                {
                    ch.SendTo("They are too close to release that type of attack!");
                    return(ReturnTypes.None);
                }
            }

            if (victim != null)
            {
                if (ch.CurrentRoom.IsPrivate() || ch.CurrentRoom.Flags.IsSet(RoomFlags.Solitary))
                {
                    ch.SendTo("You cannot perform a ranged attack from a private room.");
                    return(ReturnTypes.None);
                }

                if (ch.CurrentRoom.Tunnel > 0)
                {
                    if (ch.CurrentRoom.Contents.OfType <CharacterInstance>().Count() >= ch.CurrentRoom.Tunnel)
                    {
                        ch.SendTo("This room is too cramped to perform such an attack.");
                        return(ReturnTypes.None);
                    }
                }
            }

            SkillData skill = null;

            if (Macros.IS_VALID_SN(sn))
            {
                skill = RepositoryManager.Instance.GetEntity <SkillData>(sn);
            }

            if (exit != null && exit.GetDestination() == null)
            {
                ch.SendTo("Are you expecting to fire through a wall?!");
                return(ReturnTypes.None);
            }

            if (exit != null && exit.Flags.IsSet(ExitFlags.Closed))
            {
                if (exit.Flags.IsSet(ExitFlags.Secret) || exit.Flags.IsSet(ExitFlags.Dig))
                {
                    ch.SendTo("Are you expecting to fire through a wall?!");
                }
                else
                {
                    ch.SendTo("Are you expecting to fire through a door?!");
                }
                return(ReturnTypes.None);
            }

            CharacterInstance vch = null;

            if (exit != null && !string.IsNullOrEmpty(secondArg))
            {
                vch = scan_for_victim(ch, exit, secondArg);
                if (vch == null)
                {
                    ch.SendTo("You cannot see your target.");
                    return(ReturnTypes.None);
                }

                if (vch.CurrentRoom.Flags.IsSet(RoomFlags.NoMissile))
                {
                    ch.SendTo("You can't get a clean shot off.");
                    return(ReturnTypes.None);
                }

                if (vch.NumberFighting > GameConstants.GetConstant <int>("MaximumCombatants"))
                {
                    ch.SendTo("There is too much activity there for you to get a clear shot.");
                    return(ReturnTypes.None);
                }
            }

            if (vch != null)
            {
                if (!vch.IsNpc() && !ch.IsNpc() && ch.Act.IsSet((int)PlayerFlags.Nice))
                {
                    ch.SendTo("You're too nice to do that!");
                    return(ReturnTypes.None);
                }
                if (fight.is_safe(ch, vch, true))
                {
                    return(ReturnTypes.None);
                }
            }

            var was_in_room = ch.CurrentRoom;

            if (projectile != null)
            {
                //todo handler.separate_obj(projectile);

                var action = weapon != null ? "fire" : "throw";
                if (exit != null)
                {
                    comm.act(ATTypes.AT_GREY, $"You {action} $p $T.", ch, projectile, exit.Direction.GetName(),
                             ToTypes.Character);
                    comm.act(ATTypes.AT_GREY, $"$n {action}s $p $T.", ch, projectile, exit.Direction.GetName(),
                             ToTypes.Room);
                }
                else
                {
                    comm.act(ATTypes.AT_GREY, $"You {action} $p at $N.", ch, projectile, victim, ToTypes.Character);
                    comm.act(ATTypes.AT_GREY, $"$n {action}s $p at $N.", ch, projectile, victim, ToTypes.NotVictim);
                    comm.act(ATTypes.AT_GREY, $"$n {action}s $p at you!", ch, projectile, victim, ToTypes.Victim);
                }
            }
            else if (skill != null)
            {
                var skillText = GetSkillText(skill);

                if (skill.Type == SkillTypes.Spell)
                {
                    var color = ATTypes.AT_MAGIC;
                    if (exit != null)
                    {
                        comm.act(color, "You release $t $T.", ch, skillText.AddArticle(ArticleAppendOptions.TheToFront),
                                 exit.Direction.GetName(), ToTypes.Character);
                        comm.act(color, "$n releases $s $t $T.", ch, skillText, exit.Direction.GetName(), ToTypes.Room);
                    }
                    else
                    {
                        comm.act(color, "You release $t at $N.", ch, skillText.AddArticle(ArticleAppendOptions.TheToFront),
                                 victim, ToTypes.Character);
                        comm.act(color, "$n releases $s $t at $N.", ch, skillText, victim, ToTypes.NotVictim);
                        comm.act(color, "$n releases $s $t at you!", ch, skillText, victim, ToTypes.Victim);
                    }
                }
            }
            else
            {
                //todo record bug, missing projectile and skill
                return(ReturnTypes.None);
            }

            if (victim != null)
            {
                fight.check_illegal_pk(ch, victim);
                ch.CheckAttackForAttackerFlag(victim);
                return(ranged_got_target(ch, victim, weapon, projectile, 0, sn, "burst of energy", ATTypes.AT_GREY));
            }

            victim = vch;
            var dtxt = act_move.rev_exit(exit.Direction);

            var dist = 0;

            while (dist <= range)
            {
                ch.CurrentRoom.RemoveFrom(ch);
                exit.GetDestination().AddTo(ch);

                if (exit.Flags.IsSet(ExitFlags.Closed))
                {
                    var color = projectile != null ? ATTypes.AT_GREY : ATTypes.AT_MAGIC;

                    var txt =
                        $"You see your {(projectile != null ? projectile.Name : GetSkillText(skill))} {(projectile != null ? "pierce" : "hit")} a door in the distance to the {exit.Direction.GetName()}.";
                    comm.act(color, txt, ch, null, null, ToTypes.Character);

                    if (projectile != null)
                    {
                    }
                }
            }

            ch.CurrentRoom.RemoveFrom(ch);
            was_in_room.AddTo(ch);

            return(ReturnTypes.None);
        }