コード例 #1
0
        public static ReturnTypes spell_area_attack(int sn, int level, CharacterInstance ch, object vo)
        {
            var skill = RepositoryManager.Instance.SKILLS.Get(sn);

            if (CheckFunctions.CheckIfTrueCasting(ch.CurrentRoom.Flags.IsSet(RoomFlags.Safe), skill, ch))
            {
                return(ReturnTypes.SpellFailed);
            }

            if (string.IsNullOrEmpty(skill.HitCharacterMessage))
            {
                comm.act(ATTypes.AT_MAGIC, skill.HitCharacterMessage, ch, null, null, ToTypes.Character);
            }
            if (string.IsNullOrEmpty(skill.HitRoomMessage))
            {
                comm.act(ATTypes.AT_MAGIC, skill.HitRoomMessage, ch, null, null, ToTypes.Room);
            }

            foreach (var vch in ch.CurrentRoom.Persons
                     .Where(x => x.IsNpc() || !x.Act.IsSet((int)PlayerFlags.WizardInvisibility) ||
                            ((PlayerInstance)x).PlayerData.WizardInvisible < LevelConstants.ImmortalLevel)
                     .Where(x => x != ch)
                     .Where(x => !fight.is_safe(ch, x, false))
                     .Where(x => ch.IsNpc() || x.IsNpc() || ch.IsInArena() || (ch.IsPKill() && x.IsPKill())))
            {
                var saved = skill.CheckSave(level, ch, vch);
                if (saved &&
                    CheckFunctions.CheckIfTrueCasting(Macros.SPELL_SAVE(skill) == (int)SpellSaveEffectTypes.Negate,
                                                      skill, ch, CastingFunctionType.Failed, vch))
                {
                    continue;
                }

                var damage = GetBaseDamage(level, ch, skill);

                if (saved)
                {
                    damage = GetDamageIfSaved(sn, level, ch, skill, vch, damage);
                }

                var retcode = ch.CauseDamageTo(vch, damage, sn);
                if (retcode == ReturnTypes.None &&
                    !ch.CharDied() && !vch.CharDied()
                    &&
                    (!vch.IsAffectedBy(sn) || skill.Flags.IsSet(SkillFlags.Accumulative) ||
                     skill.Flags.IsSet(SkillFlags.ReCastable)))
                {
                    retcode = AffectCharacter.spell_affectchar(sn, level, ch, vch);
                }

                if (retcode == ReturnTypes.CharacterDied || ch.CharDied())
                {
                    break;
                }
            }
            return(ReturnTypes.None);
        }
コード例 #2
0
        private static bool EmptyInto(CharacterInstance ch, ObjectInstance obj, RoomTemplate destroom)
        {
            var retVal = false;

            foreach (var cobj in obj.Contents)
            {
                if (ch != null && cobj.ObjectIndex.HasProg(MudProgTypes.Drop) && cobj.Count > 1)
                {
                    cobj.Split();
                    cobj.RemoveFrom(cobj);
                }
                else
                {
                    cobj.RemoveFrom(cobj);
                }

                var tObj = destroom.AddTo(cobj);

                if (ch != null)
                {
                    MudProgHandler.ExecuteObjectProg(MudProgTypes.Drop, ch, tObj);
                    if (ch.CharDied())
                    {
                        ch = null;
                    }
                }
                retVal = true;
            }
            return(retVal);
        }
