예제 #1
0
        /// <summary>
        /// Interpret incoming command. To be moved to a Command Manager or GameCommand in the near future.
        /// </summary>
        /// <param name="command"></param>
        /// <param name="args"></param>
        /// <returns>False if invalid command. True if the command was completed.</returns>
        public bool InterpretCommand(string command, string args)
        {
            var i           = 0;
            var sCmdAndArgs = command + " " + args;
            var newArgs     = "";

            // Dead characters can only rest or quit.
            if (_chr.IsDead && command.ToLower() != "rest" && command.ToLower() != "quit")
            {
                _chr.WriteToDisplay("You are dead, you can either wait to be resurrected or rest.");
                return(true);
            }

            #region If a command is being interpreted then the character is no longer resting or meditating.
            if (_chr.IsResting && !_chr.IsMeditating)
            {
                if (command.ToLower() != "rest" &&
                    !command.StartsWith(((char)27).ToString()) &&
                    !command.StartsWith("show"))
                {
                    _chr.WriteToDisplay("You are no longer resting.");

                    _chr.IsResting = false;
                }
            }

            if (_chr.IsMeditating)
            {
                // using the "meditate" command while meditating will cancel meditation
                if (command.ToLower() != "memorize" &&
                    !command.StartsWith(((char)27).ToString()) && // protocol command
                    !command.StartsWith("show"))
                {
                    _chr.WriteToDisplay("You are no longer meditating.");
                    _chr.IsResting    = false;
                    _chr.IsMeditating = false;
                }
            }
            #endregion

            // Any command while peeking will be an automatic rest and break the character out of the trance.
            if (_chr.IsPeeking)
            {
                command = "rest";
                args    = "";
            }

            #region If wizard eye
            // Only movement, look, rest and again are acceptable commands when in wizard eye.
            if (_chr.IsWizardEye)
            {
                command = command.ToLower();
                switch (command.ToLower())
                {
                case "n":
                case "north":
                case "s":
                case "south":
                case "e":
                case "east":
                case "w":
                case "west":
                case "ne":
                case "northeast":
                case "nw":
                case "northwest":
                case "se":
                case "southeast":
                case "sw":
                case "southwest":
                case "d":
                case "down":
                case "u":
                case "up":
                case "a":
                case "again":
                case "l":
                case "look":
                case "rest":
                    break;

                default:
                    _chr.WriteToDisplay("You cannot use that command while polymorphed.");
                    return(true);
                }
            }
            #endregion

            if (_chr.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol)
            {
                if (ProtocolYuusha.CheckGameCommand(_chr, command, args))
                {
                    return(true);
                }
            }

            // catch some commands before they go through the parser

            #region If Speech. Command starts with a / or a " while in game.
            if (command.StartsWith("/") || command.StartsWith("\""))
            {
                if (!_chr.IsImmortal && _chr.HasEffect(Effect.EffectTypes.Silence))
                {
                    _chr.WriteToDisplay("You have been silenced and are unable to speak.");
                    return(true);
                }

                if (args.IndexOf("/!") != -1)
                {
                    _chr.SendShout(_chr.Name + ": " + args.Substring(0, args.IndexOf("/!")));
                    if (_chr.IsPC)
                    {
                        _chr.WriteToDisplay("You shout: " + args.Substring(0, args.IndexOf("/!")));
                        Utils.Log(_chr.Name + ": " + args.Substring(0, args.IndexOf("/!")), Utils.LogType.PlayerChat);
                    }
                    return(true);
                }
                else if (args.IndexOf("\"!") != -1)
                {
                    _chr.SendShout(_chr.Name + ": " + args.Substring(0, args.IndexOf("\"!")));
                    if (_chr.IsPC)
                    {
                        _chr.WriteToDisplay("You shout: " + args.Substring(0, args.IndexOf("\"!")));
                        Utils.Log(_chr.Name + ": " + args.Substring(0, args.IndexOf("\"!")), Utils.LogType.PlayerChat);
                    }
                    return(true);
                }
                else
                {
                    _chr.SendToAllInSight(_chr.Name + ": " + args);
                    if (_chr.IsPC)
                    {
                        _chr.WriteToDisplay("You say: " + args);
                        Utils.Log(_chr.Name + ": " + args, Utils.LogType.PlayerChat);
                    }
                    return(true);
                }
            }
            #endregion

            #region NPC interaction. Command ends with a comma (,)
            else if (command.EndsWith(","))// && !command.ToLower().StartsWith("all"))
            {
                if (!_chr.IsImmortal && _chr.HasEffect(Effect.EffectTypes.Silence))
                {
                    _chr.WriteToDisplay("You have been silenced and are unable to speak.");
                    return(true);
                }

                try
                {
                    // djinn, take halberd
                    // djinn, take 2 halberd
                    // 2 djinn, take 2 halberd
                    // all, follow me

                    string targetName = command.Substring(0, command.IndexOf(",")); // definitely going to be a comma

                    string[] targetArgs = targetName.Split(" ".ToCharArray());      // if this is longer than 1 in length probably using #

                    args = args.Trim();

                    string[] sArgs = args.Split(" ".ToCharArray());

                    if (String.IsNullOrEmpty(sArgs[0]) || sArgs.Length == 0)
                    {
                        return(false);
                    }

                    string order = sArgs[0];

                    args = args.Replace(order, "");

                    args = args.Trim();

                    #region All, do something
                    if (command.ToLower().StartsWith("all"))
                    {
                        if (_chr.Pets == null || _chr.Pets.Count == 0)
                        {
                            _chr.WriteToDisplay("There is nothing here to interact with.");
                            return(true);
                        }

                        bool interactPositive = false;

                        foreach (NPC pet in new List <NPC>(_chr.Pets))
                        {
                            if (TargetAcquisition.FindTargetInView(_chr, pet) != null)
                            {
                                interactPositive = AI.Interact(_chr, pet, order, args);
                            }
                        }

                        return(interactPositive);
                    }
                    #endregion

                    Character target = null;

                    var countTo = 0;

                    // Not using ALL, try 2 <target>, do something.
                    if (targetArgs.Length > 1 && Int32.TryParse(targetArgs[0], out countTo))
                    {
                        target = TargetAcquisition.FindTargetInView(_chr, targetArgs[1].ToLower(), countTo);
                    }

                    // Not using ALL, try <target>, do something.
                    if (target == null && targetArgs.Length == 1)
                    {
                        target = TargetAcquisition.FindTargetInView(_chr, targetArgs[0].ToLower(), 1);

                        if (target == null)
                        {
                            target = TargetAcquisition.FindTargetInView(_chr, targetName, false, false);
                        }
                    }

                    if (target == null)
                    {
                        _chr.WriteToDisplay("You do not see " + targetName + " here.");
                        return(true);
                    }
                    else
                    {
                        return(AI.Interact(_chr, target, order, args));
                    }
                }
                catch (Exception e)
                {
                    Utils.LogException(e);
                    return(false);
                }
            }
            #endregion
            else
            {
                int andStrPos = 0;

                #region Check for command joining, split them then parse and int
                // If command has the word "and" for joining two commands.
                // 9/24/2019 We don't still need this.
                //if (_chr.PCState == Globals.ePlayerState.PLAYING && sCmdAndArgs.IndexOf(" and ") != -1 && command.ToLower() != "tell" && )
                //    sCmdAndArgs = sCmdAndArgs.Replace(" and ", ";");

                andStrPos = sCmdAndArgs.IndexOf(";", 0, sCmdAndArgs.Length);

                if (andStrPos > 0)
                {
                    //Break out the two commands
                    string[] sCommands = sCmdAndArgs.Split(";".ToCharArray());

                    if (sCommands[0].Length > 0)
                    {
                        //get the command and the args
                        sCommands[0] = sCommands[0].Trim();//.ToLower();

                        string[] sArgss = sCommands[0].Split(" ".ToCharArray());

                        for (i = 1; i <= sArgss.GetUpperBound(0); i++)
                        {
                            newArgs = newArgs + " " + sArgss[i];
                        }

                        ParseCommand(_chr, sArgss[0].ToString().Trim(), newArgs.Trim());
                        //chr.FirstJoinedCommand = chr.CommandsProcessed[0];
                        //chr.FirstJoinedCommand = chr.CommandType;
                    }

                    if (sCommands[1].Length > 0)
                    {
                        //get the command and the args
                        sCommands[1] = sCommands[1].Trim();//.ToLower();

                        string[] s2Argss = sCommands[1].Split(" ".ToCharArray());

                        newArgs = "";

                        for (i = 1; i <= s2Argss.GetUpperBound(0); i++)
                        {
                            if (s2Argss[i].ToLower() != "it")
                            {
                                newArgs = newArgs + " " + s2Argss[i];
                            }
                            else
                            {
                                string[] sArgss = sCommands[0].Split(" ".ToCharArray());
                                newArgs = newArgs + " " + sArgss[1];
                            }
                        }

                        ParseCommand(_chr, s2Argss[0].ToString().Trim(), newArgs.Trim());
                        //chr.FirstJoinedCommand = CommandType.None;
                    }

                    return(true);
                }
                #endregion

                if (command.StartsWith("$"))
                {
                    if (command.Contains("list"))
                    {
                        args = "list";
                    }
                    else if (command.Length > 1 && command.Length < 4)
                    {
                        args = command.Substring(1, command.Length - 1) + " " + args;
                        args.Trim();
                    }

                    command = "macro";
                }

                // lower case
                command = command.ToLower();

                #region Check command aliases and change the command if an alias is found.
                if (GameCommand.GameCommandAliases.ContainsKey(command))
                {
                    command = GameCommand.GameCommandAliases[command];
                }
                else if (GameCommand.GameCommandAliases.ContainsKey(command + " " + args))
                {
                    command = GameCommand.GameCommandAliases[command + " " + args];
                }
                #endregion

                // check for the command in the dictionary
                if (GameCommand.GameCommandDictionary.ContainsKey(command))
                {
                    // non player characters make no checks to perform commands
                    if (!(_chr is PC))
                    {
                        return(GameCommand.GameCommandDictionary[command].Handler.OnCommand(_chr, args));
                    }

                    GameCommand gc = GameCommand.GameCommandDictionary[command];

                    // check player ImpLevel and the command may be executed while playing the game
                    if ((_chr as PC).ImpLevel >= (Globals.eImpLevel)gc.PrivLevel &&
                        Array.IndexOf(gc.States, _chr.PCState) > -1)
                    {
                        _chr.CommandWeight += gc.Weight;

                        return(GameCommand.GameCommandDictionary[command].Handler.OnCommand(_chr, args));
                    }

                    return(false);
                }
                else if (Talents.GameTalent.GameTalentDictionary.ContainsKey(command))
                {
                    Talents.GameTalent gameTalent = Talents.GameTalent.GameTalentDictionary[command];

                    // immortal flag added for testing purposes
                    if ((_chr.IsImmortal || _chr.talentsDictionary.ContainsKey(command)) && !gameTalent.IsPassive)
                    {
                        if (_chr.IsImmortal || (DateTime.UtcNow - gameTalent.DownTime >= _chr.talentsDictionary[command]))
                        {
                            if (!gameTalent.MeetsPerformanceCost(_chr))
                            {
                                _chr.WriteToDisplay("You do not have enough stamina to perform the " + gameTalent.Name + " talent.");
                                return(true);
                            }

                            if (!Talents.GameTalent.GameTalentDictionary[command].Handler.OnPerform(_chr, args))
                            {
                                _chr.WriteToDisplay("Talent not performed.");
                            }
                            else
                            {
                                gameTalent.SuccessfulPerformance(_chr);
                            }
                        }
                        else
                        {
                            int roundsRemaining = Utils.TimeSpanToRounds(gameTalent.DownTime - (DateTime.UtcNow - _chr.talentsDictionary[command]));
                            _chr.WriteToDisplay("Talent timer has not reset yet. It will be available " + (roundsRemaining > 0 ? "in " + roundsRemaining : "next") + " round" + (roundsRemaining > 1 ? "s" : "") + ".");
                        }
                    }
                    else if (_chr.talentsDictionary.ContainsKey(command) && gameTalent.IsPassive)
                    {
                        _chr.WriteToDisplay(gameTalent.Name + " is a passive talent.");
                    }
                    else
                    {
                        _chr.WriteToDisplay("You do not know how to perform the " + gameTalent.Name + " talent.");
                    }

                    return(true);
                }
                else // command does not exist in the dictionary
                {
                    MethodInfo[] methodInfo = typeof(CommandTasker).GetMethods();

                    try
                    {
                        foreach (MethodInfo m in methodInfo)
                        {
                            int length = m.Name.Length;
                            if (m.Name.IndexOf("_") != -1)
                            {
                                length = m.Name.IndexOf("_");
                            }
                            if (m.Name.ToLower().Substring(0, length) == command)
                            {
                                _chr.CommandWeight += 1; // add one to the command weight

                                object[] obj = new object[1];

                                obj[0] = args;

                                try
                                {
                                    m.Invoke(this, obj);
                                }
                                catch (Exception e)
                                {
                                    Utils.LogException(e);
                                }
                                return(true);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        _chr.WriteToDisplay("Error processing your command. Please report this.");
                        Utils.Log("Failure at Command.interpretCommand(" + command + ", " + args + ")", Utils.LogType.SystemFailure);
                        Utils.LogException(e);
                        return(false);
                    }
                }
            }

            #region Spell Chant Exists
            if (_chr.spellDictionary.ContainsValue(command.ToLower() + " " + args.ToLower()))
            {
                if (!_chr.IsImmortal && _chr.InUnderworld)
                {
                    _chr.WriteToDisplay(TextManager.COMMAND_NOT_UNDERSTOOD);
                    return(true);
                }

                if (!_chr.IsImmortal && _chr.HasEffect(Effect.EffectTypes.Silence))
                {
                    _chr.WriteToDisplay("You have been silenced and are unable to warm spells.");
                    return(true);
                }

                if (_chr.preppedSpell != null) // TODO talent here to automatically clear prepped spell
                {
                    _chr.WriteToDisplay("You already have a spell warmed. Either cast it or rest to clear your mind.");
                    return(true);
                }
                else
                {
                    _chr.CommandWeight += 3;

                    if (_chr.CommandWeight == 3)
                    {
                        _chr.CommandType = CommandType.Chant;
                        foreach (int spellID in _chr.spellDictionary.Keys)
                        {
                            if (_chr.spellDictionary[spellID] == (command.ToLower() + " " + args.ToLower()))
                            {
                                _chr.WarmSpell(spellID);
                                break;
                            }
                        }

                        //if(_chr is PC)
                        //    World.magicCordThisRound.Add(_chr.FacetID + "|" + _chr.LandID + "|" + _chr.MapID + "|" + _chr.X + "|" + _chr.Y + "|" + _chr.Z);

                        _chr.PreppedRound = DragonsSpineMain.GameRound;
                        int  bitcount = 0;
                        Cell curCell  = null;
                        // this is the same logic from chr.sendToAllInSight, however we add spell info in some situations
                        // loop through all visible cells

                        for (int ypos = -3; ypos <= 3; ypos += 1)
                        {
                            for (int xpos = -3; xpos <= 3; xpos += 1)
                            {
                                if (Cell.CellRequestInBounds(_chr.CurrentCell, xpos, ypos))
                                {
                                    if (_chr.CurrentCell.visCells[bitcount]) // check the PC list, and char list of the cell
                                    {
                                        curCell = Cell.GetCell(_chr.FacetID, _chr.LandID, _chr.MapID, _chr.X + xpos, _chr.Y + ypos, _chr.Z);

                                        if (curCell != null)
                                        {
                                            foreach (Character character in curCell.Characters.Values)                    // search for the character in the charlist of the cell
                                            {
                                                if (character != _chr && character is PC)                                 // players sending messages to other players
                                                {
                                                    if (Array.IndexOf((character as PC).ignoreList, _chr.UniqueID) == -1) // ignore list
                                                    {
                                                        if ((_chr.Group != null && _chr.preppedSpell != null && _chr.Group.GroupMemberIDList.Contains(character.UniqueID)) ||
                                                            (character as PC).ImpLevel >= Globals.eImpLevel.GM ||
                                                            character.HasEffect(Effect.EffectTypes.Gnostikos))
                                                        {
                                                            character.WriteToDisplay(_chr.Name + ": " + command + " " + args + " <" + _chr.preppedSpell.Name + ">");
                                                        }
                                                        else
                                                        {
                                                            character.WriteToDisplay(_chr.Name + ": " + command + " " + args);
                                                        }
                                                    }
                                                }
                                                else if (character != _chr && character.IsPC && !_chr.IsPC) // non players sending messages to other players
                                                {
                                                    character.WriteToDisplay(_chr.Name + ": " + command + " " + args);
                                                }

                                                //TODO: else... detect spell casting by sensitive NPC
                                            }
                                        }
                                    }
                                    bitcount++;
                                }
                            }
                        }
                    }
                    else
                    {
                        _chr.WriteToDisplay("Warming a spell requires your full concentration.");
                    }
                }
                return(true);
            }
            #endregion

            Utils.Log(_chr.GetLogString() + " Invalid command: " + command + " args: " + args, Utils.LogType.CommandFailure);
            _chr.WriteToDisplay("I don't understand your command. For a full list of game commands visit the Dragon's Spine forums.");
            return(false);
        }
예제 #2
0
        public static bool ParseCommand(Character chr, string command, string args)
        {
            if (!chr.IsPC)
            {
                chr.LastCommand   = command + " " + args;
                chr.CommandWeight = 0; // always reset an NPC's command weight...
            }

            var cmd       = new CommandTasker(chr);
            var fullinput = command + " " + args;
            var newArgs   = "";

            if (command.ToLower().StartsWith("say"))
            {
                command = "/";
            }

            if (chr.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol || chr.CommandWeight <= 3)
            {
                if (!command.StartsWith("$"))
                {
                    var chatPos = 0;
                    var i       = 0;

                    #region goto SlashChat
                    if (fullinput.IndexOf("\"") != -1 && fullinput.IndexOf("/") != -1)
                    {
                        if (fullinput.IndexOf("/") < fullinput.IndexOf("\""))
                        {
                            goto SlashChat;
                        }
                    }
                    #endregion

                    chatPos = fullinput.IndexOf("\"");

                    #region Found quotation mark, separate command from chat
                    if (chatPos > -1) // Break out the chat string
                    {
                        string chatCommand = fullinput.Substring(chatPos + 1);

                        if (chatPos > 0)
                        {
                            string[] commandOne = fullinput.Substring(0, chatPos).Split(" ".ToCharArray());// newCommand[0].Split(" ".ToCharArray());

                            for (i = 1; i <= commandOne.GetUpperBound(0); i++)
                            {
                                newArgs = newArgs + " " + commandOne[i];
                            }

                            command = commandOne[0].Trim();

                            args = newArgs.Trim();

                            cmd.InterpretCommand(command, args);
                        }

                        cmd.InterpretCommand("/", chatCommand);

                        return(true);
                    }
                    #endregion

SlashChat:
                    #region Separate command from slash chat
                    chatPos = fullinput.IndexOf("/");

                    if (chatPos > -1) // Break out the chat string
                    {
                        string chatCommand = fullinput.Substring(chatPos + 1);

                        if (chatPos > 0)
                        {
                            string[] commandOne = fullinput.Substring(0, chatPos).Split(" ".ToCharArray());// newCommand[0].Split(" ".ToCharArray());

                            for (i = 1; i <= commandOne.GetUpperBound(0); i++)
                            {
                                newArgs = newArgs + " " + commandOne[i];
                            }

                            command = commandOne[0].Trim();

                            args = newArgs.Trim();

                            cmd.InterpretCommand(command, args);
                        }

                        cmd.InterpretCommand("/", chatCommand);
                        return(true);
                    }
                    #endregion
                }

                cmd.InterpretCommand(command, args);

                if (chr.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol)
                {
                    ProtocolYuusha.ShowMap(chr);
                }

                return(true);
            }
            return(false);
        }
예제 #3
0
        public static void PrintMainMenu(PC ch)
        {
            DateTime lastOnline = Account.GetLastOnline(ch.Account.accountID);

            #region If using APP_PROTOCOL
            if (ch.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol)
            {
                ch.Write(ProtocolYuusha.DETECT_CLIENT);

                ProtocolYuusha.sendWorldNews(ch);

                if (!ch.sentWorldInformation)
                {
                    ch.Write(ProtocolYuusha.WORLD_INFORMATION);
                    ProtocolYuusha.SendWorldVersion(ch); // stored client side, also has round delay
                    ProtocolYuusha.SendWorldSpells(ch);  // stored client side
                    ProtocolYuusha.SendWorldTalents(ch); // stored client side
                    //ProtocolYuusha.sendWorldLands(ch);
                    //ProtocolYuusha.sendWorldMaps(ch);
                    //ProtocolYuusha.sendWorldCharGen(ch);
                    ProtocolYuusha.SendAccountInfo(ch);
                    ProtocolYuusha.SendCharacterList(ch);

                    // World info is not currently used in Yuusha as of 12/28/2016 -Eb

                    ch.sentWorldInformation = true;
                }

                if (ch.PCState == Globals.ePlayerState.MAINMENU)
                {
                    ch.Write(ProtocolYuusha.MENU_MAIN);
                }

                ProtocolYuusha.SendCurrentCharacterID(ch);

                //ProtocolYuusha.SendUserList(ch);
            }
            #endregion
            else
            {
                if (ch.protocol != "old-kesmai")
                {
                    ch.Write(ProtocolYuusha.DETECT_PROTOCOL);
                }

                Map.ClearMap(ch);
                ch.WriteLine(DragonsSpineMain.Instance.Settings.ServerName + " (" + DragonsSpineMain.Instance.Settings.ServerVersion + ") Main Menu");

                if (lastOnline.ToString() == "1/1/1900 12:00:00 AM")
                {
                    ch.WriteLine("Welcome, " + ch.Account.accountName + "!                                         ");
                }
                else
                {
                    ch.WriteLine("Welcome back, " + ch.Account.accountName + "!                                    ");
                    ch.WriteLine("Your last visit to " + DragonsSpineMain.Instance.Settings.ServerName + " was on " + lastOnline.ToShortDateString() + " at " + lastOnline.ToShortTimeString() + ".");
                }

                // NOTE: SPINEL DETECTS THE BELOW LINE
                ch.WriteLine("Current Character: " + ch.Name + " Level: " + ch.Level + " Class: " + ch.classFullName + " Land: " + ch.Land.Name + " Map: " + ch.Map.Name);

                // new mail message
                if ((ch as PC).Mailbox.HasUnreadMail)
                {
                    string plural = (ch as PC).Mailbox.UnreadMessages.Count > 1 ? "messages" : "message";
                    ch.WriteLine(Map.CLRLN + Map.BWHT + "You have " + (ch as PC).Mailbox.UnreadMessages.Count + " unread " + plural + " in your mailbox." + Map.CEND);
                }
                ch.WriteLine("");
                ch.WriteLine("1. Enter Game");
                ch.WriteLine("2. Enter Conference Room");
                ch.WriteLine("3. Disconnect");
                ch.WriteLine("4. View Account");
                ch.WriteLine("5. Change Protocol (" + ch.protocol + ")");
                ch.WriteLine("6. Change/Create/Delete Character");
                ch.WriteLine("7. Mail Menu");
                ch.WriteLine("");
                ch.Write("Command: ");
            }

            Account.SetLastOnline(ch.Account.accountID);
        }
예제 #4
0
        public bool OnCommand(Character chr, string args)
        {
            if (chr.preppedSpell != null) // lose spell
            {
                chr.preppedSpell = null;
                chr.WriteToDisplay("You have lost your warmed spell.");
                chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.SpellFail));
            }

            if (chr.CommandWeight > 3)
            {
                chr.WriteToDisplay("Command weight limit exceeded. Rest command not processed.");
                return(false);
            }

            if (chr.IsWizardEye)
            {
                chr.EffectsList[Effect.EffectTypes.Wizard_Eye].StopCharacterEffect();
                return(true);
            }
            else if (chr.IsPeeking)
            {
                chr.EffectsList[Effect.EffectTypes.Peek].StopCharacterEffect();
                return(true);
            }
            else if (chr.IsDead && chr is PC) // if the character is dead and is a player
            {
                Rules.DeadRest(chr as PC);
                return(true);
            }

            if (chr.EffectsList.ContainsKey(Effect.EffectTypes.Ensnare))
            {
                chr.WriteToDisplay("You are ensnared and thus unable to rest properly.");
                return(false);
            }

            foreach (Effect.EffectTypes effectType in chr.CurrentCell.AreaEffects.Keys)
            {
                if (MeditateCommand.NoMedOrRestEffects.Contains(effectType))
                {
                    chr.WriteToDisplay("You find it difficult to meditate in the " + Utils.FormatEnumString(effectType.ToString()) + ".");
                    return(false);
                }
            }

            if (chr.EffectsList.ContainsKey(Effect.EffectTypes.Contagion))
            {
                chr.WriteToDisplay("You are diseased and thus unable to rest properly.");
                return(false);
            }

            if (chr.Poisoned > 0)
            {
                chr.WriteToDisplay("You are poisoned and thus unable to rest properly.");
                return(false);
            }

            System.Collections.Generic.List <string> DisallowedRestCells = new System.Collections.Generic.List <string>()
            {
                GameWorld.Cell.GRAPHIC_OPEN_DOOR_HORIZONTAL, GameWorld.Cell.GRAPHIC_OPEN_DOOR_VERTICAL
            };

            if (GameWorld.Map.IsNextToCounter(chr) ||
                DisallowedRestCells.Contains(chr.CurrentCell.DisplayGraphic) ||
                chr.CurrentCell.IsLair || chr.CurrentCell.IsLocker || chr.CurrentCell.IsOrnicLocker || chr.CurrentCell.IsMapPortal)
            {
                chr.WriteToDisplay("You find it difficult to rest here.");
                return(false);
            }

            chr.CommandType = CommandTasker.CommandType.Rest;

            // character starts to rest
            chr.IsResting    = true;
            chr.IsMeditating = false; // stop meditating

            // Regeneration now takes place in round event if IsResting is true.
            #region Regenerate hits, stamina and mana if not damaged in the last 3 rounds, and not diseased (EffectType.Contagion).
            //if (!chr.EffectsList.ContainsKey(Effect.EffectType.Contagion) && chr.damageRound < DragonsSpineMain.GameRound - 3 && !chr.IsImmortal)
            //{
            //    if (chr.Hits < chr.HitsFull)  // increase stats
            //    {
            //        chr.Hits++;
            //        if (chr.hitsRegen > 0 && chr.Hits < chr.HitsFull) // gain additional mana if hpregen item/effect is active
            //        {
            //            chr.Hits += chr.hitsRegen;
            //            if (chr.Hits > chr.HitsFull) { chr.Hits = chr.HitsFull; } // confirm we didn't regen more hits than we have
            //        }
            //    }
            //    if (chr.Stamina < chr.StaminaFull)
            //    {
            //        chr.Stamina++;
            //        if (chr.staminaRegen > 0 && chr.Stamina < chr.StaminaFull)
            //        {
            //            chr.Stamina += chr.staminaRegen;
            //            if (chr.Stamina > chr.StaminaFull) { chr.Stamina = chr.StaminaFull; } // confirm we didn't regen more stamina than we have
            //        }
            //    }
            //    if (chr.Mana < chr.ManaFull)
            //    {
            //        chr.Mana++;
            //        if (chr.manaRegen > 0 && chr.Mana < chr.ManaFull) // gain additional mana if manaRegeneration item or effect is active
            //        {
            //            chr.Mana += chr.manaRegen;
            //            if (chr.Mana > chr.ManaFull) { chr.Mana = chr.ManaFull; } // confirm we didn't regen more mana than we have
            //        }
            //    }
            //}
            #endregion

            if (!chr.IsPC)
            {
                return(true);
            }                               // end the rest now if this is not a player

            // do a level up if hits and stamina are at max
            #region Level Up Logic -- No NPCs
            if (chr.IsPC && Rules.GetExpLevel(chr.Experience) > chr.Level)
            {
                if (chr.Hits >= chr.HitsFull && chr.Stamina >= chr.StaminaFull)
                {
                    if (!chr.EffectsList.ContainsKey(Effect.EffectTypes.Contagion))
                    {
                        chr.Level += 1;

                        int hitsGain     = Rules.GetHitsGain(chr, 1);    // determine hits gain amount
                        int staminaGain  = Rules.GetStaminaGain(chr, 1); // determine stamina gain amount
                        int hitsLimit    = Rules.GetMaximumHits(chr);    // get hits limit for class type
                        int staminaLimit = Rules.GetMaximumStamina(chr); // get stamina limit for class type

                        // perform adjustments if gain is over limit
                        if (chr.HitsMax + hitsGain > hitsLimit)
                        {
                            hitsGain = hitsLimit - chr.HitsMax;
                        }
                        if (chr.StaminaMax + staminaGain > staminaLimit)
                        {
                            staminaGain = staminaLimit - chr.StaminaMax;
                        }

                        chr.HitsMax    += hitsGain;    // add hitsGain to hitsmax
                        chr.StaminaMax += staminaGain; // add staminaGain to stamina

                        string pts = "point";
                        if (hitsGain != 1)
                        {
                            pts = "points";
                        }
                        chr.WriteToDisplay("You have gained " + hitsGain + " hit " + pts + ".");
                        if (staminaGain != 1)
                        {
                            pts = "points";
                        }
                        else
                        {
                            pts = "point";
                        }
                        chr.WriteToDisplay("You have gained " + staminaGain + " stamina " + pts + ".");

                        #region Mana for spell users
                        if (chr.IsSpellUser && !chr.IsHybrid)
                        {
                            int manaGain  = Rules.GetManaGain(chr, 1);
                            int manaLimit = Rules.GetMaximumMana(chr);

                            if (chr.ManaMax + manaGain > manaLimit)
                            {
                                manaGain = manaLimit - chr.ManaMax;
                            }

                            if (manaGain != 1)
                            {
                                pts = "points";
                            }
                            else
                            {
                                pts = "point";
                            }
                            chr.ManaMax += manaGain;
                            chr.WriteToDisplay("You have gained " + manaGain + " mana " + pts + ".");
                        }
                        #endregion

                        #region Determine strength add based on 15+ strength, classType and level
                        if (chr.Strength >= 15) // add a strength add at appropriate level
                        {
                            int levelAdd = 7;

                            if (chr.IsPureMelee) // melee and hybrid
                            {
                                levelAdd = 5;
                            }
                            else if (chr.IsHybrid)
                            {
                                levelAdd = 6;
                            }

                            for (int a = levelAdd; a <= Globals.MAX_EXP_LEVEL; a += 4)
                            {
                                if (chr.Level == a)
                                {
                                    chr.strengthAdd += 1;
                                    chr.WriteToDisplay("You have gained 1 strength add.");
                                    break;
                                }
                            }
                        }
                        #endregion

                        #region Determine dexterity add based on 15+ dexterity, classType and level
                        if (chr.Dexterity >= 15)
                        {
                            int levelAdd = 7;

                            if (chr.IsPureMelee) // melee and hybrid
                            {
                                levelAdd = 5;
                            }
                            else if (chr.IsHybrid)
                            {
                                levelAdd = 6;
                            }

                            for (int a = levelAdd; a <= Globals.MAX_EXP_LEVEL; a += 4)
                            {
                                if (chr.Level == a)
                                {
                                    chr.dexterityAdd += 1;
                                    chr.WriteToDisplay("You have gained 1 dexterity add.");
                                    break;
                                }
                            }
                        }
                        #endregion

                        chr.SendSound(Sound.GetCommonSound(Sound.CommonSound.LevelUp));

                        chr.WriteToDisplay("You are now a level " + chr.Level + " " + chr.classFullName.ToLower() + "!!");

                        chr.Hits    = chr.HitsFull;
                        chr.Stamina = chr.StaminaFull;
                        chr.Mana    = chr.ManaFull;

                        if (chr is PC && chr.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol)
                        {
                            ProtocolYuusha.SendCharacterStats(chr as PC, chr);
                        }
                    }
                    else
                    {
                        chr.WriteToDisplay("You cannot level up until you remove your contagion.");
                    }
                }
            }
            #endregion

            return(true);
        }
