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