コード例 #3
0
        public static ReturnTypes spell_attack(int sn, int level, CharacterInstance ch, object vo)
        {
            var skill = RepositoryManager.Instance.SKILLS.Get(sn);
            var vch   = (CharacterInstance)vo;

            var saved = skill.CheckSave(level, ch, vch);

            if (CheckFunctions.CheckIfTrueCasting(
                    saved && Macros.SPELL_SAVE(skill) == (int)SpellSaveEffectTypes.Negate, skill, ch,
                    CastingFunctionType.Failed, vch))
            {
                return(ReturnTypes.SpellFailed);
            }

            var damage = GetBaseDamage(level, ch, skill);

            if (saved)
            {
                var spellSaveType =
                    EnumerationExtensions.GetEnum <SpellSaveEffectTypes>(Macros.SPELL_SAVE(skill));
                switch (spellSaveType)
                {
                case SpellSaveEffectTypes.ThreeQuartersDamage:
                    damage = GetThreeQuartersDamage(damage);
                    break;

                case SpellSaveEffectTypes.HalfDamage:
                    damage = GetHalfDamage(damage);
                    break;

                case SpellSaveEffectTypes.QuarterDamage:
                    damage = GetQuarterDamage(damage);
                    break;

                case SpellSaveEffectTypes.EighthDamage:
                    damage = GetEighthDamage(damage);
                    break;

                case SpellSaveEffectTypes.Absorb:
                    AbsorbDamage(ch, skill, vch, damage);
                    return(ReturnTypes.None);

                case SpellSaveEffectTypes.Reflect:
                    return(spell_attack(sn, level, vch, ch));
                }
            }

            var retcode = ch.CauseDamageTo(vch, damage, sn);

            if (retcode == ReturnTypes.None &&
                !ch.CharDied() && !vch.CharDied()
                &&
                (!vch.IsAffectedBy(sn) || skill.Flags.IsSet(SkillFlags.Accumulative) ||
                 skill.Flags.IsSet(SkillFlags.ReCastable)))
            {
                retcode = AffectCharacter.spell_affectchar(sn, level, ch, vch);
            }

            return(retcode);
        }
コード例 #4
0
ファイル: AtObj.cs プロジェクト: 12-South-Studios/smaug-cs
        public static void do_atobj(CharacterInstance ch, string argument)
        {
            ch.SetColor(ATTypes.AT_IMMORT);

            var firstArg = argument.FirstWord();

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

            ObjectInstance obj = RepositoryManager.Instance.GetEntity <ObjectInstance>(argument);

            if (CheckFunctions.CheckIf(ch, () => obj?.InRoom == null,
                                       "No such object in existence."))
            {
                return;
            }

            RoomTemplate location = obj.InRoom;

            if (location.IsPrivate())
            {
                if (CheckFunctions.CheckIf(ch, () => ch.Trust < LevelConstants.GetLevel(ImmortalTypes.Greater),
                                           "That room is private right now."))
                {
                    return;
                }
                ch.SendTo("Overriding private flag!");
            }

            CharacterInstance victim = location.IsDoNotDisturb(ch);

            if (victim != null)
            {
                ch.PagerPrintf("That room is \"do not disturb\" right now.");
                victim.PagerPrintf("Your do-not-disturb flag just foiled %s's atobj command.", ch.Name);
                return;
            }

            ch.SetColor(ATTypes.AT_PLAIN);
            RoomTemplate original = ch.CurrentRoom;

            ch.CurrentRoom.RemoveFrom(ch);
            location.AddTo(ch);
            interp.interpret(ch, argument);

            if (ch.CharDied())
            {
                return;
            }
            ch.CurrentRoom.RemoveFrom(ch);
            original.AddTo(ch);
        }
コード例 #5
0
        private static void DragIntoNextRoom(CharacterInstance ch, CharacterInstance victim, ExitData exit)
        {
            var temp = victim.CurrentPosition;

            victim.CurrentPosition = PositionTypes.Drag;

            comm.act(ATTypes.AT_ACTION, "You drag $M into the next room.", ch, victim, null, ToTypes.Character);
            comm.act(ATTypes.AT_ACTION, "$n grabs your hair and drags you.", ch, victim, null, ToTypes.Victim);
            Move.move_char(victim, exit, 0);

            if (!victim.CharDied())
            {
                victim.CurrentPosition = temp;
            }

            Move.move_char(ch, exit, 0);
            Macros.WAIT_STATE(ch, 12);
        }
