/// <summary> /// Delve a Style handled by this processor /// </summary> /// <param name="delveInfo"></param> /// <param name="style"></param> /// <param name="player"></param> public static void DelveWeaponStyle(IList<string> delveInfo, Style style, GamePlayer player) { delveInfo.Add(LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.WeaponType", style.GetRequiredWeaponName())); string temp = LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Opening") + " "; if (Style.eOpening.Offensive == style.OpeningRequirementType) { //attacker action result is opening switch (style.AttackResultRequirement) { case Style.eAttackResult.Hit: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.YouHit"); break; case Style.eAttackResult.Miss: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.YouMiss"); break; case Style.eAttackResult.Parry: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.TargetParrys"); break; case Style.eAttackResult.Block: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.TargetBlocks"); break; case Style.eAttackResult.Evade: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.TargetEvades"); break; case Style.eAttackResult.Fumble: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.YouFumble"); break; case Style.eAttackResult.Style: Style reqStyle = SkillBase.GetStyleByID(style.OpeningRequirementValue, player.CharacterClass.ID); if (reqStyle == null) { reqStyle = SkillBase.GetStyleByID(style.OpeningRequirementValue, 0); } temp = LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.OpeningStyle") + " "; if (reqStyle == null) { temp += "(style not found " + style.OpeningRequirementValue + ")"; } else { temp += reqStyle.Name; } break; default: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Any"); break; } } else if (Style.eOpening.Defensive == style.OpeningRequirementType) { //defender action result is opening switch (style.AttackResultRequirement) { case Style.eAttackResult.Miss: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.TargetMisses"); break; case Style.eAttackResult.Hit: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.TargetHits"); break; case Style.eAttackResult.Parry: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.YouParry"); break; case Style.eAttackResult.Block: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.YouBlock"); break; case Style.eAttackResult.Evade: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.YouEvade"); break; case Style.eAttackResult.Fumble: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.TargetFumbles"); break; case Style.eAttackResult.Style: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.TargetStyle"); break; default: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Any"); break; } } else if (Style.eOpening.Positional == style.OpeningRequirementType) { //attacker position to target is opening temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Positional"); switch (style.OpeningRequirementValue) { case (int)Style.eOpeningPosition.Front: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Front"); break; case (int)Style.eOpeningPosition.Back: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Back"); break; case (int)Style.eOpeningPosition.Side: temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Side"); break; } } delveInfo.Add(temp); if (style.OpeningRequirementValue != 0 && style.AttackResultRequirement == 0 && style.OpeningRequirementType == 0) { delveInfo.Add(string.Format("- Error: Opening Requirement '{0}' but requirement type is Any!", style.OpeningRequirementValue)); } temp = ""; foreach (Style st in SkillBase.GetStyleList(style.Spec, player.CharacterClass.ID)) { if (st.AttackResultRequirement == Style.eAttackResult.Style && st.OpeningRequirementValue == style.ID) { temp = (temp == "" ? st.Name : temp + LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Or", st.Name)); } } if (temp == "") { foreach (Style st in player.GetChampionStyleList()) { if (st.AttackResultRequirement == Style.eAttackResult.Style && st.OpeningRequirementValue == style.ID) { temp = (temp == "" ? st.Name : temp + LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Or", st.Name)); } } } if (temp != "") { delveInfo.Add(LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.FollowupStyle", temp)); } temp = LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.FatigueCost") + " "; if (style.EnduranceCost < 5) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryLow"); else if (style.EnduranceCost < 10) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Low"); else if (style.EnduranceCost < 15) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Medium"); else if (style.EnduranceCost < 20) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.High"); else temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryHigh"); delveInfo.Add(temp); temp = LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Damage") + " "; if (style.GrowthRate == 0) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.NoBonus"); else if (style.GrowthRate < .1) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryLow"); else if (style.GrowthRate < .25) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Low"); else if (style.GrowthRate < .5) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Medium"); else if (style.GrowthRate < 1.0) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.High"); else temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryHigh"); temp += " (" + style.GrowthRate + ")"; delveInfo.Add(temp); temp = LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.ToHit") + " "; if (style.BonusToHit <= -20) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryHighPenalty"); else if (style.BonusToHit <= -15) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.HighPenalty"); else if (style.BonusToHit <= -10) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.MediumPenalty"); else if (style.BonusToHit <= -5) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.LowPenalty"); else if (style.BonusToHit < 0) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryLowPenalty"); else if (style.BonusToHit == 0) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.NoBonus"); else if (style.BonusToHit < 5) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryLowBonus"); else if (style.BonusToHit < 10) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.LowBonus"); else if (style.BonusToHit < 15) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.MediumBonus"); else if (style.BonusToHit < 20) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.HighBonus"); else temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryHighBonus"); delveInfo.Add(temp); temp = LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.Defense") + " "; if (style.BonusToDefense <= -20) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryHighPenalty"); else if (style.BonusToDefense <= -15) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.HighPenalty"); else if (style.BonusToDefense <= -10) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.MediumPenalty"); else if (style.BonusToDefense <= -5) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.LowPenalty"); else if (style.BonusToDefense < 0) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryLowPenalty"); else if (style.BonusToDefense == 0) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.NoBonus"); else if (style.BonusToDefense < 5) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryLowBonus"); else if (style.BonusToDefense < 10) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.LowBonus"); else if (style.BonusToDefense < 15) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.MediumBonus"); else if (style.BonusToDefense < 20) temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.HighBonus"); else temp += LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.VeryHighBonus"); delveInfo.Add(temp); if (style.Procs.Count > 0) { temp = LanguageMgr.GetTranslation(player.Client, "DetailDisplayHandler.HandlePacket.TargetEffect") + " "; SpellLine styleLine = SkillBase.GetSpellLine(GlobalSpellsLines.Combat_Styles_Effect); if (styleLine != null) { foreach (DBStyleXSpell proc in style.Procs) { // RR4: we added all the procs to the style, now it's time to check for class ID if (proc.ClassID != 0 && proc.ClassID != player.CharacterClass.ID) continue; Spell spell = SkillBase.GetSpellByID(proc.SpellID); if (spell != null) { ISpellHandler spellHandler = ScriptMgr.CreateSpellHandler(player.Client.Player, spell, styleLine); if (spellHandler == null) { temp += spell.Name + " (Not implemented yet)"; delveInfo.Add(temp); } else { temp += spell.Name; delveInfo.Add(temp); delveInfo.Add(" ");//empty line delveInfo.AddRange(spellHandler.DelveInfo); } } } } } if (player.Client.Account.PrivLevel > 1) { delveInfo.Add(" "); delveInfo.Add("--- Style Technical Information ---"); delveInfo.Add(" "); delveInfo.Add(string.Format("ID: {0}", style.ID)); delveInfo.Add(string.Format("ClassID: {0}", style.ClassID)); delveInfo.Add(string.Format("Icon: {0}", style.Icon)); delveInfo.Add(string.Format("TwoHandAnimation: {0}", style.TwoHandAnimation)); delveInfo.Add(string.Format("Spec: {0}", style.Spec)); delveInfo.Add(string.Format("SpecLevelRequirement: {0}", style.SpecLevelRequirement)); delveInfo.Add(string.Format("Level: {0}", style.Level)); delveInfo.Add(string.Format("GrowthRate: {0}", style.GrowthRate)); delveInfo.Add(string.Format("Endurance: {0}", style.EnduranceCost)); delveInfo.Add(string.Format("StealthRequirement: {0}", style.StealthRequirement)); delveInfo.Add(string.Format("WeaponTypeRequirement: {0}", style.WeaponTypeRequirement)); string indicator = ""; if (style.OpeningRequirementValue != 0 && style.AttackResultRequirement == 0 && style.OpeningRequirementType == 0) { indicator = "!!"; } delveInfo.Add(string.Format("AttackResultRequirement: {0}({1}) {2}", style.AttackResultRequirement, (int)style.AttackResultRequirement, indicator)); delveInfo.Add(string.Format("OpeningRequirementType: {0}({1}) {2}", style.OpeningRequirementType, (int)style.OpeningRequirementType, indicator)); delveInfo.Add(string.Format("OpeningRequirementValue: {0}", style.OpeningRequirementValue)); delveInfo.Add(string.Format("ArmorHitLocation: {0}({1})", style.ArmorHitLocation, (int)style.ArmorHitLocation)); delveInfo.Add(string.Format("BonusToDefense: {0}", style.BonusToDefense)); delveInfo.Add(string.Format("BonusToHit: {0}", style.BonusToHit)); if (style.Procs != null && style.Procs.Count > 0) { delveInfo.Add(" "); string procs = ""; foreach (DBStyleXSpell spell in style.Procs) { if (procs != "") procs += ", "; procs += spell.SpellID; } delveInfo.Add(string.Format("Procs: {0}", procs)); delveInfo.Add(string.Format("RandomProc: {0}", style.RandomProc)); } } }
/// <summary> /// Tries to queue a new style in the player's style queue. /// Takes care of all conditions like setting backup styles and /// canceling styles if the style was queued already. /// </summary> /// <param name="living">The living to execute the style</param> /// <param name="style">The style to execute</param> public static void TryToUseStyle(GameLiving living, Style style) { //First thing in processors, lock the objects you modify //This way it makes sure the objects are not modified by //several different threads at the same time! GamePlayer player = living as GamePlayer; lock (living) { //Dead players can't use styles if (!living.IsAlive) { if (player != null) player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.CantCombatMode"), eChatType.CT_YouHit, eChatLoc.CL_SystemWindow); return; } if (living.IsDisarmed) { if(living is GamePlayer) (living as GamePlayer).Out.SendMessage("You are disarmed and cannot attack!", eChatType.CT_YouHit, eChatLoc.CL_SystemWindow); return; } //Can't use styles with range weapon if (living.ActiveWeaponSlot == GameLiving.eActiveWeaponSlot.Distance) { if (player != null) player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.CantMeleeCombat"), eChatType.CT_YouHit, eChatLoc.CL_SystemWindow); return; } //Put player into attack state before setting the styles //Changing the attack state clears out the styles... if (living.AttackState == false) { living.StartAttack(player.TargetObject); } if (living.TargetObject == null) { if (player != null) player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.MustHaveTarget"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } InventoryItem weapon = (style.WeaponTypeRequirement == (int)eObjectType.Shield) ? living.Inventory.GetItem(eInventorySlot.LeftHandWeapon) : living.AttackWeapon; // if (weapon == null) return; // no weapon = no style if (!CheckWeaponType(style, living, weapon)) { if (player != null) { if (style.WeaponTypeRequirement == Style.SpecialWeaponType.DualWield) player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.DualWielding"), eChatType.CT_System, eChatLoc.CL_SystemWindow); else player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.StyleRequires", style.GetRequiredWeaponName()), eChatType.CT_System, eChatLoc.CL_SystemWindow); } return; } if (player != null) //Do mob use endurance? { int fatCost = CalculateEnduranceCost(player, style, weapon.SPD_ABS); if (player.Endurance < fatCost) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.Fatigued"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } } if (player != null) { Style preRequireStyle = null; if (style.OpeningRequirementType == Style.eOpening.Offensive && style.AttackResultRequirement == Style.eAttackResult.Style) preRequireStyle = SkillBase.GetStyleByID(style.OpeningRequirementValue, player.CharacterClass.ID); //We have not set any primary style yet? if (player.NextCombatStyle == null) { if (preRequireStyle != null) { AttackData lastAD = (AttackData)living.TempProperties.getProperty<object>(GameLiving.LAST_ATTACK_DATA, null); if (lastAD == null || lastAD.AttackResult != GameLiving.eAttackResult.HitStyle || lastAD.Style == null || lastAD.Style.ID != style.OpeningRequirementValue) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.PerformStyleBefore", preRequireStyle.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } } player.NextCombatStyle = style; player.NextCombatBackupStyle = null; player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.PreparePerform", style.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); if (living.IsEngaging) { // cancel engage effect if exist EngageEffect effect = living.EffectList.GetOfType<EngageEffect>(); if (effect != null) effect.Cancel(false); } // unstealth only on primary style to not break // stealth with non-stealth backup styles if (!style.StealthRequirement) player.Stealth(false); } else { //Have we also set the backupstyle already? if (player.NextCombatBackupStyle != null) { //All styles set, can't change anything now player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.AlreadySelectedStyles"), eChatType.CT_System, eChatLoc.CL_SystemWindow); } else { //Have we pressed the same style button used for the primary style again? if (player.NextCombatStyle.ID == style.ID) { if (player.CancelStyle) { //If yes, we cancel the style player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.NoLongerPreparing", player.NextCombatStyle.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); player.NextCombatStyle = null; player.NextCombatBackupStyle = null; } else { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.AlreadyPreparing"), eChatType.CT_System, eChatLoc.CL_SystemWindow); } } else { if (preRequireStyle != null) { AttackData lastAD = (AttackData)living.TempProperties.getProperty<object>(GameLiving.LAST_ATTACK_DATA, null); if (lastAD == null || lastAD.AttackResult != GameLiving.eAttackResult.HitStyle || lastAD.Style == null || lastAD.Style.ID != style.OpeningRequirementValue) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.PerformStyleBefore", preRequireStyle.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } } //If no, set the secondary backup style player.NextCombatBackupStyle = style; player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "StyleProcessor.TryToUseStyle.BackupStyle", style.Name, player.NextCombatStyle.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); } } } } } }