예제 #5
0
        public bool OnCommand(Character chr, string args)
        {
            args = args.TrimEnd();

            bool usingMacro = args.Length == 1 || args.Length == 2;

            if (args == null || args == "" || args.StartsWith("list") || (usingMacro && chr.PCState != Globals.ePlayerState.PLAYING))
            {
                #region No arguments or argument is "list" - display list of macros.
                if ((chr as PC).macros.Count == 0)
                {
                    chr.WriteToDisplay("You do not have any macros set.");
                    return(true);
                }

                string result = "";

                chr.WriteToDisplay("Macros List:");

                int count = 0;
                foreach (string macro in (chr as PC).macros)
                {
                    chr.WriteToDisplay(count + ": " + macro);
                    count++;
                }
                //for (int a = 0; a < (chr as PC).macros.Count; a++)
                //{
                //    string text = (chr as PC).macros[a].ToString();

                //    if(text.Length > 0) // do not display empty macros
                //        result += (a + " = " + (chr as PC).macros[a].ToString() + "\r\n");
                //}

                chr.WriteToDisplay("" + result);

                if (chr.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol)
                {
                    ProtocolYuusha.SendCharacterMacros(chr as PC, chr as PC);
                }
                return(true);

                #endregion
            }

            int macrosIndex = -1;

            if (usingMacro) // using a macro, has to be a macros list index
            {
                if (!Int32.TryParse(args, out macrosIndex))
                {
                    chr.WriteToDisplay("Invalid macro command. View command help for details.");
                    return(true);
                }
            }
            else if (args.IndexOf(" ") >= 1) // setting a macro
            {
                if (!Int32.TryParse(args.Substring(0, args.IndexOf(" ")), out macrosIndex))
                {
                    chr.WriteToDisplay("Invalid macro command. View command help for details.");
                    return(true);
                }
                else
                {
                    args = args.Substring(args.IndexOf(" ") + 1, args.Length - macrosIndex.ToString().Length - 1);
                }
            }
            else
            {
                chr.WriteToDisplay("Invalid macro command. View command help for details.");
                return(true);
            }

            if (macrosIndex >= Character.MAX_MACROS) // 0 through 19
            {
                chr.WriteToDisplay("The current maximum amount of macros is " + Character.MAX_MACROS + ".");
                return(true);
            }
            else if (macrosIndex < 0)
            {
                chr.WriteToDisplay("Invalid macro command. View command help for details.");
                return(true);
            }
            else if (usingMacro && ((chr as PC).macros.Count < macrosIndex + 1 || (chr as PC).macros[macrosIndex].Length < 1))
            {
                chr.WriteToDisplay("Macro " + macrosIndex + " is not set.");
                return(true);
            }

            try
            {
                if (usingMacro)
                {
                    if ((chr as PC).macros[macrosIndex].ToString().IndexOf(" ") != -1)
                    {
                        string command = (chr as PC).macros[macrosIndex].ToString().Substring(0, (chr as PC).macros[macrosIndex].ToString().IndexOf(" "));
                        string newArgs = (chr as PC).macros[macrosIndex].ToString().Substring((chr as PC).macros[macrosIndex].ToString().IndexOf(" ") + 1);
                        return(CommandTasker.ParseCommand(chr, command, newArgs));
                    }
                    else
                    {
                        return(CommandTasker.ParseCommand(chr, (chr as PC).macros[macrosIndex].ToString(), ""));
                    }
                }
                else
                {
                    if (args.IndexOf(ProtocolYuusha.ISPLIT) != -1)
                    {
                        chr.WriteToDisplay("Your macro contains an illegal character. The character " + ProtocolYuusha.ISPLIT + " is reserved.");
                        return(true);
                    }

                    if ((chr as PC).macros.Count >= macrosIndex + 1)
                    {
                        (chr as PC).macros[macrosIndex] = args;

                        if (chr.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol)
                        {
                            ProtocolYuusha.SendCharacterMacros(chr as PC, chr as PC);
                        }

                        chr.WriteToDisplay("Macro " + macrosIndex + " has been set to \"" + args + "\".");
                    }
                    else
                    {
                        (chr as PC).macros.Add(args);

                        if (chr.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol)
                        {
                            ProtocolYuusha.SendCharacterMacros(chr as PC, chr as PC);
                        }

                        chr.WriteToDisplay("Macro " + macrosIndex + " has been set to \"" + args + "\".");
                    }
                }

                return(true);
            }
            catch (Exception e)
            {
                Utils.LogException(e);
                return(true);
            }
        }