コード例 #6
0
ファイル: Drop.cs プロジェクト: 12-South-Studios/smaug-cs
        private static void DropObject(CharacterInstance ch, string firstArg)
        {
            var obj = ch.GetCarriedObject(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, obj, "You do not have that item."))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, !ch.CanDrop(obj), "You can't let go of it."))
            {
                return;
            }

            obj.Split();
            comm.act(ATTypes.AT_ACTION, "$n drops $p.", ch, obj, null, ToTypes.Room);
            comm.act(ATTypes.AT_ACTION, "You drop $p.", ch, obj, null, ToTypes.Character);

            obj.RemoveFrom();
            obj = ch.CurrentRoom.AddTo(obj);
            MudProgHandler.ExecuteObjectProg(MudProgTypes.Drop, ch, obj);

            if (ch.CharDied() || handler.obj_extracted(obj))
            {
                return;
            }

            if (ch.CurrentRoom.Flags.IsSet(RoomFlags.ClanStoreroom))
            {
                foreach (var clan in RepositoryManager.Instance.CLANS.Values)
                {
                    if (clan.StoreRoom == ch.CurrentRoom.ID)
                    {
                        act_obj.save_clan_storeroom(ch, clan);
                    }
                }
            }

            if (GameManager.Instance.SystemData.SaveFlags.IsSet(AutoSaveFlags.Drop))
            {
                save.save_char_obj(ch);
            }
        }
コード例 #7
0
ファイル: Say.cs プロジェクト: 12-South-Studios/smaug-cs
        public static void do_say(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

            if (CheckFunctions.CheckIfEmptyString(ch, argument, "Say what?"))
            {
                return;
            }
            if (CheckFunctions.CheckIf(ch,
                                       args => ((CharacterInstance)args[0]).CurrentRoom.Flags.IsSet((int)RoomFlags.Silence),
                                       "You can't do that here.", new List <object> {
                ch
            }))
            {
                return;
            }

            var actflags = ch.Act;
            if (ch.IsNpc())
            {
                ch.Act.RemoveBit((int)ActFlags.Secretive);
            }

            foreach (var vch in ch.CurrentRoom.Persons.Where(vch => vch != ch))
            {
                var sbuf = argument;
                if (vch.IsIgnoring(ch))
                {
                    if (!ch.IsImmortal() || vch.Trust > ch.Trust)
                    {
                        continue;
                    }

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

#if !SCRAMBLE
                /*if (speaking != -1 && (!ch.IsNpc() || ch.Speaking != 0))
                 * {
                 *  int speakswell = vch.KnowsLanguage(ch.Speaking, ch).GetLowestOfTwoNumbers(ch.KnowsLanguage(ch.Speaking, vch));
                 *  if (speakswell < 75)
                 *      sbuf = act_comm.TranslateLanguage(speakswell, argument, GameConstants.LanguageTable[speaking]);
                 * }*/
#else
                if (KnowsLanguage(vch, ch.Speaking, ch) == 0 &&
                    (!ch.IsNpc() || ch.Speaking != 0))
                {
                    sbuf = ScrambleText(argument, ch.Speaking);
                }
#endif
                sbuf = sbuf.Drunkify(ch);

                // TODO Toggle global mobtrigger flag
                comm.act(ATTypes.AT_SAY, "$n says '$t'", ch, sbuf, vch, ToTypes.Victim);
            }

            ch.Act = actflags;
            // TODO Toggle global mobtrigger flag
            comm.act(ATTypes.AT_SAY, "You say '%T'", ch, null, argument.Drunkify(ch), ToTypes.Character);

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

            MudProgHandler.ExecuteMobileProg(MudProgTypes.Speech, argument, ch);
            if (ch.CharDied())
            {
                return;
            }
            MudProgHandler.ExecuteObjectProg(MudProgTypes.Speech, argument, ch);
            if (ch.CharDied())
            {
                return;
            }
            MudProgHandler.ExecuteRoomProg(MudProgTypes.Speech, argument, ch);
        }
コード例 #8
0
        public static void do_at(CharacterInstance ch, string argument)
        {
            ch.SetColor(ATTypes.AT_IMMORT);

            var firstArg = argument.FirstWord();

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

            RoomTemplate      location       = null;
            CharacterInstance worldCharacter = null;

            if (argument.IsNumber())
            {
                location = RepositoryManager.Instance.GetEntity <RoomTemplate>(argument);
            }
            else if (argument.EqualsIgnoreCase("pk"))
            {
                // todo get last pkroom
            }
            else
            {
                worldCharacter = RepositoryManager.Instance.GetEntity <CharacterInstance>(argument);
                if (CheckFunctions.CheckIf(ch, () => worldCharacter?.CurrentRoom == null,
                                           "No such mobile or player in the world."))
                {
                    return;
                }
            }

            if (location == null && worldCharacter != null)
            {
                location = worldCharacter.CurrentRoom;
            }

            if (CheckFunctions.CheckIfNullObject(ch, location, "No such location exists."))
            {
                return;
            }

            if (worldCharacter != null && !worldCharacter.IsNpc())
            {
                if (((PlayerInstance)worldCharacter).PlayerData.Flags.IsSet(PCFlags.DoNotDisturb))
                {
                    ch.PagerPrintf("Sorry. %s does not wish to be disturbed.", worldCharacter.Name);
                    worldCharacter.PagerPrintf("Your Do-Not-Disturb flag just foiled %s's AT command.", ch.Name);
                    return;
                }
            }

            if (location.IsPrivate())
            {
                if (CheckFunctions.CheckIf(ch, () => ch.Trust < LevelConstants.GetLevel(ImmortalTypes.Greater),
                                           "That room is private right now."))
                {
                    return;
                }
                ch.SendTo("Overriding private flag!");
            }

            CharacterInstance victim = location.IsDoNotDisturb(ch);

            if (victim != null)
            {
                ch.PagerPrintf("That room is \"do not disturb\" right now.");
                victim.PagerPrintf("Your do-not-disturb flag just foiled %s's atmob command.", ch.Name);
                return;
            }

            ch.SetColor(ATTypes.AT_PLAIN);
            RoomTemplate original = ch.CurrentRoom;

            ch.CurrentRoom.RemoveFrom(ch);
            location.AddTo(ch);
            interp.interpret(ch, argument);

            if (!ch.CharDied())
            {
                ch.CurrentRoom.RemoveFrom(ch);
                original.AddTo(ch);
            }
        }
コード例 #9
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);
        }
