/// <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); }
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); }
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); }
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); }
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); } }
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); } }