예제 #6
0
        public void FinishStep(NPC questGiver, PC questor, int step)
        {
            try
            {
                // precautionary
                if (step <= 0)
                {
                    step = 1;
                }

                // flag check
                if (!PlayerMeetsRequirements(questor, true))
                {
                    return;
                }

                // make the quest giver stand still for a period of time to conclude interaction
                if (questGiver != null)
                {
                    Effect.CreateCharacterEffect(Effect.EffectTypes.Hello_Immobility, 0, questGiver, Rules.RollD(5, 6), null);
                }

                // the quest giver tells the player that the quest is complete
                if (this.FinishStrings.ContainsKey(step))
                {
                    if (questGiver != null)
                    {
                        string emote  = Utils.ParseEmote(this.FinishStrings[step]);
                        string finish = this.FinishStrings[step];
                        if (emote != "")
                        {
                            finish = finish.Replace("{" + emote + "}", "");
                            questor.WriteToDisplay(questGiver.Name + " " + emote);
                        }
                        if (finish.Length > 0)
                        {
                            questor.WriteToDisplay(questGiver.Name + ": " + finish);
                        }
                    }
                    else
                    {
                        questor.WriteToDisplay(this.FinishStrings[step]);
                    }
                }

                // play quest sound file if applicable
                if (this.SoundFiles.ContainsKey(step))
                {
                    if (questGiver != null)
                    {
                        questGiver.EmitSound(this.SoundFiles[step]);
                    }
                    else
                    {
                        questor.CurrentCell.EmitSound(this.SoundFiles[step]);
                    }
                }

                // give reward title
                if (this.RewardTitle != "")
                {
                    string[] s = this.RewardTitle.Split(VSPLIT.ToCharArray());
                    if (s.Length > 0 && Convert.ToInt16(s[0]) == this.CurrentStep)
                    {
                        string oldTitle = questor.classFullName; // store old title
                        questor.classFullName = s[1];
                        questor.WriteToDisplay("Your title has been changed from " + oldTitle + " to " + questor.classFullName + ".");
                    }
                }

                // give reward class
                if (this.RewardClass != "")
                {
                    string[] s = this.RewardClass.Split(VSPLIT.ToCharArray());

                    if (s.Length > 0 && Convert.ToInt16(s[0]) == this.CurrentStep)
                    {
                        string oldClass   = "";
                        bool   classMatch = false;
                        foreach (Character.ClassType classType in Enum.GetValues(typeof(Character.ClassType)))
                        {
                            if (classType.ToString().ToLower() == s[1].ToLower())
                            {
                                oldClass = questor.BaseProfession.ToString(); // store old class
                                questor.BaseProfession = (Character.ClassType)Enum.Parse(typeof(Character.ClassType), s[1], true);
                                questor.classFullName  = Utils.FormatEnumString(questor.BaseProfession.ToString());
                                questor.WriteToDisplay("Your profession has been changed from " + oldClass + " to " + questor.BaseProfession.ToString() + ".");
                                if (questor.protocol == DragonsSpineMain.Instance.Settings.DefaultProtocol)
                                {
                                    ProtocolYuusha.SendCharacterStats(questor, questor);
                                }
                                classMatch = true;
                                break;
                            }
                        }

                        if (!classMatch)
                        {
                            // search subclasses here for a match then change subclass... TODO
                        }
                    }
                }

                // give reward item
                if (this.RewardItems.ContainsKey(step))
                {
                    Item reward = Item.CopyItemFromDictionary(this.RewardItems[step]);

                    if (reward != null)
                    {
                        if (this.CoinValues.ContainsKey(step)) // set coin value of reward if necessary
                        {
                            reward.coinValue = this.CoinValues[step];
                        }

                        if (reward.attuneType == Globals.eAttuneType.Quest)
                        {
                            reward.AttuneItem(questor);
                        }
                        if (reward.coinValue == 0 && reward.vRandLow > 0) //mlt fix worthless gem reward v
                        {
                            reward.coinValue = Rules.Dice.Next(reward.vRandLow, reward.vRandHigh);
                        }                                                                                     //mlt^
                        questor.EquipEitherHandOrDrop(reward);
                    }

                    if (this.TotalSteps == 1 && this.RewardItems.Count > 1) // used for simple escort quests with multiple rewards
                    {
                        foreach (short s in this.RewardItems.Keys)
                        {
                            if (s > 1) // already rewarded the first item
                            {
                                reward = Item.CopyItemFromDictionary(this.RewardItems[s]);
                                if (reward != null)
                                {
                                    if (this.CoinValues.ContainsKey(s)) // set coin value of reward if necessary
                                    {
                                        reward.coinValue = this.CoinValues[s];
                                    }
                                    if (reward.coinValue == 0 && reward.vRandLow > 0) //mlt fix worthless gem reward v
                                    {
                                        reward.coinValue = Rules.Dice.Next(reward.vRandLow, reward.vRandHigh);
                                    }                                                                                //mlt ^
                                    if (reward.attuneType == Globals.eAttuneType.Quest)
                                    {
                                        reward.AttuneItem(questor);
                                    }

                                    questor.EquipEitherHandOrDrop(reward);
                                }
                            }
                        }
                    }
                }

                // give quest flag
                if (this.RewardFlags.ContainsKey(step))
                {
                    if (!questor.QuestFlags.Contains(this.RewardFlags[step]))
                    {
                        questor.QuestFlags.Add(this.RewardFlags[step]);
                        if (this.RewardFlags[step].IndexOf("_C") != -1) // add a permanent content flag
                        {
                            // remove the _C at the end of the flag
                            questor.ContentFlags.Add(this.RewardFlags[step].Substring(0, this.RewardFlags[step].IndexOf("_C")));
                        }
                        //questor.WriteToDisplay("You have received a quest flag!");
                    }
                }

                // give quest experience
                if (this.RewardExperience.ContainsKey(step))
                {
                    long expGain = this.RewardExperience[step];

                    // Accelerated experience gain option.
                    if (DragonsSpineMain.Instance.Settings.AcceleratedExperienceGain)
                    {
                        expGain = Convert.ToInt64(expGain * DragonsSpineMain.Instance.Settings.AcceleratedExperienceGainMultiplier);
                    }

                    questor.WriteToDisplay("You earn " + expGain + " experience.");

                    questor.Experience += expGain;
                }

                // give reward stats
                if (this.RewardStats.ContainsKey(step))
                {
                    // Stats: stat #
                    // Talent:
                    // TODO: Faction: faction # #

                    string[] stat = this.RewardStats[step].Split(ASPLIT.ToCharArray());

                    switch (stat[0].ToLower())
                    {
                    case "h":
                        questor.HitsAdjustment += Convert.ToInt32(stat[1]);
                        questor.WriteToDisplay("Your maximum hits have increased by " + Convert.ToInt32(stat[1]) + ".");
                        questor.Hits = questor.HitsFull;
                        break;

                    case "s":
                        questor.StaminaAdjustment += Convert.ToInt32(stat[1]);
                        questor.WriteToDisplay("Your maximum stamina has increased by " + Convert.ToInt32(stat[1]) + ".");
                        questor.Stamina = questor.StaminaFull;
                        break;

                    case "m":
                        questor.ManaAdjustment += Convert.ToInt32(stat[1]);
                        questor.WriteToDisplay("Your maximum mana has increased by " + Convert.ToInt32(stat[1]) + ".");
                        questor.Mana = questor.ManaFull;
                        break;

                    case "q":
                        questor.UW_hasStomach = true;
                        questor.WriteToDisplay("You have gained your stomach!");
                        break;

                    case "w":
                        questor.UW_hasIntestines = true;
                        questor.WriteToDisplay("You have gained your intestines!");
                        break;

                    case "e":
                        questor.UW_hasLiver = true;
                        questor.WriteToDisplay("You have gained your liver!");
                        break;

                    case "r":
                        questor.UW_hasLungs = true;
                        questor.WriteToDisplay("You have gained your lungs!");
                        break;

                    case "t":
                    case "tal":
                    case "talent":
                        DragonsSpine.Talents.GameTalent talent = null;
                        foreach (string tSearch in DragonsSpine.Talents.GameTalent.GameTalentDictionary.Keys)
                        {
                            if (tSearch == stat[1])
                            {
                                talent = DragonsSpine.Talents.GameTalent.GameTalentDictionary[tSearch];
                                break;
                            }
                        }

                        if (talent != null)
                        {
                            questor.talentsDictionary.Add(talent.Command, DateTime.Now - talent.DownTime);
                            questor.WriteToDisplay(questGiver.GetNameForActionResult() + " teaches you how to perform " + talent.Description.ToLower());
                            DAL.DBPlayer.InsertPlayerTalent(questor.UniqueID, talent.Command);
                        }
                        break;

                    default:
                        // TODO: add faction here
                        break;
                    }
                }

                // reward teleport
                if (this.RewardTeleports.ContainsKey(step))
                {
                    string[] coords = this.RewardTeleports[step].Split(",".ToCharArray());
                    questor.CurrentCell = GameWorld.Cell.GetCell(questor.FacetID, Convert.ToInt16(coords[0]), Convert.ToInt16(coords[1]),
                                                                 Convert.ToInt32(coords[2]), Convert.ToInt32(coords[3]), Convert.ToInt32(coords[4]));

                    if (coords.Length >= 6 && coords[5].Length > 0)
                    {
                        questor.WriteToDisplay(coords[5]);
                    }

                    // teleport the group with the questor
                    if (this.TeleportGroup && questor.Group != null)
                    {
                        string reason = "";
                        if (coords.Length >= 6 && coords[5].Length > 1)
                        {
                            reason = coords[5];
                        }
                        questor.Group.TeleportGroup(questor, questor.CurrentCell, reason);
                    }
                }

                if (!this.CompletedSteps.Contains(this.CurrentStep))
                {
                    this.CompletedSteps.Add(this.CurrentStep);
                }

                if (this.TotalSteps > this.CurrentStep)
                {
                    this.CurrentStep++;
                    // log the quest step completion
                    Utils.Log(this.GetLogString() + ", quest step " + step + ", was completed by " + questor.GetLogString(), Utils.LogType.QuestCompletion);
                }

                if (this.CurrentStep >= this.TotalSteps || this.TotalSteps == 1)
                {
                    this.CompleteQuest(questor);

                    if (this.DespawnsNPC)
                    {
                        NPC npc = (NPC)questGiver;
                        npc.RoundsRemaining = 0;
                        npc.special         = npc.special + " despawn";
                        //npc.special += " despawn";
                    }
                }
            }
            catch (Exception e)
            {
                Utils.LogException(e);
            }
        }