コード例 #10
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();
        }
コード例 #11
0
        public static ReturnTypes ObjectCastSpell(this CharacterInstance ch, int sn, int level,
                                                  CharacterInstance victim = null, ObjectInstance obj = null)
        {
            var skill = RepositoryManager.Instance.GetEntity <SkillData>(sn);

            if (skill?.SpellFunction == null)
            {
                return(ReturnTypes.Error);
            }

            if (ch.CurrentRoom.Flags.IsSet(RoomFlags.NoMagic) ||
                (ch.CurrentRoom.Flags.IsSet(RoomFlags.Safe) &&
                 skill.Target == TargetTypes.OffensiveCharacter))
            {
                ch.SetColor(ATTypes.AT_MAGIC);
                ch.SendTo("Nothing seems to happen...");
                return(ReturnTypes.None);
            }

            // Reduces the number of level 5 players using level 40 scrolls in battle
            var levelDiff = ch.Level - level;

            if ((skill.Target == TargetTypes.OffensiveCharacter || SmaugRandom.Bits(7) == 1) &&
                skill.Type != SkillTypes.Herb &&
                ch.Chance(95 + levelDiff))
            {
                switch (SmaugRandom.Bits(2))
                {
                case 0:
                case 2:
                    ch.FailedCast(skill, victim);
                    break;

                case 1:
                case 3:
                    comm.act(ATTypes.AT_MAGIC, "The $t spell backfires!", ch, skill.Name, victim, ToTypes.Character);
                    if (victim != null)
                    {
                        comm.act(ATTypes.AT_MAGIC, "$n's $t spell backfires!", ch, skill.Name, victim,
                                 ToTypes.Victim);
                    }
                    comm.act(ATTypes.AT_MAGIC, "$n's $t spell backfires!", ch, skill.Name, victim, ToTypes.Room);
                    return(ch.CauseDamageTo(ch, SmaugRandom.Between(1, level), Program.TYPE_UNDEFINED));
                }

                return(ReturnTypes.None);
            }

            object vo;

            switch (skill.Target)
            {
            default:
                LogManager.Instance.Bug("Bad target for sn {0}", sn);
                return(ReturnTypes.Error);

            case TargetTypes.Ignore:
                vo = null;
                if (victim != null)
                {
                    Cast.TargetName = victim.Name;
                }
                else if (obj != null)
                {
                    Cast.TargetName = obj.Name;
                }
                break;

            case TargetTypes.OffensiveCharacter:
                if (victim != ch)
                {
                    if (victim == null)
                    {
                        victim = ch.GetMyTarget();
                    }
                    if (CheckFunctions.CheckIfTrue(ch, victim == null || (!victim.IsNpc() && !victim.IsInArena()),
                                                   "You can't do that."))
                    {
                        return(ReturnTypes.None);
                    }
                }
                if (ch != victim && fight.is_safe(ch, victim, true))
                {
                    return(ReturnTypes.None);
                }
                vo = victim;
                break;

            case TargetTypes.DefensiveCharacter:
                if (victim == null)
                {
                    victim = ch;
                }
                vo = victim;
                if (CheckFunctions.CheckIfTrueCasting(
                        skill.Type != SkillTypes.Herb && victim.Immunity.IsSet(ResistanceTypes.Magic),
                        skill, ch, CastingFunctionType.Immune, victim))
                {
                    return(ReturnTypes.None);
                }
                break;

            case TargetTypes.Self:
                vo = ch;
                if (CheckFunctions.CheckIfTrueCasting(
                        skill.Type != SkillTypes.Herb && ch.Immunity.IsSet(ResistanceTypes.Magic),
                        skill, ch, CastingFunctionType.Immune, victim))
                {
                    return(ReturnTypes.None);
                }
                break;

            case TargetTypes.InventoryObject:
                if (CheckFunctions.CheckIfNullObject(ch, obj, "You can't do that!"))
                {
                    return(ReturnTypes.None);
                }

                vo = obj;
                break;
            }

            var start   = DateTime.Now;
            var retcode = skill.SpellFunction.Value.Invoke(sn, level, ch, vo);

            skill.UseHistory.Use(ch, DateTime.Now.Subtract(start));

            if (retcode == ReturnTypes.SpellFailed)
            {
                retcode = ReturnTypes.None;
            }

            if (retcode == ReturnTypes.CharacterDied || retcode == ReturnTypes.Error)
            {
                return(retcode);
            }

            if (ch.CharDied())
            {
                return(ReturnTypes.CharacterDied);
            }

            if (skill.Target == TargetTypes.OffensiveCharacter &&
                victim != ch &&
                !victim.CharDied())
            {
                foreach (
                    var vch in
                    ch.CurrentRoom.Persons.Where(
                        vch => victim == vch && vch.CurrentFighting == null && vch.Master != ch))
                {
                    retcode = fight.multi_hit(vch, ch, Program.TYPE_UNDEFINED);
                    break;
                }
            }

            return(retcode);
        }
