diff --git a/zone/aura.cpp b/zone/aura.cpp index 5d13acff2..e4f88514b 100644 --- a/zone/aura.cpp +++ b/zone/aura.cpp @@ -80,7 +80,7 @@ void Aura::ProcessOnAllFriendlies(Mob *owner) if (!mob) { continue; } - if (mob->IsClient() || mob->IsPetOwnerClient() || mob->IsMerc()) { + if (mob->IsClient() || mob->IsPetOwnerClient() || mob->IsMerc() || mob->IsBot()) { auto it = casted_on.find(mob->GetID()); if (it != casted_on.end()) { // we are already on the list, let's check for removal diff --git a/zone/bot.cpp b/zone/bot.cpp index 6cc376042..c961e37c6 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -5320,11 +5320,6 @@ void Bot::Damage(Mob *from, int64 damage, uint16 spell_id, EQ::skills::SkillType } } -//void Bot::AddToHateList(Mob* other, int64 hate = 0, int64 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false) -void Bot::AddToHateList(Mob* other, int64 hate, int64 damage, bool iYellForHelp, bool bFrenzy, bool iBuffTic, bool pet_command) { - Mob::AddToHateList(other, hate, damage, iYellForHelp, bFrenzy, iBuffTic, pet_command); -} - bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts) { if (!other) { SetTarget(nullptr); @@ -6134,20 +6129,6 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) { classattack_timer.Start(reuse / HasteModifier); } -int32 Bot::CheckAggroAmount(uint16 spellid) { - int32 AggroAmount = Mob::CheckAggroAmount(spellid, nullptr); - int64 focusAggro = GetFocusEffect(focusSpellHateMod, spellid); - AggroAmount = (AggroAmount * (100 + focusAggro) / 100); - return AggroAmount; -} - -int32 Bot::CheckHealAggroAmount(uint16 spellid, Mob *target, uint32 heal_possible) { - int32 AggroAmount = Mob::CheckHealAggroAmount(spellid, target, heal_possible); - int64 focusAggro = GetFocusEffect(focusSpellHateMod, spellid); - AggroAmount = (AggroAmount * (100 + focusAggro) / 100); - return AggroAmount; -} - void Bot::MakePet(uint16 spell_id, const char* pettype, const char *petname) { Mob::MakePet(spell_id, pettype, petname); } @@ -6415,276 +6396,6 @@ void Bot::SetAttackTimer() { } } -int64 Bot::GetActSpellHealing(uint16 spell_id, int64 value, Mob* target) { - if (target == nullptr) - target = this; - - int64 base_value = value; - int16 critical_chance = 0; - int8 critical_modifier = 1; - - if (spells[spell_id].buff_duration < 1) { - critical_chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance; - - if (spellbonuses.CriticalHealDecay) { - critical_chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay); - } - } - else { - critical_chance = itembonuses.CriticalHealOverTime + spellbonuses.CriticalHealOverTime + aabonuses.CriticalHealOverTime; - - if (spellbonuses.CriticalRegenDecay) { - critical_chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay); - } - } - - if (critical_chance) { - - if (spells[spell_id].override_crit_chance > 0 && critical_chance > spells[spell_id].override_crit_chance) { - critical_chance = spells[spell_id].override_crit_chance; - } - - if (zone->random.Roll(critical_chance)) { - critical_modifier = 2; //At present time no critical heal amount modifier SPA exists. - } - } - - if (GetClass() == CLERIC) { - value += int(base_value*RuleI(Spells, ClericInnateHealFocus) / 100); //confirmed on live parsing clerics get an innate 5 pct heal focus - } - value += int(base_value*GetFocusEffect(focusImprovedHeal, spell_id) / 100); - value += int(base_value*GetFocusEffect(focusFcAmplifyMod, spell_id) / 100); - - // Instant Heals - if (spells[spell_id].buff_duration < 1) { - - /* Mob::GetFocusEffect is not accessible from this context. This focus effect was not accounted for in previous version of this method at all, either - if (target) { - value += int(base_value * target->GetFocusEffect(focusFcHealPctIncoming, spell_id, this)/100,nullptr); //SPA 393 Add before critical - value += int(base_value * target->GetFocusEffect(focusFcHealPctCritIncoming, spell_id, this)/100,nullptr); //SPA 395 Add before critical (?) - } - */ - - value += GetFocusEffect(focusFcHealAmtCrit, spell_id); //SPA 396 Add before critical - - //Using IgnoreSpellDmgLvlRestriction to also allow healing to scale - if ((RuleB(Spells, IgnoreSpellDmgLvlRestriction) || spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt) { - value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, base_value);//Item Heal Amt Add before critical - } - - if (target) { - value += value * target->GetHealRate() / 100; //SPA 120 modifies value after Focus Applied but before critical - } - - /* - Apply critical hit modifier - */ - - value *= critical_modifier; - value += GetFocusEffect(focusFcHealAmt, spell_id); //SPA 392 Add after critical - value += GetFocusEffect(focusFcAmplifyAmt, spell_id); //SPA 508 ? Add after critical - - - if (critical_modifier > 1) { - entity_list.MessageCloseString( - this, true, 100, Chat::SpellCrit, - OTHER_CRIT_HEAL, GetName(), itoa(value)); - } - - return value; - } - - //Heal over time spells. [Heal Rate and Additional Healing effects do not increase this value] - else { - //Using IgnoreSpellDmgLvlRestriction to also allow healing to scale - if (RuleB(Spells, HOTsScaleWithHealAmt)) { - int duration = CalcBuffDuration(this, target, spell_id); - int32 extra_heal = 0; - if ((RuleB(Spells, IgnoreSpellDmgLvlRestriction) || spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt) { - extra_heal += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, base_value); - } - - if (duration > 0 && extra_heal > 0) { - extra_heal /= duration; - value += extra_heal; - } - } - - if (critical_chance && zone->random.Roll(critical_chance)) - value *= critical_modifier; - } - - return value; -} - -int32 Bot::GetActSpellCasttime(uint16 spell_id, int32 casttime) { - int64 cast_reducer = GetFocusEffect(focusSpellHaste, spell_id); - auto min_cap = casttime / 2; - uint8 botlevel = GetLevel(); - uint8 botclass = GetClass(); - if (botlevel >= 51 && casttime >= 3000 && !spells[spell_id].good_effect && - (botclass == SHADOWKNIGHT || botclass == RANGER || botclass == PALADIN || botclass == BEASTLORD)) { - int level_mod = std::min(15, botlevel - 50); - cast_reducer += level_mod * 3; - } - - if((casttime >= 4000) && BeneficialSpell(spell_id) && IsBuffSpell(spell_id)) { - switch (GetAA(aaSpellCastingDeftness)) { - case 1: - cast_reducer += 5; - break; - case 2: - cast_reducer += 10; - break; - case 3: - cast_reducer += 25; - break; - } - - switch (GetAA(aaQuickBuff)) { - case 1: - cast_reducer += 10; - break; - case 2: - cast_reducer += 25; - break; - case 3: - cast_reducer += 50; - break; - } - } - - if(IsSummonSpell(spell_id)) { - switch (GetAA(aaQuickSummoning)) { - case 1: - cast_reducer += 10; - break; - case 2: - cast_reducer += 25; - break; - case 3: - cast_reducer += 50; - break; - } - } - - if(IsEvacSpell(spell_id)) { - switch (GetAA(aaQuickEvacuation)) { - case 1: - cast_reducer += 10; - break; - case 2: - cast_reducer += 25; - break; - case 3: - cast_reducer += 50; - break; - } - } - - if(IsDamageSpell(spell_id) && spells[spell_id].cast_time >= 4000) { - switch (GetAA(aaQuickDamage)) { - case 1: - cast_reducer += 2; - break; - case 2: - cast_reducer += 5; - break; - case 3: - cast_reducer += 10; - break; - } - } - - casttime = casttime * (100 - cast_reducer) / 100; - return std::max(casttime, min_cap); -} - -int32 Bot::GetActSpellCost(uint16 spell_id, int32 cost) { - if(itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) { - int32 mana_back = (itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100); - if(mana_back > cost) - mana_back = cost; - - cost -= mana_back; - } - - float PercentManaReduction = 0; - float SpecializeSkill = GetSpecializeSkillValue(spell_id); - int SuccessChance = zone->random.Int(0, 100); - float bonus = 1.0; - switch(GetAA(aaSpellCastingMastery)) { - case 1: - bonus += 0.05; - break; - case 2: - bonus += 0.15; - break; - case 3: - bonus += 0.30; - break; - } - - bonus += (0.05 * GetAA(aaAdvancedSpellCastingMastery)); - - if(SuccessChance <= (SpecializeSkill * 0.3 * bonus)) { - PercentManaReduction = (1 + 0.05 * SpecializeSkill); - switch(GetAA(aaSpellCastingMastery)) { - case 1: - PercentManaReduction += 2.5; - break; - case 2: - PercentManaReduction += 5.0; - break; - case 3: - PercentManaReduction += 10.0; - break; - } - - switch(GetAA(aaAdvancedSpellCastingMastery)) { - case 1: - PercentManaReduction += 2.5; - break; - case 2: - PercentManaReduction += 5.0; - break; - case 3: - PercentManaReduction += 10.0; - break; - } - } - - int64 focus_redux = GetFocusEffect(focusManaCost, spell_id); - - if(focus_redux > 0) - PercentManaReduction += zone->random.Real(1, (double)focus_redux); - - cost -= (cost * (PercentManaReduction / 100)); - if(focus_redux >= 100) { - uint32 buff_max = GetMaxTotalSlots(); - for (int buffSlot = 0; buffSlot < buff_max; buffSlot++) { - if (buffs[buffSlot].spellid == 0 || buffs[buffSlot].spellid >= SPDAT_RECORDS) - continue; - - if(IsEffectInSpell(buffs[buffSlot].spellid, SE_ReduceManaCost)) { - if(CalcFocusEffect(focusManaCost, buffs[buffSlot].spellid, spell_id) == 100) - cost = 1; - } - } - } - - if(cost < 0) - cost = 0; - - return cost; -} - -float Bot::GetActSpellRange(uint16 spell_id, float range) { - float extrange = 100; - extrange += GetFocusEffect(focusRange, spell_id); - return ((range * extrange) / 100); -} - int32 Bot::GetActSpellDuration(uint16 spell_id, int32 duration) { int increase = 100; increase += GetFocusEffect(focusSpellDuration, spell_id); diff --git a/zone/bot.h b/zone/bot.h index 77138436c..e13d8e97c 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -144,15 +144,17 @@ public: Bot(NPCType *npcTypeData, Client* botOwner); Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType *npcTypeData); - //abstract virtual function implementations requird by base abstract class - virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill); - virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None); - virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, - ExtraAttackOptions *opts = nullptr); - virtual bool HasRaid() { return (GetRaid() ? true : false); } - virtual bool HasGroup() { return (GetGroup() ? true : false); } - virtual Raid* GetRaid() { return entity_list.GetRaidByMob(this); } - virtual Group* GetGroup() { return entity_list.GetGroupByMob(this); } + //abstract virtual override function implementations requird by base abstract class + bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) override; + void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, + bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) override; + + bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false, + ExtraAttackOptions *opts = nullptr) override; + bool HasRaid() override { return (GetRaid() ? true : false); } + bool HasGroup() override { return (GetGroup() ? true : false); } + Raid* GetRaid() override { return entity_list.GetRaidByMob(this); } + Group* GetGroup() override { return entity_list.GetGroupByMob(this); } // Common, but informal "interfaces" with Client object uint32 CharacterID() { return GetBotID(); } // Just returns the Bot Id @@ -167,71 +169,68 @@ public: bool IsValidName(); static bool IsValidName(std::string& name); bool Spawn(Client* botCharacterOwner); - virtual void SetLevel(uint8 in_level, bool command = false); - virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); - virtual bool Process(); + void SetLevel(uint8 in_level, bool command = false) override; + void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) override; + bool Process() override; void FinishTrade(Client* client, BotTradeType trade_type); - virtual bool Save(); - virtual void Depop(); + bool Save() override; + void Depop(); void CalcBotStats(bool showtext = true); uint16 BotGetSpells(int spellslot) { return AIBot_spells[spellslot].spellid; } uint32 BotGetSpellType(int spellslot) { return AIBot_spells[spellslot].type; } uint16 BotGetSpellPriority(int spellslot) { return AIBot_spells[spellslot].priority; } - virtual float GetProcChances(float ProcBonus, uint16 hand); - virtual int GetHandToHandDamage(void); - virtual bool TryFinishingBlow(Mob *defender, int64 &damage); - virtual void DoRiposte(Mob* defender); - inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(EQ::skills::SkillOffense)) * 9 / 10); } - inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; } + float GetProcChances(float ProcBonus, uint16 hand) override; + int GetHandToHandDamage(void) override; + bool TryFinishingBlow(Mob *defender, int64 &damage) override; + void DoRiposte(Mob* defender) override; + inline int32 GetATK() const override { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(EQ::skills::SkillOffense)) * 9 / 10); } + inline int32 GetATKBonus() const override { return itembonuses.ATK + spellbonuses.ATK; } uint32 GetTotalATK(); uint32 GetATKRating(); uint16 GetPrimarySkillValue(); uint16 MaxSkill(EQ::skills::SkillType skillid, uint16 class_, uint16 level) const; inline uint16 MaxSkill(EQ::skills::SkillType skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); } - virtual int GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target = nullptr); - virtual void DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance = false); - virtual void TryBackstab(Mob *other,int ReuseTime = 10); - virtual void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10); - virtual void RogueAssassinate(Mob* other); - virtual void DoClassAttacks(Mob *target, bool IsRiposte=false); + int GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target = nullptr) override; + void DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance = false); + void TryBackstab(Mob *other,int ReuseTime = 10) override; + void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10) override; + void RogueAssassinate(Mob* other) override; + void DoClassAttacks(Mob *target, bool IsRiposte=false); bool CanDoSpecialAttack(Mob *other); - virtual int32 CheckAggroAmount(uint16 spellid); - virtual void CalcBonuses(); + void CalcBonuses() override; void CalcItemBonuses(StatBonuses* newbon); void AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0); int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); - virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr); - virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther); - inline virtual bool IsPet() { return false; } - virtual bool IsNPC() const { return false; } - virtual Mob* GetOwner(); - virtual Mob* GetOwnerOrSelf(); - inline virtual bool HasOwner() { return (GetBotOwner() ? true : false); } - virtual int32 CheckHealAggroAmount(uint16 spellid, Mob *target, uint32 heal_possible = 0); - virtual int64 CalcMaxMana(); - virtual void SetAttackTimer(); + void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr) override; + FACTION_VALUE GetReverseFactionCon(Mob* iOther) override; + inline bool IsPet() override { return false; } + bool IsNPC() const override { return false; } + Mob* GetOwner() override; + Mob* GetOwnerOrSelf() override; + inline bool HasOwner() override { return (GetBotOwner() ? true : false); } + int64 CalcMaxMana() override; + void SetAttackTimer() override; uint64 GetClassHPFactor(); - virtual int64 CalcMaxHP(); + int64 CalcMaxHP() override; bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic); bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic); bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic); void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color); void Camp(bool save_to_database = true); - virtual void AddToHateList(Mob* other, int64 hate = 0, int64 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false, bool pet_command = false); - virtual void SetTarget(Mob* mob); - virtual void Zone(); + void SetTarget(Mob* mob) override; + void Zone(); bool IsArcheryRange(Mob* target); void ChangeBotArcherWeapons(bool isArcher); void Sit(); void Stand(); bool IsSitting(); bool IsStanding(); - virtual int GetWalkspeed() const { return (int)((float)_GetWalkSpeed() * 1.785714285f); } // 1.25 / 0.7 = 1.7857142857142857142857142857143 - virtual int GetRunspeed() const { return (int)((float)_GetRunSpeed() * 1.785714285f); } - virtual void WalkTo(float x, float y, float z); - virtual void RunTo(float x, float y, float z); - virtual void StopMoving(); - virtual void StopMoving(float new_heading); + int GetWalkspeed() const override { return (int)((float)_GetWalkSpeed() * 1.785714285f); } // 1.25 / 0.7 = 1.7857142857142857142857142857143 + int GetRunspeed() const override { return (int)((float)_GetRunSpeed() * 1.785714285f); } + void WalkTo(float x, float y, float z) override; + void RunTo(float x, float y, float z) override; + void StopMoving() override; + void StopMoving(float new_heading) override; //bool GetCombatJitterFlag() { return m_combat_jitter_flag; } bool GetGuardFlag() { return m_guard_flag; } void SetGuardFlag(bool flag = true) { m_guard_flag = flag; } @@ -342,10 +341,10 @@ public: void AI_Bot_Event_SpellCastFinished(bool iCastSucceeded, uint16 slot); // AI Methods - virtual bool AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes); - virtual bool AI_EngagedCastCheck(); - virtual bool AI_PursueCastCheck(); - virtual bool AI_IdleCastCheck(); + bool AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes); + bool AI_EngagedCastCheck() override; + bool AI_PursueCastCheck() override; + bool AI_IdleCastCheck() override; bool AIHealRotation(Mob* tar, bool useFastHeals); bool GetPauseAI() { return _pauseAI; } void SetPauseAI(bool pause_flag) { _pauseAI = pause_flag; } @@ -359,25 +358,22 @@ public: void AI_Bot_Start(uint32 iMoveDelay = 0); // Mob AI Virtual Override Methods - virtual void AI_Process(); - virtual void AI_Stop(); + void AI_Process() override; + void AI_Stop() override; // Mob Spell Virtual Override Methods - virtual void SpellProcess(); - virtual int64 GetActSpellHealing(uint16 spell_id, int64 value, Mob* target = nullptr); - virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime); - virtual int32 GetActSpellCost(uint16 spell_id, int32 cost); - virtual float GetActSpellRange(uint16 spell_id, float range); - virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration); - virtual float GetAOERange(uint16 spell_id); + void SpellProcess() override; + int32 GetActSpellDuration(uint16 spell_id, int32 duration) override; + float GetAOERange(uint16 spell_id) override; virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100); - virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr); + void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr) override; virtual bool CastSpell(uint16 spell_id, uint16 target_id, EQ::spells::CastingSlot slot = EQ::spells::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, - uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr, uint32 aa_id = 0); + uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr, uint32 aa_id = 0); virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar); - virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster); + bool IsImmuneToSpell(uint16 spell_id, Mob *caster) override; virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction, EQ::spells::CastingSlot slot); - virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQ::spells::CastingSlot slot = EQ::spells::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0); + virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQ::spells::CastingSlot slot = EQ::spells::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, + uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0); bool GetBotOwnerDataBuckets(); bool GetBotDataBuckets(); @@ -387,7 +383,7 @@ public: void BotTradeAddItem(const EQ::ItemInstance* inst, uint16 slot_id, std::string* error_message, bool save_to_database = true); void EquipBot(std::string* error_message); bool CheckLoreConflict(const EQ::ItemData* item); - virtual void UpdateEquipmentLight() { m_Light.Type[EQ::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQ::lightsource::LightEquipment] = EQ::lightsource::TypeToLevel(m_Light.Type[EQ::lightsource::LightEquipment]); } + void UpdateEquipmentLight() override { m_Light.Type[EQ::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQ::lightsource::LightEquipment] = EQ::lightsource::TypeToLevel(m_Light.Type[EQ::lightsource::LightEquipment]); } inline EQ::InventoryProfile& GetInv() { return m_inv; } // Static Class Methods @@ -464,12 +460,12 @@ public: Mob* GetBotOwner() { return this->_botOwner; } uint32 GetBotArcheryRange(); EQ::ItemInstance* GetBotItem(uint16 slot_id); - virtual bool GetSpawnStatus() { return _spawnStatus; } + bool GetSpawnStatus() { return _spawnStatus; } uint8 GetPetChooserID() { return _petChooserID; } bool IsPetChooser() { return _petChooser; } bool IsBotArcher() { return m_bot_archery_setting; } bool IsBotCharmer() { return _botCharmer; } - virtual bool IsBot() const { return true; } + bool IsBot() const override { return true; } bool GetRangerAutoWeaponSelect() { return _rangerAutoWeaponSelect; } BotRoleType GetBotRole() { return _botRole; } EQ::constants::StanceType GetBotStance() { return _botStance; } @@ -524,32 +520,32 @@ public: bool GetAltOutOfCombatBehavior() { return _altoutofcombatbehavior;} bool GetShowHelm() { return _showhelm; } - inline virtual int32 GetSTR() const { return STR; } - inline virtual int32 GetSTA() const { return STA; } - inline virtual int32 GetDEX() const { return DEX; } - inline virtual int32 GetAGI() const { return AGI; } - inline virtual int32 GetINT() const { return INT; } - inline virtual int32 GetWIS() const { return WIS; } - inline virtual int32 GetCHA() const { return CHA; } - inline virtual int32 GetMR() const { return MR; } - inline virtual int32 GetFR() const { return FR; } - inline virtual int32 GetDR() const { return DR; } - inline virtual int32 GetPR() const { return PR; } - inline virtual int32 GetCR() const { return CR; } - inline virtual int32 GetCorrup() const { return Corrup; } + inline int32 GetSTR() const override { return STR; } + inline int32 GetSTA() const override { return STA; } + inline int32 GetDEX() const override { return DEX; } + inline int32 GetAGI() const override { return AGI; } + inline int32 GetINT() const override { return INT; } + inline int32 GetWIS() const override { return WIS; } + inline int32 GetCHA() const override { return CHA; } + inline int32 GetMR() const override { return MR; } + inline int32 GetFR() const override { return FR; } + inline int32 GetDR() const override { return DR; } + inline int32 GetPR() const override { return PR; } + inline int32 GetCR() const override { return CR; } + inline int32 GetCorrup() const override { return Corrup; } //Heroic - inline virtual int32 GetHeroicSTR() const { return itembonuses.HeroicSTR; } - inline virtual int32 GetHeroicSTA() const { return itembonuses.HeroicSTA; } - inline virtual int32 GetHeroicDEX() const { return itembonuses.HeroicDEX; } - inline virtual int32 GetHeroicAGI() const { return itembonuses.HeroicAGI; } - inline virtual int32 GetHeroicINT() const { return itembonuses.HeroicINT; } - inline virtual int32 GetHeroicWIS() const { return itembonuses.HeroicWIS; } - inline virtual int32 GetHeroicCHA() const { return itembonuses.HeroicCHA; } - inline virtual int32 GetHeroicMR() const { return itembonuses.HeroicMR; } - inline virtual int32 GetHeroicFR() const { return itembonuses.HeroicFR; } - inline virtual int32 GetHeroicDR() const { return itembonuses.HeroicDR; } - inline virtual int32 GetHeroicPR() const { return itembonuses.HeroicPR; } - inline virtual int32 GetHeroicCR() const { return itembonuses.HeroicCR; } + inline int32 GetHeroicSTR() const override { return itembonuses.HeroicSTR; } + inline int32 GetHeroicSTA() const override { return itembonuses.HeroicSTA; } + inline int32 GetHeroicDEX() const override { return itembonuses.HeroicDEX; } + inline int32 GetHeroicAGI() const override { return itembonuses.HeroicAGI; } + inline int32 GetHeroicINT() const override { return itembonuses.HeroicINT; } + inline int32 GetHeroicWIS() const override { return itembonuses.HeroicWIS; } + inline int32 GetHeroicCHA() const override { return itembonuses.HeroicCHA; } + inline int32 GetHeroicMR() const override { return itembonuses.HeroicMR; } + inline int32 GetHeroicFR() const override { return itembonuses.HeroicFR; } + inline int32 GetHeroicDR() const override { return itembonuses.HeroicDR; } + inline int32 GetHeroicPR() const override { return itembonuses.HeroicPR; } + inline int32 GetHeroicCR() const override { return itembonuses.HeroicCR; } inline virtual int32 GetHeroicCorrup() const { return itembonuses.HeroicCorrup; } // Mod2 inline virtual int32 GetShielding() const { return itembonuses.MeleeMitigation; } @@ -593,7 +589,7 @@ public: // "SET" Class Methods void SetBotSpellID(uint32 newSpellID); - virtual void SetSpawnStatus(bool spawnStatus) { _spawnStatus = spawnStatus; } + void SetSpawnStatus(bool spawnStatus) { _spawnStatus = spawnStatus; } void SetPetChooserID(uint8 id) { _petChooserID = id; } void SetBotArcherySetting(bool bot_archer_setting, bool save = false); void SetBotCharmer(bool c) { _botCharmer = c; } @@ -645,10 +641,10 @@ public: std::string CreateSayLink(Client* botOwner, const char* message, const char* name); // Class Destructors - virtual ~Bot(); + ~Bot() override; // Publicized protected functions - virtual void BotRangedAttack(Mob* other); + void BotRangedAttack(Mob* other); // Publicized private functions static NPCType *FillNPCTypeStruct( @@ -734,11 +730,11 @@ public: void OwnerMessage(std::string message); protected: - virtual void PetAIProcess(); - virtual void BotMeditate(bool isSitting); - virtual bool CheckBotDoubleAttack(bool Triple = false); - virtual void PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client* client); - virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0); + void PetAIProcess(); + void BotMeditate(bool isSitting); + bool CheckBotDoubleAttack(bool Triple = false); + void PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client* client); + bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0) override; BotCastingRoles& GetCastingRoles() { return m_CastingRoles; } void SetGroupHealer(bool flag = true) { m_CastingRoles.GroupHealer = flag; } diff --git a/zone/client.h b/zone/client.h index 7e0cf29cd..ec872f657 100644 --- a/zone/client.h +++ b/zone/client.h @@ -559,7 +559,6 @@ public: inline virtual int32 GetDelayDeath() const { return aabonuses.DelayDeath + spellbonuses.DelayDeath + itembonuses.DelayDeath + 11; } - int32 GetActSpellCost(uint16 spell_id, int32); virtual bool CheckFizzle(uint16 spell_id); virtual bool CheckSpellLevelRestriction(uint16 spell_id); virtual int GetCurrentBuffSlots() const; diff --git a/zone/effects.cpp b/zone/effects.cpp index 879ae374a..774cc4b3b 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -31,7 +31,7 @@ #include "../common/zone_store.h" #include "position.h" -float Mob::GetActSpellRange(uint16 spell_id, float range, bool IsBard) +float Mob::GetActSpellRange(uint16 spell_id, float range) { float extrange = 100; @@ -317,7 +317,9 @@ int64 Mob::GetExtraSpellAmt(uint16 spell_id, int64 extra_spell_amt, int64 base_s } int64 Mob::GetActSpellHealing(uint16 spell_id, int64 value, Mob* target, bool from_buff_tic) { - + if (target == nullptr && IsBot()) { + target = this; + } if (IsNPC()) { value += value * CastToNPC()->GetSpellFocusHeal() / 100; @@ -443,7 +445,7 @@ int64 Mob::GetActSpellHealing(uint16 spell_id, int64 value, Mob* target, bool fr } -int32 Client::GetActSpellCost(uint16 spell_id, int32 cost) +int32 Mob::GetActSpellCost(uint16 spell_id, int32 cost) { //FrenziedDevastation doubles mana cost of all DD spells int16 FrenziedDevastation = itembonuses.FrenziedDevastation + spellbonuses.FrenziedDevastation + aabonuses.FrenziedDevastation; diff --git a/zone/merc.cpp b/zone/merc.cpp index c3013a954..d0b78d08a 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -2706,53 +2706,6 @@ int64 Merc::GetFocusEffect(focusType type, uint16 spell_id, bool from_buff_tic) return realTotal + realTotal2 + realTotal3; } -int32 Merc::GetActSpellCost(uint16 spell_id, int32 cost) -{ - // Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell - if(itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) - { - int mana_back = itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100; - // Doesnt generate mana, so best case is a free spell - if(mana_back > cost) - mana_back = cost; - - cost -= mana_back; - } - - // This formula was derived from the following resource: - // http://www.eqsummoners.com/eq1/specialization-library.html - // WildcardX - float PercentManaReduction = 0; - - int16 focus_redux = GetFocusEffect(focusManaCost, spell_id); - - if(focus_redux > 0) - { - PercentManaReduction += zone->random.Real(1, (double)focus_redux); - } - - cost -= (cost * (PercentManaReduction / 100)); - - // Gift of Mana - reduces spell cost to 1 mana - if(focus_redux >= 100) { - uint32 buff_max = GetMaxTotalSlots(); - for (int buffSlot = 0; buffSlot < buff_max; buffSlot++) { - if (buffs[buffSlot].spellid == 0 || buffs[buffSlot].spellid >= SPDAT_RECORDS) - continue; - - if(IsEffectInSpell(buffs[buffSlot].spellid, SE_ReduceManaCost)) { - if(CalcFocusEffect(focusManaCost, buffs[buffSlot].spellid, spell_id) == 100) - cost = 1; - } - } - } - - if(cost < 0) - cost = 0; - - return cost; -} - int8 Merc::GetChanceToCastBySpellType(uint32 spellType) { int mercStance = (int)GetStance(); int8 mercClass = GetClass(); diff --git a/zone/merc.h b/zone/merc.h index 8dd7bd98c..b05fa32d3 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -83,7 +83,6 @@ public: Corpse* GetGroupMemberCorpse(); // Merc Spell Casting Methods - virtual int32 GetActSpellCost(uint16 spell_id, int32 cost); int8 GetChanceToCastBySpellType(uint32 spellType); void SetSpellRecastTimer(uint16 timer_id, uint16 spellid, uint32 recast_delay); void SetDisciplineRecastTimer(uint16 timer_id, uint16 spellid, uint32 recast_delay); diff --git a/zone/mob.h b/zone/mob.h index a7fe76593..57408b970 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -322,13 +322,13 @@ public: bool IsAISpellEffect = false, uint16 effect_id = 0, int32 se_base = 0, int32 se_limit = 0, int32 se_max = 0); void NegateSpellEffectBonuses(uint16 spell_id); bool NegateSpellEffect(uint16 spell_id, int effect_id); - virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false); - virtual int64 GetActSpellDamage(uint16 spell_id, int64 value, Mob* target = nullptr); - virtual int64 GetActDoTDamage(uint16 spell_id, int64 value, Mob* target, bool from_buff_tic = true); - virtual int64 GetActSpellHealing(uint16 spell_id, int64 value, Mob* target = nullptr, bool from_buff_tic = false); - virtual int32 GetActSpellCost(uint16 spell_id, int32 cost){ return cost;} + float GetActSpellRange(uint16 spell_id, float range); + int64 GetActSpellDamage(uint16 spell_id, int64 value, Mob* target = nullptr); + int64 GetActDoTDamage(uint16 spell_id, int64 value, Mob* target, bool from_buff_tic = true); + int64 GetActSpellHealing(uint16 spell_id, int64 value, Mob* target = nullptr, bool from_buff_tic = false); + int32 GetActSpellCost(uint16 spell_id, int32 cost); virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration); - virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime); + int32 GetActSpellCasttime(uint16 spell_id, int32 casttime); virtual int64 GetActReflectedSpellDamage(int32 spell_id, int64 value, int effectiveness); float ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override = false, int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false, @@ -710,7 +710,7 @@ public: //AI static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel); inline uint32 GetLevelCon(uint8 iOtherLevel) const { return GetLevelCon(GetLevel(), iOtherLevel); } - virtual void AddToHateList(Mob* other, int64 hate = 0, int64 damage = 0, bool iYellForHelp = true, + void AddToHateList(Mob* other, int64 hate = 0, int64 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false, uint16 spell_id = SPELL_UNKNOWN, bool pet_comand = false); bool RemoveFromHateList(Mob* mob); void SetHateAmountOnEnt(Mob* other, int64 hate = 0, int64 damage = 0) { hate_list.SetHateAmountOnEnt(other,hate,damage);} @@ -1601,7 +1601,7 @@ protected: virtual #endif int GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target = nullptr); - int64 GetFocusEffect(focusType type, uint16 spell_id, Mob *caster = nullptr, bool from_buff_tic = false); + virtual int64 GetFocusEffect(focusType type, uint16 spell_id, Mob *caster = nullptr, bool from_buff_tic = false); virtual EQ::InventoryProfile& GetInv() { return m_inv; } void CalculateNewFearpoint(); float FindGroundZ(float new_x, float new_y, float z_offset=0.0); diff --git a/zone/npc.h b/zone/npc.h index e1e1e3ae5..6863d7576 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -580,7 +580,7 @@ protected: virtual bool AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes, bool bInnates = false); virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0); AISpellsVar_Struct AISpellVar; - int64 GetFocusEffect(focusType type, uint16 spell_id, Mob *caster = nullptr, bool from_buff_tic = false); + int64 GetFocusEffect(focusType type, uint16 spell_id, Mob *caster = nullptr, bool from_buff_tic = false) override; uint16 innate_proc_spell_id; uint32 npc_spells_effects_id; diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index cf1181fd2..eca9a59d5 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -6373,8 +6373,8 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro rand_effectiveness = true; } - //Check if item focus effect exists for the client. - if (itembonuses.FocusEffects[type]){ + //Check if item focus effect exists for the mob. + if (itembonuses.FocusEffects[type]) { const EQ::ItemData* TempItem = nullptr; const EQ::ItemData* UsedItem = nullptr; @@ -6384,12 +6384,13 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro int32 focus_max_real = 0; //item focus - for (int x = EQ::invslot::EQUIPMENT_BEGIN; x <= EQ::invslot::EQUIPMENT_END; x++) - { + for (int x = EQ::invslot::EQUIPMENT_BEGIN; x <= EQ::invslot::EQUIPMENT_END; x++) { TempItem = nullptr; EQ::ItemInstance* ins = GetInv().GetItem(x); - if (!ins) + if (!ins) { continue; + } + TempItem = ins->GetItem(); if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) { if(rand_effectiveness) { @@ -6418,12 +6419,10 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro } } - for (int y = EQ::invaug::SOCKET_BEGIN; y <= EQ::invaug::SOCKET_END; ++y) - { + for (int y = EQ::invaug::SOCKET_BEGIN; y <= EQ::invaug::SOCKET_END; ++y) { EQ::ItemInstance *aug = nullptr; aug = ins->GetAugment(y); - if(aug) - { + if (aug) { const EQ::ItemData* TempItemAug = aug->GetItem(); if (TempItemAug && TempItemAug->Focus.Effect > 0 && TempItemAug->Focus.Effect != SPELL_UNKNOWN) { if(rand_effectiveness) { @@ -6456,16 +6455,17 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro } if (IsClient()) { - //Tribute Focus - for (int x = EQ::invslot::TRIBUTE_BEGIN; x <= EQ::invslot::TRIBUTE_END; ++x) - { + //Client Tribute Focus + for (int x = EQ::invslot::TRIBUTE_BEGIN; x <= EQ::invslot::TRIBUTE_END; ++x) { TempItem = nullptr; EQ::ItemInstance* ins = GetInv().GetItem(x); - if (!ins) + if (!ins) { continue; + } + TempItem = ins->GetItem(); if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) { - if(rand_effectiveness) { + if (rand_effectiveness) { focus_max = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id, true); if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) { focus_max_real = focus_max; @@ -6494,8 +6494,9 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro } } - if(UsedItem && rand_effectiveness && focus_max_real != 0) + if (UsedItem && rand_effectiveness && focus_max_real != 0) { realTotal = CalcFocusEffect(type, UsedFocusID, spell_id); + } if ((rand_effectiveness && UsedItem) || (realTotal != 0 && UsedItem)) { // there are a crap ton more of these, I was able to verify these ones though @@ -6540,8 +6541,8 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro } } - //Check if spell focus effect exists for the client. - if (spellbonuses.FocusEffects[type]){ + //Check if spell focus effect exists for the mob. + if (spellbonuses.FocusEffects[type]) { //Spell Focus int32 Total2 = 0; @@ -6555,10 +6556,11 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro int buff_max = GetMaxTotalSlots(); for (buff_slot = 0; buff_slot < buff_max; buff_slot++) { focusspellid = buffs[buff_slot].spellid; - if (focusspellid == 0 || focusspellid >= SPDAT_RECORDS) + if (focusspellid == 0 || focusspellid >= SPDAT_RECORDS) { continue; + } - if(rand_effectiveness) { + if (rand_effectiveness) { focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true, buffs[buff_slot].casterid, caster); if (focus_max2 > 0 && focus_max_real2 >= 0 && focus_max2 > focus_max_real2) { focus_max_real2 = focus_max2; @@ -6589,16 +6591,17 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro original_caster_id = buffs[buff_tracker].casterid; } - if(focusspell_tracker && rand_effectiveness && focus_max_real2 != 0) + if (focusspell_tracker && rand_effectiveness && focus_max_real2 != 0) { realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id, false, original_caster_id, caster); + } - if(!from_buff_tic && buff_tracker >= 0 && buffs[buff_tracker].hit_number > 0) { + if (!from_buff_tic && buff_tracker >= 0 && buffs[buff_tracker].hit_number > 0) { CheckNumHitsRemaining(NumHit::MatchingSpells, buff_tracker); } } // AA Focus - if (aabonuses.FocusEffects[type]){ + if (aabonuses.FocusEffects[type]) { int32 Total3 = 0; @@ -6607,12 +6610,13 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro auto ability = ability_rank.first; auto rank = ability_rank.second; - if(!ability) { + if (!ability) { continue; } - if (rank->effects.empty()) + if (rank->effects.empty()) { continue; + } Total3 = CalcAAFocus(type, *rank, spell_id); if (Total3 > 0 && realTotal3 >= 0 && Total3 > realTotal3) { @@ -6624,15 +6628,17 @@ int64 Mob::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster, bool fro } } - if(type == focusReagentCost && (IsEffectInSpell(spell_id, SE_SummonItem) || IsSacrificeSpell(spell_id))) + if (type == focusReagentCost && (IsEffectInSpell(spell_id, SE_SummonItem) || IsSacrificeSpell(spell_id))) { return 0; + } //Summon Spells that require reagents are typically imbue type spells, enchant metal, sacrifice and shouldn't be affected //by reagent conservation for obvious reasons. //Non-Live like feature to allow for an additive focus bonus to be applied from foci that are placed in worn slot. (No limit checks) int32 worneffect_bonus = 0; - if (RuleB(Spells, UseAdditiveFocusFromWornSlot)) + if (RuleB(Spells, UseAdditiveFocusFromWornSlot)) { worneffect_bonus = itembonuses.FocusEffectsWorn[type]; + } return realTotal + realTotal2 + realTotal3 + worneffect_bonus; } diff --git a/zone/spells.cpp b/zone/spells.cpp index af3c4028d..9805ccece 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -739,8 +739,7 @@ bool Mob::DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob *sp ignore_if_npc_or_gm = true; } - if (check_on_casting){ - + if (check_on_casting) { if (spells[spell_id].target_type == ST_AEClientV1 || spells[spell_id].target_type == ST_AECaster || spells[spell_id].target_type == ST_Ring ||