コード例 #12
0
 private static bool ReflectDamage(int sn, int level, CharacterInstance ch, CharacterInstance vch)
 {
     Attack.spell_attack(sn, level, vch, ch);
     return(ch.CharDied());
 }
コード例 #13
0
ファイル: act_obj.cs プロジェクト: 12-South-Studios/smaug-cs
        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);
        }
コード例 #14
0
        public static void ModifyAffect(this CharacterInstance ch, AffectData affect, bool add)
        {
            var mod = affect.Modifier;

            if (add)
            {
                mod = ModifyAndAddAffect(ch, affect, mod);
            }
            else
            {
                ch.AffectedBy.RemoveBit((int)affect.Type);

                if ((int)affect.Location % Program.REVERSE_APPLY == (int)ApplyTypes.RecurringSpell)
                {
                    mod = Math.Abs(mod);
                    var skill = RepositoryManager.Instance.SKILLS.Values.ToList()[mod];

                    if (!Macros.IS_VALID_SN(mod) || skill == null || skill.Type != SkillTypes.Spell)
                    {
                        throw new InvalidDataException($"RecurringSpell with bad SN {mod}");
                    }
                    ch.AffectedBy.RemoveBit((int)AffectedByTypes.RecurringSpell);
                    return;
                }

                switch ((int)affect.Location % Program.REVERSE_APPLY)
                {
                case (int)ApplyTypes.Affect:
                    return;

                case (int)ApplyTypes.ExtendedAffect:
                    ch.AffectedBy.RemoveBit(mod);
                    return;

                case (int)ApplyTypes.Resistance:
                    ch.Resistance.RemoveBit(mod);
                    return;

                case (int)ApplyTypes.Immunity:
                    ch.Immunity.RemoveBit(mod);
                    return;

                case (int)ApplyTypes.Susceptibility:
                    ch.Susceptibility.RemoveBit(mod);
                    return;

                case (int)ApplyTypes.Remove:
                    return;
                }
                mod = 0 - mod;
            }

            var applyType = Common.EnumerationExtensions.GetEnum <ApplyTypes>((int)affect.Location % Program.REVERSE_APPLY);

            switch (applyType)
            {
            case ApplyTypes.Strength:
                ch.ModStrength += mod;
                break;

            case ApplyTypes.Dexterity:
                ch.ModDexterity += mod;
                break;

            case ApplyTypes.Intelligence:
                ch.ModIntelligence += mod;
                break;

            case ApplyTypes.Wisdom:
                ch.ModWisdom += mod;
                break;

            case ApplyTypes.Constitution:
                ch.ModConstitution += mod;
                break;

            case ApplyTypes.Charisma:
                ch.ModCharisma += mod;
                break;

            case ApplyTypes.Luck:
                ch.ModLuck += mod;
                break;

            case ApplyTypes.Gender:
                //ch.Gender = (ch.Gender + mod) % 3;
                // TODO Fix this
                //if (ch.Gender < 0)
                //    ch.Gender += 2;
                //ch.Gender = Check.Range(0, ch.Gender, 2);
                break;

            case ApplyTypes.Height:
                ch.Height += mod;
                break;

            case ApplyTypes.Weight:
                ch.Weight += mod;
                break;

            case ApplyTypes.Mana:
                ch.MaximumMana += mod;
                break;

            case ApplyTypes.Hit:
                ch.MaximumHealth += mod;
                break;

            case ApplyTypes.Movement:
                ch.MaximumMovement += mod;
                break;

            case ApplyTypes.ArmorClass:
                ch.ArmorClass += mod;
                break;

            case ApplyTypes.HitRoll:
                ch.HitRoll.SizeOf += mod;
                break;

            case ApplyTypes.DamageRoll:
                ch.DamageRoll.SizeOf += mod;
                break;

            case ApplyTypes.SaveVsPoison:
                ch.SavingThrows.SaveVsPoisonDeath += mod;
                break;

            case ApplyTypes.SaveVsRod:
                ch.SavingThrows.SaveVsWandRod += mod;
                break;

            case ApplyTypes.SaveVsParalysis:
                ch.SavingThrows.SaveVsParalysisPetrify += mod;
                break;

            case ApplyTypes.SaveVsBreath:
                ch.SavingThrows.SaveVsBreath += mod;
                break;

            case ApplyTypes.SaveVsSpell:
                ch.SavingThrows.SaveVsSpellStaff += mod;
                break;

            case ApplyTypes.Affect:
                ch.AffectedBy.Bits[0].SetBit(mod);
                break;

            case ApplyTypes.ExtendedAffect:
                ch.AffectedBy.SetBit(mod);
                break;

            case ApplyTypes.Resistance:
                ch.Resistance.SetBit(mod);
                break;

            case ApplyTypes.Immunity:
                ch.Immunity.SetBit(mod);
                break;

            case ApplyTypes.Susceptibility:
                ch.Susceptibility.SetBit(mod);
                break;

            case ApplyTypes.Remove:
                ch.AffectedBy.Bits[0].RemoveBit(mod);
                break;

            case ApplyTypes.Full:
            case ApplyTypes.Thirst:
            case ApplyTypes.Drunk:
            case ApplyTypes.Blood:
                HandlePlayerCondition(ch, applyType, mod);
                break;

            case ApplyTypes.MentalState:
                ch.MentalState = (ch.MentalState + mod).GetNumberThatIsBetween(-100, 100);
                break;

            case ApplyTypes.Emotion:
                ch.EmotionalState = ch.EmotionalState.GetNumberThatIsBetween(-100, 100);
                break;

            case ApplyTypes.StripSN:
                if (Macros.IS_VALID_SN(mod))
                {
                    ch.StripAffects(mod);
                }
                else
                {
                    LogManager.Instance.Bug("apply_modify: ApplyTypes.StripSN invalid SN %d", mod);
                }
                break;

            case ApplyTypes.WearSpell:
            case ApplyTypes.RemoveSpell:
                if (ch.CurrentRoom.Flags.IsSet(RoomFlags.NoMagic) ||
                    ch.Immunity.IsSet(ResistanceTypes.Magic) ||
                    (applyType == ApplyTypes.WearSpell && !add) ||
                    (applyType == ApplyTypes.RemoveSpell && add) ||
                    handler.SavingCharacter == ch ||
                    handler.LoadingCharacter == ch)
                {
                    return;
                }

                mod = Math.Abs(mod);
                var skill = RepositoryManager.Instance.SKILLS.Values.ToList()[mod];

                if (Macros.IS_VALID_SN(mod) && skill != null && skill.Type == SkillTypes.Spell)
                {
                    if (skill.Target == TargetTypes.Ignore ||
                        skill.Target == TargetTypes.InventoryObject)
                    {
                        LogManager.Instance.Bug("ApplyTypes.WearSpell trying to apply bad target spell. SN is %d.", mod);
                        return;
                    }
                    var retcode = skill.SpellFunction.Value.Invoke(mod, ch.Level, ch, ch);
                    if (retcode == ReturnTypes.CharacterDied || ch.CharDied())
                    {
                        return;
                    }
                }
                break;

            default:
                var skillData = RepositoryManager.Instance.GetEntity <SkillData>(applyType.GetName());
                if (skillData != null)
                {
                    ch.ModifySkill((int)skillData.Type, mod, add);
                }
                else
                {
                    LogManager.Instance.Bug("affect_modify: unknown location %d", affect.Location);
                }
                break;
            }

            var wield       = ch.GetEquippedItem(WearLocations.Wield);
            var strWieldMod = (int)LookupManager.Instance.GetStatMod("Strength", ch.GetCurrentStrength(),
                                                                     StrengthModTypes.Wield);

            if (!ch.IsNpc() && handler.SavingCharacter != ch && wield != null && wield.GetWeight() > strWieldMod)
            {
                if (Depth == 0)
                {
                    Depth++;
                    comm.act(ATTypes.AT_ACTION, "You are too weak to wield $p any longer.", ch, wield, null,
                             ToTypes.Character);
                    comm.act(ATTypes.AT_ACTION, "$n stops wielding $p.", ch, wield, null, ToTypes.Room);
                    ch.Unequip(wield);
                    Depth--;
                }
            }
        }
コード例 #15
0
        public static ObjectInstance RawKill(this CharacterInstance ch, CharacterInstance victim)
        {
            var victimPc = (PlayerInstance)victim;

            if (victim.IsNotAuthorized())
            {
                LogManager.Instance.Bug("Killing unauthorized");
                return(null);
            }

            victim.StopFighting(true);

            if (victim.CurrentMorph != null)
            {
                UnmorphChar.do_unmorph_char(victim, string.Empty);
                return(ch.RawKill(victim));
            }

            MudProgHandler.ExecuteMobileProg(MudProgTypes.Death, ch, victim);
            if (victim.CharDied())
            {
                return(null);
            }

            MudProgHandler.ExecuteRoomProg(MudProgTypes.Death, victim);
            if (victim.CharDied())
            {
                return(null);
            }

            var corpse = ObjectFactory.CreateCorpse(victim, ch);

            switch (victim.CurrentRoom.SectorType)
            {
            case SectorTypes.OceanFloor:
            case SectorTypes.Underwater:
            case SectorTypes.ShallowWater:
            case SectorTypes.DeepWater:
                comm.act(ATTypes.AT_BLOOD, "$n's blood slowly clouds the surrounding water.", victim, null, null, ToTypes.Room);
                break;

            case SectorTypes.Air:
                comm.act(ATTypes.AT_BLOOD, "$n's blood sprays wildly through the air.", victim, null, null, ToTypes.Room);
                break;

            default:
                ObjectFactory.CreateBlood(victim);
                break;
            }

            if (victim.IsNpc())
            {
                ((MobileInstance)victim).MobIndex.TimesKilled++;
                victim.Extract(true);
                victim = null;
                return(corpse);
            }

            victim.SetColor(ATTypes.AT_DIEMSG);
            Help.do_help(victim,
                         ((PlayerInstance)victim).PlayerData.PvEDeaths + ((PlayerInstance)victim).PlayerData.PvPDeaths < 3 ? "new_death" : "_DIEMSG_");

            victim.Extract(false);

            while (victim.Affects.Count > 0)
            {
                victim.RemoveAffect(victim.Affects.First());
            }

            var victimRace = RepositoryManager.Instance.GetRace(victim.CurrentRace);

            victim.AffectedBy       = victimRace.AffectedBy;
            victim.Resistance       = 0;
            victim.Susceptibility   = 0;
            victim.Immunity         = 0;
            victim.CarryWeight      = 0;
            victim.ArmorClass       = 100 + victimRace.ArmorClassBonus;
            victim.Attacks          = victimRace.Attacks;
            victim.Defenses         = victimRace.Defenses;
            victim.ModStrength      = 0;
            victim.ModDexterity     = 0;
            victim.ModWisdom        = 0;
            victim.ModIntelligence  = 0;
            victim.ModConstitution  = 0;
            victim.ModCharisma      = 0;
            victim.ModLuck          = 0;
            victim.DamageRoll       = new DiceData();
            victim.HitRoll          = new DiceData();
            victim.MentalState      = -10;
            victim.CurrentAlignment = Macros.URANGE(-1000, victim.CurrentAlignment, 1000);
            victim.SavingThrows     = victimRace.SavingThrows;
            victim.CurrentPosition  = PositionTypes.Resting;
            victim.CurrentHealth    = Macros.UMAX(1, victim.CurrentHealth);
            victim.CurrentMana      = victim.Level < GetLevelAvatar() ? Macros.UMAX(1, victim.CurrentMana) : 1;
            victim.CurrentMovement  = Macros.UMAX(1, victim.CurrentMovement);

            if (victim.Act.IsSet((int)PlayerFlags.Killer))
            {
                victim.Act.RemoveBit((int)PlayerFlags.Killer);
                victim.SendTo("The gods have pardoned you for your murderous acts.");
            }

            if (victim.Act.IsSet((int)PlayerFlags.Thief))
            {
                victim.Act.RemoveBit((int)PlayerFlags.Thief);
                victim.SendTo("The gods have pardoned you for your thievery.");
            }

            victimPc.PlayerData.SetConditionValue(ConditionTypes.Full, 12);
            victimPc.PlayerData.SetConditionValue(ConditionTypes.Thirsty, 12);

            if (victimPc.IsVampire())
            {
                victimPc.PlayerData.SetConditionValue(ConditionTypes.Bloodthirsty, victim.Level / 2);
            }

            // TODO if (IS_SET(sysdata.save_flags, SV_DEATH))
            //      save_char_obj(victim);

            return(corpse);
        }
コード例 #16
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);
        }