mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-24 17:48:20 +00:00
Merge branch 'master' into shieldability
This commit is contained in:
@@ -1236,6 +1236,7 @@ bool IsEffectIgnoredInStacking(int spa)
|
|||||||
case SE_Ff_CasterClass:
|
case SE_Ff_CasterClass:
|
||||||
case SE_Ff_Same_Caster:
|
case SE_Ff_Same_Caster:
|
||||||
case SE_Proc_Timer_Modifier:
|
case SE_Proc_Timer_Modifier:
|
||||||
|
case SE_Weapon_Stance:
|
||||||
case SE_TwinCastBlocker:
|
case SE_TwinCastBlocker:
|
||||||
case SE_Fc_CastTimeAmt:
|
case SE_Fc_CastTimeAmt:
|
||||||
case SE_Fc_CastTimeMod2:
|
case SE_Fc_CastTimeMod2:
|
||||||
|
|||||||
+7
-6
@@ -64,6 +64,7 @@
|
|||||||
#define SPELL_SHAPECHANGE70 6503
|
#define SPELL_SHAPECHANGE70 6503
|
||||||
#define SPELL_MANA_BURN 2751
|
#define SPELL_MANA_BURN 2751
|
||||||
#define SPELL_LIFE_BURN 2755
|
#define SPELL_LIFE_BURN 2755
|
||||||
|
#define SPELL_TOUCH_OF_THE_DIVINE 4789
|
||||||
// these have known hardcoded behavior but we don't do anything yet, move them above this comment when fixed
|
// these have known hardcoded behavior but we don't do anything yet, move them above this comment when fixed
|
||||||
#define SPELL_THE_DAINS_JUSTICE 1476
|
#define SPELL_THE_DAINS_JUSTICE 1476
|
||||||
#define SPELL_MODULATION 1502
|
#define SPELL_MODULATION 1502
|
||||||
@@ -834,11 +835,11 @@ typedef enum {
|
|||||||
#define SE_Chance_Best_in_Spell_Grp 469 // implemented - Chance to cast highest scribed spell within a spell group. All base2 spells share roll chance, only 1 cast.
|
#define SE_Chance_Best_in_Spell_Grp 469 // implemented - Chance to cast highest scribed spell within a spell group. All base2 spells share roll chance, only 1 cast.
|
||||||
#define SE_Trigger_Best_in_Spell_Grp 470 // implemented - Chance to cast highest scribed spell within a spell group. Each spell has own chance.
|
#define SE_Trigger_Best_in_Spell_Grp 470 // implemented - Chance to cast highest scribed spell within a spell group. Each spell has own chance.
|
||||||
//#define SE_Double_Melee_Round 471 //
|
//#define SE_Double_Melee_Round 471 //
|
||||||
//#define SE_Buy_AA_Rank 472 //
|
#define SE_Buy_AA_Rank 472 // implemented, @Special, Used in AA abilities that have Enable/Disable toggle. Spell on Disabled Rank has this effect in it, base: 1, limit: none, max: none, Note: This will not just buy an AA
|
||||||
#define SE_Double_Backstab_Front 473 // implemented - Chance to double backstab from front
|
#define SE_Double_Backstab_Front 473 // implemented - Chance to double backstab from front
|
||||||
#define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 // implemenetd - Critical damage mod applied to pets from owner
|
#define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 // implemenetd - Critical damage mod applied to pets from owner
|
||||||
#define SE_Trigger_Spell_Non_Item 475 // implemented - Trigger spell on cast only if not from item click.
|
#define SE_Trigger_Spell_Non_Item 475 // implemented - Trigger spell on cast only if not from item click.
|
||||||
//#define SE_Weapon_Stance 476 //
|
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Duel Wield is equiped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
|
||||||
#define SE_Hatelist_To_Top_Index 477 // Implemented - Chance to be set to top of rampage list
|
#define SE_Hatelist_To_Top_Index 477 // Implemented - Chance to be set to top of rampage list
|
||||||
#define SE_Hatelist_To_Tail_Index 478 // Implemented - Chance to be set to bottom of rampage list
|
#define SE_Hatelist_To_Tail_Index 478 // Implemented - Chance to be set to bottom of rampage list
|
||||||
#define SE_Ff_Value_Min 479 // implemented, @Ff, Minimum base value of a spell that can be focused, base: spells to be focused base1 value
|
#define SE_Ff_Value_Min 479 // implemented, @Ff, Minimum base value of a spell that can be focused, base: spells to be focused base1 value
|
||||||
@@ -865,10 +866,10 @@ typedef enum {
|
|||||||
#define SE_Fc_CastTimeMod2 500 // implemented, @Fc, On Caster, cast time mod pct, base: pct, Note: Can reduce to instant cast
|
#define SE_Fc_CastTimeMod2 500 // implemented, @Fc, On Caster, cast time mod pct, base: pct, Note: Can reduce to instant cast
|
||||||
#define SE_Fc_CastTimeAmt 501 // implemented, @Fc, On Caster, cast time mod flat amt, base: milliseconds, Note: Can reduce to instant cast
|
#define SE_Fc_CastTimeAmt 501 // implemented, @Fc, On Caster, cast time mod flat amt, base: milliseconds, Note: Can reduce to instant cast
|
||||||
#define SE_Fearstun 502 // implemented - Stun with a max level limit. Normal stun restrictions don't apply.
|
#define SE_Fearstun 502 // implemented - Stun with a max level limit. Normal stun restrictions don't apply.
|
||||||
#define SE_Melee_Damage_Position_Mod 503 // implemented - modify melee damage by pct if done from Front or Behind
|
#define SE_Melee_Damage_Position_Mod 503 // implemented, @OffBonus, modify melee damage by percent if done from Front or Behind opponent, base: pct, limit: 0=back 1=front, max: none
|
||||||
//#define SE_Melee_Damage_Position_Amt 504 //
|
#define SE_Melee_Damage_Position_Amt 504 // implemented, @OffBonus, modify melee damage by flat amount if done from Front or Behind opponent, base: amt, limit: 0=back 1=front, max: none
|
||||||
#define SE_Damage_Taken_Position_Mod 505 // implemented - mitigate melee damage by pct if dmg taken from Front or Behind
|
#define SE_Damage_Taken_Position_Mod 505 // implemented, @DefBonus, modify melee damage by percent if dmg taken from Front or Behind, base: pct, limit: 0=back 1=front, max: none
|
||||||
//#define SE_Damage_Taken_Position_Amt 506 //
|
#define SE_Damage_Taken_Position_Amt 506 // implemented -@DefBonus, modify melee damage by flat amount if dmg taken from your Front or Behind, base: amt, limit: 0=back 1=front, max: none
|
||||||
#define SE_Fc_Amplify_Mod 507 // implemented, @Fc, On Caster, damage-heal-dot mod pct, base: pct
|
#define SE_Fc_Amplify_Mod 507 // implemented, @Fc, On Caster, damage-heal-dot mod pct, base: pct
|
||||||
#define SE_Fc_Amplify_Amt 508 // implemented, @Fc, On Caster, damage-heal-dot mod flat amt, base: amt
|
#define SE_Fc_Amplify_Amt 508 // implemented, @Fc, On Caster, damage-heal-dot mod flat amt, base: amt
|
||||||
#define SE_Health_Transfer 509 // implemented - exchange health for damage or healing on a target. ie Lifeburn/Act of Valor
|
#define SE_Health_Transfer 509 // implemented - exchange health for damage or healing on a target. ie Lifeburn/Act of Valor
|
||||||
|
|||||||
+191
-17
@@ -1162,6 +1162,7 @@ void Client::IncrementAlternateAdvancementRank(int rank_id) {
|
|||||||
|
|
||||||
void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
||||||
AA::Rank *rank = zone->GetAlternateAdvancementRank(rank_id);
|
AA::Rank *rank = zone->GetAlternateAdvancementRank(rank_id);
|
||||||
|
|
||||||
if(!rank) {
|
if(!rank) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1179,8 +1180,10 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool use_toggle_passive_hotkey = UseTogglePassiveHotkey(*rank);
|
||||||
|
|
||||||
//make sure it is not a passive
|
//make sure it is not a passive
|
||||||
if(!rank->effects.empty()) {
|
if(!rank->effects.empty() && !use_toggle_passive_hotkey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1188,7 +1191,6 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
|||||||
// We don't have the AA
|
// We don't have the AA
|
||||||
if (!GetAA(rank_id, &charges))
|
if (!GetAA(rank_id, &charges))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//if expendable make sure we have charges
|
//if expendable make sure we have charges
|
||||||
if(ability->charges > 0 && charges < 1)
|
if(ability->charges > 0 && charges < 1)
|
||||||
return;
|
return;
|
||||||
@@ -1241,15 +1243,21 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bards can cast instant cast AAs while they are casting another song
|
if (use_toggle_passive_hotkey) {
|
||||||
if(spells[rank->spell].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
|
TogglePassiveAlternativeAdvancement(*rank, ability->id);
|
||||||
if(!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQ::spells::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].ResistDiff, false)) {
|
}
|
||||||
return;
|
else {
|
||||||
|
// Bards can cast instant cast AAs while they are casting another song
|
||||||
|
if (spells[rank->spell].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
|
||||||
|
if (!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQ::spells::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].ResistDiff, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ExpendAlternateAdvancementCharge(ability->id);
|
||||||
}
|
}
|
||||||
ExpendAlternateAdvancementCharge(ability->id);
|
else {
|
||||||
} else {
|
if (!CastSpell(rank->spell, target_id, EQ::spells::CastingSlot::AltAbility, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, nullptr, rank->id)) {
|
||||||
if(!CastSpell(rank->spell, target_id, EQ::spells::CastingSlot::AltAbility, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, nullptr, rank->id)) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1287,16 +1295,16 @@ int Mob::GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
||||||
for(auto &iter : aa_ranks) {
|
for (auto &iter : aa_ranks) {
|
||||||
AA::Ability *ability = zone->GetAlternateAdvancementAbility(iter.first);
|
AA::Ability *ability = zone->GetAlternateAdvancementAbility(iter.first);
|
||||||
if(ability && aa_id == ability->id) {
|
if (ability && aa_id == ability->id) {
|
||||||
if(iter.second.second > 0) {
|
if (iter.second.second > 0) {
|
||||||
iter.second.second -= 1;
|
iter.second.second -= 1;
|
||||||
|
|
||||||
if(iter.second.second == 0) {
|
if (iter.second.second == 0) {
|
||||||
if(IsClient()) {
|
if (IsClient()) {
|
||||||
AA::Rank *r = ability->GetRankByPointsSpent(iter.second.first);
|
AA::Rank *r = ability->GetRankByPointsSpent(iter.second.first);
|
||||||
if(r) {
|
if (r) {
|
||||||
CastToClient()->GetEPP().expended_aa += r->cost;
|
CastToClient()->GetEPP().expended_aa += r->cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1307,7 +1315,7 @@ void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
|||||||
aa_ranks.erase(iter.first);
|
aa_ranks.erase(iter.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsClient()) {
|
if (IsClient()) {
|
||||||
Client *c = CastToClient();
|
Client *c = CastToClient();
|
||||||
c->SaveAA();
|
c->SaveAA();
|
||||||
c->SendAlternateAdvancementPoints();
|
c->SendAlternateAdvancementPoints();
|
||||||
@@ -1796,3 +1804,169 @@ bool Mob::CheckAATimer(int timer)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ability_id)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Certain AA, like Weapon Stance line use a special toggle Hotkey to enable or disable the AA's passive abilities.
|
||||||
|
This is occurs by doing the following. Each 'rank' of Weapon Stance is actually 2 actual ranks.
|
||||||
|
First rank is always the Disabled version which cost X amount of AA. Second rank is the Enabled version which cost 0 AA.
|
||||||
|
When you buy the first rank, you make a hotkey that on live say 'Weapon Stance Disabled', if you clik that it then BUYS the
|
||||||
|
next rank of AA (cost 0) which switches the hotkey to 'Enabled Weapon Stance' and you are given the passive buff effects.
|
||||||
|
If you click the Enabled hotkey, it causes you to lose an AA rank and once again be disabled. Thus, you are switching between
|
||||||
|
two AA ranks. Thefore when creating an AA using this ability, you need generate both ranks. Follow the same pattern for additional ranks.
|
||||||
|
|
||||||
|
IMPORTANT! The toggle system can be used to Enable or Disable ANY passive AA. You just need to follow the instructions on how to create it.
|
||||||
|
Example: Enable or Disable a buff that gives a large hate modifier. Play may Enable when tanking and Disable when DPS ect.
|
||||||
|
|
||||||
|
Note: On live the Enabled rank is shown having a Charge of 1, while Disabled rank has no charges. Our current code doesn't support that. Do not use charges.
|
||||||
|
Note: Live uses a spell 'Disable Ability' ID 46164 to trigger a script to do the AA rank changes. At present time it is not coded to require that, any spell id works.
|
||||||
|
Note: Discovered a bug on ROF2, where when you buy first rank of an AA with a hotkey, it will always display the title of the second rank in the database. Be aware. No easy fix.
|
||||||
|
|
||||||
|
Dev Note(Kayen 8/1/21): The system as set up is very similar to live, with exception that live gives the Enabled rank 1 Charge. The code here emulates what happens when a
|
||||||
|
charge would be expended.
|
||||||
|
|
||||||
|
Instructions for how to make the AA - assuming a basic level of knowledge of how AA's work.
|
||||||
|
- aa_abilities table : Create new ability with a hotkey, type 3, zero charges
|
||||||
|
- aa_ranks table : [Disabled rank] First rank, should have a cost > 0 (this is what you buy), Set hotkeys, MUST SET A SPELL CONTAINING EFFECT SE_Buy_AA_Rank(SPA 472), set a short recast timer.
|
||||||
|
[Enabled rank] Second rank, should have a cost = 0, Set hotkeys, Set any valid spell ID you want (it has to exist but does nothing), set a short recast timer.
|
||||||
|
*Recommend if doing custom, just make the hotkey titled 'Toggle <Ability Name>' and use for both.
|
||||||
|
|
||||||
|
- aa_rank_effects table : [Disabled rank] No data needed in the aa_ranks_effect table
|
||||||
|
[Enabled rank] Second rank set effect_id = 457 (weapon stance), slot 1,2,3, base1= spell triggers, base= weapon type (0=2H,1=SH,2=DW), for slot 1,2,3
|
||||||
|
|
||||||
|
Example SQL -Disabled
|
||||||
|
DO NOT ADD any data to the aa_rank_effects for this rank_id
|
||||||
|
|
||||||
|
-Enabled
|
||||||
|
INSERT INTO aa_rank_effects (rank_id, slot, effect_id, base1, base2) VALUES (20003, 1, 476, 145,0);
|
||||||
|
INSERT INTO aa_rank_effects (rank_id, slot, effect_id, base1, base2) VALUES (20003, 2, 476, 174,1);
|
||||||
|
INSERT INTO aa_rank_effects (rank_id, slot, effect_id, base1, base2) VALUES (20003, 3, 476, 172,2);
|
||||||
|
|
||||||
|
Warning: If you want to design an AA that only uses one weapon type to trigger, like will only apply buff if Shield. Do not include data for other types. Never have a base value=0
|
||||||
|
in the Enabled rank.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool enable_next_rank = IsEffectInSpell(rank.spell, SE_Buy_AA_Rank);
|
||||||
|
|
||||||
|
if (enable_next_rank) {
|
||||||
|
|
||||||
|
//Enable
|
||||||
|
TogglePurchaseAlternativeAdvancementRank(rank.next_id);
|
||||||
|
Message(Chat::Spells, "You enable an ability."); //Message live gives you. Should come from spell.
|
||||||
|
|
||||||
|
AA::Rank *rank_next = zone->GetAlternateAdvancementRank(rank.next_id);
|
||||||
|
|
||||||
|
//Add checks for any special cases for toggle.
|
||||||
|
if (IsEffectinAlternateAdvancementRankEffects(*rank_next, SE_Weapon_Stance)) {
|
||||||
|
weaponstance.aabonus_enabled = true;
|
||||||
|
ApplyWeaponsStance();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
//Disable
|
||||||
|
ResetAlternateAdvancementRank(ability_id);
|
||||||
|
TogglePurchaseAlternativeAdvancementRank(rank.prev_id);
|
||||||
|
Message(Chat::Spells, "You disable an ability."); //Message live gives you. Should come from spell.
|
||||||
|
|
||||||
|
//Add checks for any special cases for toggle.
|
||||||
|
if (IsEffectinAlternateAdvancementRankEffects(rank, SE_Weapon_Stance)) {
|
||||||
|
weaponstance.aabonus_enabled = false;
|
||||||
|
BuffFadeBySpellID(weaponstance.aabonus_buff_spell_id);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::UseTogglePassiveHotkey(const AA::Rank &rank) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Disabled rank needs a rank spell containing the SE_Buy_AA_Rank effect to return true.
|
||||||
|
Enabled rank checks to see if the prior rank contains a rank spell with SE_Buy_AA_Rank, if so true.
|
||||||
|
|
||||||
|
Note: On live the enabled rank is Expendable with Charge 1.
|
||||||
|
|
||||||
|
We have already confirmed the rank spell is valid before this function is called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (IsEffectInSpell(rank.spell, SE_Buy_AA_Rank)) {//Checked when is Disabled.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (rank.prev_id != -1) {//Check when effect is Enabled.
|
||||||
|
AA::Rank *rank_prev = zone->GetAlternateAdvancementRank(rank.prev_id);
|
||||||
|
|
||||||
|
if (IsEffectInSpell(rank_prev->spell, SE_Buy_AA_Rank)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::IsEffectinAlternateAdvancementRankEffects(const AA::Rank &rank, int effect_id) {
|
||||||
|
|
||||||
|
for (const auto &e : rank.effects) {
|
||||||
|
|
||||||
|
if (e.effect_id == effect_id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::ResetAlternateAdvancementRank(uint32 aa_id) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Resets your AA to baseline
|
||||||
|
*/
|
||||||
|
|
||||||
|
for(auto &iter : aa_ranks) {
|
||||||
|
|
||||||
|
AA::Ability *ability = zone->GetAlternateAdvancementAbility(iter.first);
|
||||||
|
|
||||||
|
if(ability && aa_id == ability->id) {
|
||||||
|
RemoveExpendedAA(ability->first_rank_id);
|
||||||
|
aa_ranks.erase(iter.first);
|
||||||
|
SaveAA();
|
||||||
|
SendAlternateAdvancementPoints();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::TogglePurchaseAlternativeAdvancementRank(int rank_id){
|
||||||
|
|
||||||
|
/*
|
||||||
|
Stripped down version of purchasing AA. Will give no messages.
|
||||||
|
Used with toggle hotkey functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
AA::Rank *rank = zone->GetAlternateAdvancementRank(rank_id);
|
||||||
|
if (!rank) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rank->base_ability) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CanPurchaseAlternateAdvancementRank(rank, false, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rank_id = rank->base_ability->first_rank_id;
|
||||||
|
SetAA(rank_id, rank->current_value, 0);
|
||||||
|
|
||||||
|
if (rank->next) {
|
||||||
|
SendAlternateAdvancementRank(rank->base_ability->id, rank->next->current_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveAA();
|
||||||
|
SendAlternateAdvancementPoints();
|
||||||
|
SendAlternateAdvancementStats();
|
||||||
|
CalcBonuses();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -5222,7 +5222,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
|||||||
// Seems the crit message is generated before some of them :P
|
// Seems the crit message is generated before some of them :P
|
||||||
|
|
||||||
// worn item +skill dmg, SPA 220, 418. Live has a normalized version that should be here too
|
// worn item +skill dmg, SPA 220, 418. Live has a normalized version that should be here too
|
||||||
hit.min_damage += GetSkillDmgAmt(hit.skill);
|
hit.min_damage += GetSkillDmgAmt(hit.skill) + GetPositionalDmgAmt(defender);
|
||||||
|
|
||||||
// shielding mod2
|
// shielding mod2
|
||||||
if (defender->itembonuses.MeleeMitigation)
|
if (defender->itembonuses.MeleeMitigation)
|
||||||
@@ -5279,7 +5279,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
|||||||
|
|
||||||
int pct_damage_reduction = defender->GetSkillDmgTaken(hit.skill, opts) + defender->GetPositionalDmgTaken(this);
|
int pct_damage_reduction = defender->GetSkillDmgTaken(hit.skill, opts) + defender->GetPositionalDmgTaken(this);
|
||||||
|
|
||||||
hit.damage_done += (hit.damage_done * pct_damage_reduction / 100) + (defender->GetFcDamageAmtIncoming(this, 0, true, hit.skill));
|
hit.damage_done += (hit.damage_done * pct_damage_reduction / 100) + (defender->GetFcDamageAmtIncoming(this, 0, true, hit.skill)) + defender->GetPositionalDmgTakenAmt(this);
|
||||||
|
|
||||||
if (defender->GetShielderID()) {
|
if (defender->GetShielderID()) {
|
||||||
DoShieldDamageOnShielder(defender, hit.damage_done, hit.skill);
|
DoShieldDamageOnShielder(defender, hit.damage_done, hit.skill);
|
||||||
|
|||||||
+137
-17
@@ -154,6 +154,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
|
|||||||
SetShieldEquiped(false);
|
SetShieldEquiped(false);
|
||||||
SetTwoHandBluntEquiped(false);
|
SetTwoHandBluntEquiped(false);
|
||||||
SetTwoHanderEquipped(false);
|
SetTwoHanderEquipped(false);
|
||||||
|
SetDuelWeaponsEquiped(false);
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
// Update: MainAmmo should only calc skill mods (TODO: Check for other cases)
|
// Update: MainAmmo should only calc skill mods (TODO: Check for other cases)
|
||||||
@@ -171,8 +172,13 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
|
|||||||
SetTwoHandBluntEquiped(true);
|
SetTwoHandBluntEquiped(true);
|
||||||
SetTwoHanderEquipped(true);
|
SetTwoHanderEquipped(true);
|
||||||
}
|
}
|
||||||
else if (i == EQ::invslot::slotPrimary && (item && (item->ItemType == EQ::item::ItemType2HSlash || item->ItemType == EQ::item::ItemType2HPiercing)))
|
else if (i == EQ::invslot::slotPrimary && (item && (item->ItemType == EQ::item::ItemType2HSlash || item->ItemType == EQ::item::ItemType2HPiercing))) {
|
||||||
SetTwoHanderEquipped(true);
|
SetTwoHanderEquipped(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CanThisClassDualWield()) {
|
||||||
|
SetDuelWeaponsEquiped(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//tribute items
|
//tribute items
|
||||||
@@ -1539,6 +1545,26 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SE_Damage_Taken_Position_Amt:
|
||||||
|
{
|
||||||
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
|
if (base2 < 0 || base2 > 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
newbon->Damage_Taken_Position_Amt[base2] += base1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SE_Melee_Damage_Position_Amt:
|
||||||
|
{
|
||||||
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
|
if (base2 < 0 || base2 > 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
newbon->Melee_Damage_Position_Amt[base2] += base1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SE_DS_Mitigation_Amount:
|
case SE_DS_Mitigation_Amount:
|
||||||
newbon->DS_Mitigation_Amount += base1;
|
newbon->DS_Mitigation_Amount += base1;
|
||||||
break;
|
break;
|
||||||
@@ -1555,6 +1581,25 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
newbon->Pet_Add_Atk += base1;
|
newbon->Pet_Add_Atk += base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_Weapon_Stance:
|
||||||
|
{
|
||||||
|
if (IsValidSpell(base1)) { //base1 is the spell_id of buff
|
||||||
|
if (base2 <= WEAPON_STANCE_TYPE_MAX) { //0=2H, 1=Shield, 2=DW
|
||||||
|
if (IsValidSpell(newbon->WeaponStance[base2])) { //Check if we already a spell_id saved for this effect
|
||||||
|
if (spells[newbon->WeaponStance[base2]].rank < spells[base1].rank) { //If so, check if any new spellids with higher rank exist (live spells for this are ranked).
|
||||||
|
newbon->WeaponStance[base2] = base1; //Overwrite with new effect
|
||||||
|
SetWeaponStanceEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newbon->WeaponStance[base2] = base1; //If no prior effect exists, then apply
|
||||||
|
SetWeaponStanceEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SE_ExtraAttackChance:
|
case SE_ExtraAttackChance:
|
||||||
{
|
{
|
||||||
if (newbon->ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE] < base1) {
|
if (newbon->ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE] < base1) {
|
||||||
@@ -1615,6 +1660,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
case SE_TrapCircumvention:
|
case SE_TrapCircumvention:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
// not handled here
|
// not handled here
|
||||||
case SE_HastenedAASkill:
|
case SE_HastenedAASkill:
|
||||||
// not handled here but don't want to clutter debug log -- these may need to be verified to ignore
|
// not handled here but don't want to clutter debug log -- these may need to be verified to ignore
|
||||||
@@ -3470,6 +3516,26 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SE_Damage_Taken_Position_Amt:
|
||||||
|
{
|
||||||
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
|
if (base2 < 0 || base2 > 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
new_bonus->Damage_Taken_Position_Amt[base2] += effect_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SE_Melee_Damage_Position_Amt:
|
||||||
|
{
|
||||||
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
|
if (base2 < 0 || base2 > 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
new_bonus->Melee_Damage_Position_Amt[base2] += effect_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SE_DS_Mitigation_Amount:
|
case SE_DS_Mitigation_Amount:
|
||||||
new_bonus->DS_Mitigation_Amount += effect_value;
|
new_bonus->DS_Mitigation_Amount += effect_value;
|
||||||
break;
|
break;
|
||||||
@@ -3491,10 +3557,12 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
if (AdditiveWornBonus) {
|
if (AdditiveWornBonus) {
|
||||||
new_bonus->ExtendedShielding += effect_value;
|
new_bonus->ExtendedShielding += effect_value;
|
||||||
}
|
}
|
||||||
else if (effect_value < 0 && new_bonus->ExtendedShielding > effect_value)
|
else if (effect_value < 0 && new_bonus->ExtendedShielding > effect_value){
|
||||||
new_bonus->ExtendedShielding = effect_value;
|
new_bonus->ExtendedShielding = effect_value;
|
||||||
else if (effect_value > 0 && new_bonus->ExtendedShielding < effect_value)
|
}
|
||||||
|
else if (effect_value > 0 && new_bonus->ExtendedShielding < effect_value){
|
||||||
new_bonus->ExtendedShielding = effect_value;
|
new_bonus->ExtendedShielding = effect_value;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3503,10 +3571,44 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
if (AdditiveWornBonus) {
|
if (AdditiveWornBonus) {
|
||||||
new_bonus->ShieldDuration += effect_value;
|
new_bonus->ShieldDuration += effect_value;
|
||||||
}
|
}
|
||||||
else if (effect_value < 0 && new_bonus->ShieldDuration > effect_value)
|
else if (effect_value < 0 && new_bonus->ShieldDuration > effect_value){
|
||||||
new_bonus->ShieldDuration = effect_value;
|
new_bonus->ShieldDuration = effect_value;
|
||||||
else if (effect_value > 0 && new_bonus->ShieldDuration < effect_value)
|
}
|
||||||
|
else if (effect_value > 0 && new_bonus->ShieldDuration < effect_value){
|
||||||
new_bonus->ShieldDuration = effect_value;
|
new_bonus->ShieldDuration = effect_value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SE_Weapon_Stance: {
|
||||||
|
if (IsValidSpell(effect_value)) { //base1 is the spell_id of buff
|
||||||
|
if (base2 <= WEAPON_STANCE_TYPE_MAX) { //0=2H, 1=Shield, 2=DW
|
||||||
|
if (IsValidSpell(new_bonus->WeaponStance[base2])) { //Check if we already a spell_id saved for this effect
|
||||||
|
if (spells[new_bonus->WeaponStance[base2]].rank < spells[effect_value].rank) { //If so, check if any new spellids with higher rank exist (live spells for this are ranked).
|
||||||
|
new_bonus->WeaponStance[base2] = effect_value; //Overwrite with new effect
|
||||||
|
SetWeaponStanceEnabled(true);
|
||||||
|
|
||||||
|
if (WornType) {
|
||||||
|
weaponstance.itembonus_enabled = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
weaponstance.spellbonus_enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new_bonus->WeaponStance[base2] = effect_value; //If no prior effect exists, then apply
|
||||||
|
SetWeaponStanceEnabled(true);
|
||||||
|
|
||||||
|
if (WornType) {
|
||||||
|
weaponstance.itembonus_enabled = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
weaponstance.spellbonus_enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5098,21 +5200,39 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_Melee_Damage_Position_Mod:
|
case SE_Melee_Damage_Position_Mod:
|
||||||
spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] = effect_value;
|
spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
|
||||||
aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] = effect_value;
|
aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
|
||||||
itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] = effect_value;
|
itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
|
||||||
spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION] = effect_value;
|
spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION] = effect_value;
|
aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION] = effect_value;
|
itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_Damage_Taken_Position_Mod:
|
case SE_Damage_Taken_Position_Mod:
|
||||||
spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] = effect_value;
|
spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
|
||||||
aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] = effect_value;
|
aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
|
||||||
itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] = effect_value;
|
itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
|
||||||
spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION] = effect_value;
|
spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION] = effect_value;
|
aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION] = effect_value;
|
itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SE_Melee_Damage_Position_Amt:
|
||||||
|
spellbonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
|
||||||
|
aabonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
|
||||||
|
itembonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
|
||||||
|
spellbonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
|
aabonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
|
itembonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SE_Damage_Taken_Position_Amt:
|
||||||
|
spellbonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
|
||||||
|
aabonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
|
||||||
|
itembonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
|
||||||
|
spellbonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
|
aabonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
|
itembonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+217
@@ -10236,3 +10236,220 @@ void Client::SetGMStatus(int newStatus) {
|
|||||||
if (this->Admin() != newStatus)
|
if (this->Admin() != newStatus)
|
||||||
database.UpdateGMStatus(this->AccountID(), newStatus);
|
database.UpdateGMStatus(this->AccountID(), newStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::ApplyWeaponsStance()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|
||||||
|
If you have a weapons stance bonus from at least one bonus type, each time you change weapons this function will ensure the correct
|
||||||
|
associated buffs are applied, and previous buff is removed. If your weapon stance bonus is completely removed it will, ensure buff is
|
||||||
|
also removed (ie, removing an item that has worn effect with weapon stance, or clicking off a buff). If client no longer has/never had
|
||||||
|
any spells/item/aa bonuses with weapon stance effect this function will only do a simple bool check.
|
||||||
|
|
||||||
|
Note: Live like behavior is once you have the triggered buff you can manually click it off to remove it. Swaping any items in inventory will
|
||||||
|
reapply it automatically.
|
||||||
|
|
||||||
|
Only buff spells should be used as triggered spell effect. IsBuffSpell function also checks spell id validity.
|
||||||
|
WeaponStance bonus arrary: 0=2H Weapon 1=Shield 2=Dualweild
|
||||||
|
|
||||||
|
Toggling ON or OFF
|
||||||
|
- From spells, just remove the Primary buff that contains the WeaponStance effect in it.
|
||||||
|
- For items with worn effect, unequip the item.
|
||||||
|
- For AA abilities, a hotkey is used to Enable and Disable the effect. See. Client::TogglePassiveAlternativeAdvancement in aa.cpp for extensive details.
|
||||||
|
|
||||||
|
Rank
|
||||||
|
- Most important for AA, but if you have more than one of WeaponStance effect for a given type, the spell trigger buff will apply whatever has the highest
|
||||||
|
'rank' value from the spells table. AA's on live for this effect naturally do this. Be awere of this if making custom spells/worn effects/AA.
|
||||||
|
|
||||||
|
When creating weapon stance effects, you do not need to use all three types. For example, can make an effect where you only get a buff from equiping shield.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!IsWeaponStanceEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enabled = false;
|
||||||
|
bool item_bonus_exists = false;
|
||||||
|
bool aa_bonus_exists = false;
|
||||||
|
|
||||||
|
if (weaponstance.spellbonus_enabled) {
|
||||||
|
|
||||||
|
if (spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H] || spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD] ||
|
||||||
|
spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) {
|
||||||
|
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
// Check if no longer has correct combination of weapon type and buff, if so remove buff.
|
||||||
|
if (!HasTwoHanderEquipped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]) &&
|
||||||
|
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
||||||
|
}
|
||||||
|
else if (!HasShieldEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
||||||
|
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
||||||
|
}
|
||||||
|
else if (!HasDualWeaponsEquiped() &&
|
||||||
|
IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
||||||
|
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
||||||
|
}
|
||||||
|
// If you have correct combination of weapon type and bonus, and do not already have buff, then apply buff.
|
||||||
|
if (HasTwoHanderEquipped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H], this);
|
||||||
|
}
|
||||||
|
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
||||||
|
}
|
||||||
|
else if (HasShieldEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
|
||||||
|
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
||||||
|
}
|
||||||
|
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
||||||
|
}
|
||||||
|
else if (HasDualWeaponsEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
|
||||||
|
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
||||||
|
}
|
||||||
|
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spellbonus effect removal is checked in BuffFadeBySlot(int slot, bool iRecalcBonuses) in spell_effects.cpp when the buff is clicked off or fades.
|
||||||
|
|
||||||
|
if (weaponstance.itembonus_enabled) {
|
||||||
|
|
||||||
|
if (itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H] || itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD] ||
|
||||||
|
itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) {
|
||||||
|
|
||||||
|
enabled = true;
|
||||||
|
item_bonus_exists = true;
|
||||||
|
|
||||||
|
|
||||||
|
// Edge case check if have multiple items with WeaponStance worn effect. Make sure correct buffs are applied if items are removed but others left on.
|
||||||
|
if (weaponstance.itembonus_buff_spell_id) {
|
||||||
|
|
||||||
|
bool buff_desync = true;
|
||||||
|
if (weaponstance.itembonus_buff_spell_id == itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H] ||
|
||||||
|
weaponstance.itembonus_buff_spell_id == itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD] ||
|
||||||
|
(weaponstance.itembonus_buff_spell_id == itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
buff_desync = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buff_desync) {
|
||||||
|
int fade_spell = weaponstance.itembonus_buff_spell_id;
|
||||||
|
weaponstance.itembonus_buff_spell_id = 0; //Need to zero this before we fade to prevent any recursive loops.
|
||||||
|
BuffFadeBySpellID(fade_spell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if no longer has correct combination of weapon type and buff, if so remove buff.
|
||||||
|
if (!HasTwoHanderEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]) &&
|
||||||
|
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
||||||
|
}
|
||||||
|
else if (!HasShieldEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
||||||
|
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
||||||
|
}
|
||||||
|
else if (!HasDualWeaponsEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
||||||
|
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you have correct combination of weapon type and bonus, and do not already have buff, then apply buff.
|
||||||
|
if (HasTwoHanderEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
|
||||||
|
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H], this);
|
||||||
|
}
|
||||||
|
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
||||||
|
}
|
||||||
|
else if (HasShieldEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
|
||||||
|
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
||||||
|
}
|
||||||
|
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
||||||
|
}
|
||||||
|
else if (HasDualWeaponsEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
||||||
|
}
|
||||||
|
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Itembonus effect removal when item is removed
|
||||||
|
if (!item_bonus_exists && weaponstance.itembonus_enabled) {
|
||||||
|
weaponstance.itembonus_enabled = false;
|
||||||
|
|
||||||
|
if (weaponstance.itembonus_buff_spell_id) {
|
||||||
|
BuffFadeBySpellID(weaponstance.itembonus_buff_spell_id);
|
||||||
|
weaponstance.itembonus_buff_spell_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weaponstance.aabonus_enabled) {
|
||||||
|
|
||||||
|
if (aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H] || aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD] ||
|
||||||
|
aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) {
|
||||||
|
|
||||||
|
enabled = true;
|
||||||
|
aa_bonus_exists = true;
|
||||||
|
|
||||||
|
//Check if no longer has correct combination of weapon type and buff, if so remove buff.
|
||||||
|
if (!HasTwoHanderEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]) &&
|
||||||
|
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!HasShieldEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
||||||
|
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!HasDualWeaponsEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
||||||
|
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If you have correct combination of weapon type and bonus, and do not already have buff, then apply buff.
|
||||||
|
if (HasTwoHanderEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
|
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H], this);
|
||||||
|
}
|
||||||
|
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (HasShieldEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
||||||
|
}
|
||||||
|
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (HasDualWeaponsEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
|
||||||
|
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
||||||
|
}
|
||||||
|
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AA bonus removal is checked in TogglePassiveAA in aa.cpp. when the hot key is toggled.
|
||||||
|
|
||||||
|
// If no bonuses remain present, prevent additional future checks until new bonus is applied.
|
||||||
|
if (!enabled) {
|
||||||
|
SetWeaponStanceEnabled(false);
|
||||||
|
weaponstance.aabonus_enabled = false;
|
||||||
|
weaponstance.itembonus_enabled = false;
|
||||||
|
weaponstance.spellbonus_enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1554,6 +1554,13 @@ public:
|
|||||||
|
|
||||||
void ShowNumHits(); // work around function for numhits not showing on buffs
|
void ShowNumHits(); // work around function for numhits not showing on buffs
|
||||||
|
|
||||||
|
void ApplyWeaponsStance();
|
||||||
|
void TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ability_id);
|
||||||
|
bool UseTogglePassiveHotkey(const AA::Rank &rank);
|
||||||
|
void TogglePurchaseAlternativeAdvancementRank(int rank_id);
|
||||||
|
void ResetAlternateAdvancementRank(uint32 aa_id);
|
||||||
|
bool IsEffectinAlternateAdvancementRankEffects(const AA::Rank &rank, int effect_id);
|
||||||
|
|
||||||
void TripInterrogateInvState() { interrogateinv_flag = true; }
|
void TripInterrogateInvState() { interrogateinv_flag = true; }
|
||||||
bool GetInterrogateInvState() { return interrogateinv_flag; }
|
bool GetInterrogateInvState() { return interrogateinv_flag; }
|
||||||
|
|
||||||
|
|||||||
@@ -1717,6 +1717,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
/* Task Packets */
|
/* Task Packets */
|
||||||
LoadClientTaskState();
|
LoadClientTaskState();
|
||||||
|
|
||||||
|
ApplyWeaponsStance();
|
||||||
|
|
||||||
m_expedition_id = ExpeditionsRepository::GetIDByMemberID(database, CharacterID());
|
m_expedition_id = ExpeditionsRepository::GetIDByMemberID(database, CharacterID());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+23
-2
@@ -104,6 +104,8 @@
|
|||||||
#define PET_BUTTON_SPELLHOLD 9
|
#define PET_BUTTON_SPELLHOLD 9
|
||||||
|
|
||||||
#define AURA_HARDCAP 2
|
#define AURA_HARDCAP 2
|
||||||
|
#define WEAPON_STANCE_TYPE_MAX 2
|
||||||
|
|
||||||
|
|
||||||
#define SHIELD_ABILITY_RECAST_TIME 180
|
#define SHIELD_ABILITY_RECAST_TIME 180
|
||||||
|
|
||||||
@@ -540,11 +542,15 @@ struct StatBonuses {
|
|||||||
int32 AC_Avoidance_Max_Percent; // Increase AC avoidance by percent
|
int32 AC_Avoidance_Max_Percent; // Increase AC avoidance by percent
|
||||||
int32 Damage_Taken_Position_Mod[2]; // base = percent melee damage reduction base2 0=back 1=front. [0]Back[1]Front
|
int32 Damage_Taken_Position_Mod[2]; // base = percent melee damage reduction base2 0=back 1=front. [0]Back[1]Front
|
||||||
int32 Melee_Damage_Position_Mod[2]; // base = percent melee damage increase base2 0=back 1=front. [0]Back[1]Front
|
int32 Melee_Damage_Position_Mod[2]; // base = percent melee damage increase base2 0=back 1=front. [0]Back[1]Front
|
||||||
|
int32 Damage_Taken_Position_Amt[2]; // base = flat amt melee damage reduction base2 0=back 1=front. [0]Back[1]Front
|
||||||
|
int32 Melee_Damage_Position_Amt[2]; // base = flat amt melee damage increase base2 0=back 1=front. [0]Back[1]Front
|
||||||
int32 Double_Backstab_Front; // base = percent chance to double back stab front
|
int32 Double_Backstab_Front; // base = percent chance to double back stab front
|
||||||
int32 DS_Mitigation_Amount; // base = flat amt DS mitigation. Negative value to reduce
|
int32 DS_Mitigation_Amount; // base = flat amt DS mitigation. Negative value to reduce
|
||||||
int32 DS_Mitigation_Percentage; // base = percent amt of DS mitigation. Negative value to reduce
|
int32 DS_Mitigation_Percentage; // base = percent amt of DS mitigation. Negative value to reduce
|
||||||
int32 Pet_Crit_Melee_Damage_Pct_Owner; // base = percent mod for pet critcal damage from owner
|
int32 Pet_Crit_Melee_Damage_Pct_Owner; // base = percent mod for pet critcal damage from owner
|
||||||
int32 Pet_Add_Atk; // base = Pet ATK bonus from owner
|
int32 Pet_Add_Atk; // base = Pet ATK bonus from owner
|
||||||
|
int32 WeaponStance[WEAPON_STANCE_TYPE_MAX +1];// base = trigger spell id, base2 = 0 is 2h, 1 is shield, 2 is dual wield, [0]spid 2h, [1]spid shield, [2]spid DW
|
||||||
|
|
||||||
|
|
||||||
// AAs
|
// AAs
|
||||||
int32 ShieldDuration; // extends duration of /shield ability
|
int32 ShieldDuration; // extends duration of /shield ability
|
||||||
@@ -651,8 +657,8 @@ namespace SBIndex {
|
|||||||
constexpr uint16 ROOT_BUFFSLOT = 1; // SPA 99
|
constexpr uint16 ROOT_BUFFSLOT = 1; // SPA 99
|
||||||
constexpr uint16 RUNE_AMOUNT = 0; // SPA 55
|
constexpr uint16 RUNE_AMOUNT = 0; // SPA 55
|
||||||
constexpr uint16 RUNE_BUFFSLOT = 1; // SPA 78
|
constexpr uint16 RUNE_BUFFSLOT = 1; // SPA 78
|
||||||
constexpr uint16 POSITIONAL_DAMAGE_MOD = 0; // SPA 503-506
|
constexpr uint16 POSITION_BACK = 0; // SPA 503-506
|
||||||
constexpr uint16 POSITIONAL_LOCATION = 1; // SPA 503-506
|
constexpr uint16 POSITION_FRONT = 1; // SPA 503-506
|
||||||
constexpr uint16 PET_RAMPAGE_CHANCE = 0; // SPA 464,465
|
constexpr uint16 PET_RAMPAGE_CHANCE = 0; // SPA 464,465
|
||||||
constexpr uint16 PET_RAMPAGE_DMG_MOD = 1; // SPA 465,465
|
constexpr uint16 PET_RAMPAGE_DMG_MOD = 1; // SPA 465,465
|
||||||
constexpr uint16 SKILLPROC_CHANCE = 0; // SPA 427
|
constexpr uint16 SKILLPROC_CHANCE = 0; // SPA 427
|
||||||
@@ -678,6 +684,21 @@ typedef struct
|
|||||||
int level_override;
|
int level_override;
|
||||||
} tProc;
|
} tProc;
|
||||||
|
|
||||||
|
|
||||||
|
struct WeaponStance_Struct {
|
||||||
|
bool enabled;
|
||||||
|
bool spellbonus_enabled;
|
||||||
|
bool itembonus_enabled;
|
||||||
|
bool aabonus_enabled;
|
||||||
|
int spellbonus_buff_spell_id;
|
||||||
|
int itembonus_buff_spell_id;
|
||||||
|
int aabonus_buff_spell_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint16 WEAPON_STANCE_TYPE_2H = 0;
|
||||||
|
constexpr uint16 WEAPON_STANCE_TYPE_SHIELD = 1;
|
||||||
|
constexpr uint16 WEAPON_STANCE_TYPE_DUAL_WIELD = 2;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16 increment;
|
uint16 increment;
|
||||||
|
|||||||
@@ -2026,6 +2026,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
|||||||
|
|
||||||
// Step 8: Re-calc stats
|
// Step 8: Re-calc stats
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
|
ApplyWeaponsStance();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+60
-4
@@ -234,6 +234,7 @@ Mob::Mob(
|
|||||||
has_shieldequiped = false;
|
has_shieldequiped = false;
|
||||||
has_twohandbluntequiped = false;
|
has_twohandbluntequiped = false;
|
||||||
has_twohanderequipped = false;
|
has_twohanderequipped = false;
|
||||||
|
has_duelweaponsequiped = false;
|
||||||
can_facestab = false;
|
can_facestab = false;
|
||||||
has_numhits = false;
|
has_numhits = false;
|
||||||
has_MGB = false;
|
has_MGB = false;
|
||||||
@@ -409,6 +410,14 @@ Mob::Mob(
|
|||||||
viral_spells[i] = 0;
|
viral_spells[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
weaponstance.enabled = false;
|
||||||
|
weaponstance.spellbonus_enabled = false; //Set when bonus is applied
|
||||||
|
weaponstance.itembonus_enabled = false; //Set when bonus is applied
|
||||||
|
weaponstance.aabonus_enabled = false; //Controlled by function TogglePassiveAA
|
||||||
|
weaponstance.spellbonus_buff_spell_id = 0;
|
||||||
|
weaponstance.itembonus_buff_spell_id = 0;
|
||||||
|
weaponstance.aabonus_buff_spell_id = 0;
|
||||||
|
|
||||||
pStandingPetOrder = SPO_Follow;
|
pStandingPetOrder = SPO_Follow;
|
||||||
pseudo_rooted = false;
|
pseudo_rooted = false;
|
||||||
|
|
||||||
@@ -3857,8 +3866,8 @@ int32 Mob::GetPositionalDmgTaken(Mob *attacker)
|
|||||||
int back_arc = 0;
|
int back_arc = 0;
|
||||||
int total_mod = 0;
|
int total_mod = 0;
|
||||||
|
|
||||||
back_arc += itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] + aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] + spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD];
|
back_arc += itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] + aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] + spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK];
|
||||||
front_arc += itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION] + aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION] + spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITIONAL_LOCATION];
|
front_arc += itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] + aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] + spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT];
|
||||||
|
|
||||||
if (back_arc || front_arc) { //Do they have this bonus?
|
if (back_arc || front_arc) { //Do they have this bonus?
|
||||||
if (attacker->BehindMob(this, attacker->GetX(), attacker->GetY()))//Check if attacker is striking from behind
|
if (attacker->BehindMob(this, attacker->GetX(), attacker->GetY()))//Check if attacker is striking from behind
|
||||||
@@ -3875,6 +3884,29 @@ int32 Mob::GetPositionalDmgTaken(Mob *attacker)
|
|||||||
return total_mod;
|
return total_mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 Mob::GetPositionalDmgTakenAmt(Mob *attacker)
|
||||||
|
{
|
||||||
|
if (!attacker)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int front_arc = 0;
|
||||||
|
int back_arc = 0;
|
||||||
|
int total_amt = 0;
|
||||||
|
|
||||||
|
back_arc += itembonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] + aabonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] + spellbonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK];
|
||||||
|
front_arc += itembonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] + aabonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] + spellbonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT];
|
||||||
|
|
||||||
|
if (back_arc || front_arc) {
|
||||||
|
if (attacker->BehindMob(this, attacker->GetX(), attacker->GetY()))
|
||||||
|
total_amt = back_arc;
|
||||||
|
else
|
||||||
|
total_amt = front_arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_amt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int16 Mob::GetHealRate(uint16 spell_id, Mob* caster) {
|
int16 Mob::GetHealRate(uint16 spell_id, Mob* caster) {
|
||||||
|
|
||||||
int16 heal_rate = 0;
|
int16 heal_rate = 0;
|
||||||
@@ -4851,8 +4883,8 @@ int16 Mob::GetMeleeDmgPositionMod(Mob* defender)
|
|||||||
int back_arc = 0;
|
int back_arc = 0;
|
||||||
int total_mod = 0;
|
int total_mod = 0;
|
||||||
|
|
||||||
back_arc += itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] + aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD] + spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_DAMAGE_MOD];
|
back_arc += itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] + aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] + spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK];
|
||||||
front_arc += itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION] + aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION] + spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITIONAL_LOCATION];
|
front_arc += itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] + aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] + spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT];
|
||||||
|
|
||||||
if (back_arc || front_arc) { //Do they have this bonus?
|
if (back_arc || front_arc) { //Do they have this bonus?
|
||||||
if (BehindMob(defender, GetX(), GetY()))//Check if attacker is striking from behind
|
if (BehindMob(defender, GetX(), GetY()))//Check if attacker is striking from behind
|
||||||
@@ -4891,6 +4923,30 @@ int16 Mob::GetSkillDmgAmt(uint16 skill)
|
|||||||
return skill_dmg;
|
return skill_dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16 Mob::GetPositionalDmgAmt(Mob* defender)
|
||||||
|
{
|
||||||
|
if (!defender)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
//SPA 504
|
||||||
|
int front_arc_dmg_amt = 0;
|
||||||
|
int back_arc_dmg_amt = 0;
|
||||||
|
|
||||||
|
int total_amt = 0;
|
||||||
|
|
||||||
|
back_arc_dmg_amt += itembonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] + aabonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] + spellbonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK];
|
||||||
|
front_arc_dmg_amt += itembonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] + aabonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] + spellbonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT];
|
||||||
|
|
||||||
|
if (back_arc_dmg_amt || front_arc_dmg_amt) {
|
||||||
|
if (BehindMob(defender, GetX(), GetY()))
|
||||||
|
total_amt = back_arc_dmg_amt;
|
||||||
|
else
|
||||||
|
total_amt = front_arc_dmg_amt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_amt;
|
||||||
|
}
|
||||||
|
|
||||||
void Mob::MeleeLifeTap(int32 damage) {
|
void Mob::MeleeLifeTap(int32 damage) {
|
||||||
|
|
||||||
int32 lifetap_amt = 0;
|
int32 lifetap_amt = 0;
|
||||||
|
|||||||
+10
@@ -432,6 +432,8 @@ public:
|
|||||||
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
|
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
|
||||||
bool HasTwoHanderEquipped() { return has_twohanderequipped; }
|
bool HasTwoHanderEquipped() { return has_twohanderequipped; }
|
||||||
void SetTwoHanderEquipped(bool val) { has_twohanderequipped = val; }
|
void SetTwoHanderEquipped(bool val) { has_twohanderequipped = val; }
|
||||||
|
bool HasDualWeaponsEquiped() const { return has_duelweaponsequiped; }
|
||||||
|
inline void SetDuelWeaponsEquiped(bool val) { has_duelweaponsequiped = val; }
|
||||||
bool CanFacestab() { return can_facestab; }
|
bool CanFacestab() { return can_facestab; }
|
||||||
void SetFacestab(bool val) { can_facestab = val; }
|
void SetFacestab(bool val) { can_facestab = val; }
|
||||||
virtual uint16 GetSkill(EQ::skills::SkillType skill_num) const { return 0; }
|
virtual uint16 GetSkill(EQ::skills::SkillType skill_num) const { return 0; }
|
||||||
@@ -804,6 +806,7 @@ public:
|
|||||||
int32 GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spell_id);
|
int32 GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spell_id);
|
||||||
int32 GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts = nullptr);
|
int32 GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts = nullptr);
|
||||||
int32 GetPositionalDmgTaken(Mob *attacker);
|
int32 GetPositionalDmgTaken(Mob *attacker);
|
||||||
|
int32 GetPositionalDmgTakenAmt(Mob *attacker);
|
||||||
void DoKnockback(Mob *caster, uint32 pushback, uint32 pushup);
|
void DoKnockback(Mob *caster, uint32 pushback, uint32 pushup);
|
||||||
int16 CalcResistChanceBonus();
|
int16 CalcResistChanceBonus();
|
||||||
int16 CalcFearResistChance();
|
int16 CalcFearResistChance();
|
||||||
@@ -821,6 +824,7 @@ public:
|
|||||||
int16 GetSkillReuseTime(uint16 skill);
|
int16 GetSkillReuseTime(uint16 skill);
|
||||||
int GetCriticalChanceBonus(uint16 skill);
|
int GetCriticalChanceBonus(uint16 skill);
|
||||||
int16 GetSkillDmgAmt(uint16 skill);
|
int16 GetSkillDmgAmt(uint16 skill);
|
||||||
|
int16 GetPositionalDmgAmt(Mob* defender);
|
||||||
bool TryReflectSpell(uint32 spell_id);
|
bool TryReflectSpell(uint32 spell_id);
|
||||||
inline bool CanBlockSpell() const { return(spellbonuses.FocusEffects[focusBlockNextSpell]); }
|
inline bool CanBlockSpell() const { return(spellbonuses.FocusEffects[focusBlockNextSpell]); }
|
||||||
bool DoHPToManaCovert(uint16 mana_cost = 0);
|
bool DoHPToManaCovert(uint16 mana_cost = 0);
|
||||||
@@ -1140,6 +1144,11 @@ public:
|
|||||||
inline int GetMaxShielderDistance() const { return shielder_max_distance; }
|
inline int GetMaxShielderDistance() const { return shielder_max_distance; }
|
||||||
inline void SetShielerMaxDistance(int val) { shielder_max_distance = val; }
|
inline void SetShielerMaxDistance(int val) { shielder_max_distance = val; }
|
||||||
|
|
||||||
|
WeaponStance_Struct weaponstance;
|
||||||
|
bool IsWeaponStanceEnabled() const { return weaponstance.enabled; }
|
||||||
|
inline void SetWeaponStanceEnabled(bool val) { weaponstance.enabled = val; }
|
||||||
|
|
||||||
|
|
||||||
inline glm::vec4 GetCurrentWayPoint() const { return m_CurrentWayPoint; }
|
inline glm::vec4 GetCurrentWayPoint() const { return m_CurrentWayPoint; }
|
||||||
inline float GetCWPP() const { return(static_cast<float>(cur_wp_pause)); }
|
inline float GetCWPP() const { return(static_cast<float>(cur_wp_pause)); }
|
||||||
inline int GetCWP() const { return(cur_wp); }
|
inline int GetCWP() const { return(cur_wp); }
|
||||||
@@ -1506,6 +1515,7 @@ protected:
|
|||||||
bool has_shieldequiped;
|
bool has_shieldequiped;
|
||||||
bool has_twohandbluntequiped;
|
bool has_twohandbluntequiped;
|
||||||
bool has_twohanderequipped;
|
bool has_twohanderequipped;
|
||||||
|
bool has_duelweaponsequiped;
|
||||||
bool can_facestab;
|
bool can_facestab;
|
||||||
bool has_numhits;
|
bool has_numhits;
|
||||||
bool has_MGB;
|
bool has_MGB;
|
||||||
|
|||||||
+20
-1
@@ -2959,7 +2959,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
int shld_target_mitigation = spells[spell_id].base2[i] ? spells[spell_id].base2[i] : 50;
|
int shld_target_mitigation = spells[spell_id].base2[i] ? spells[spell_id].base2[i] : 50;
|
||||||
int shlder_mitigation = spells[spell_id].max[i] ? spells[spell_id].base2[i] : 50;
|
int shlder_mitigation = spells[spell_id].max[i] ? spells[spell_id].base2[i] : 50;
|
||||||
ShieldAbility(petowner->GetID(), 25, shield_duration, shld_target_mitigation, shlder_mitigation);
|
ShieldAbility(petowner->GetID(), 25, shield_duration, shld_target_mitigation, shlder_mitigation);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SE_Weapon_Stance: {
|
||||||
|
if (IsClient()) {
|
||||||
|
CastToClient()->ApplyWeaponsStance();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3218,6 +3223,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
case SE_Critical_Melee_Damage_Mod_Max:
|
case SE_Critical_Melee_Damage_Mod_Max:
|
||||||
case SE_Melee_Damage_Position_Mod:
|
case SE_Melee_Damage_Position_Mod:
|
||||||
case SE_Damage_Taken_Position_Mod:
|
case SE_Damage_Taken_Position_Mod:
|
||||||
|
case SE_Melee_Damage_Position_Amt:
|
||||||
|
case SE_Damage_Taken_Position_Amt:
|
||||||
case SE_DS_Mitigation_Amount:
|
case SE_DS_Mitigation_Amount:
|
||||||
case SE_DS_Mitigation_Percentage:
|
case SE_DS_Mitigation_Percentage:
|
||||||
case SE_Double_Backstab_Front:
|
case SE_Double_Backstab_Front:
|
||||||
@@ -3242,6 +3249,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
case SE_AddExtraAttackPct_1h_Primary:
|
case SE_AddExtraAttackPct_1h_Primary:
|
||||||
case SE_AddExtraAttackPct_1h_Secondary:
|
case SE_AddExtraAttackPct_1h_Secondary:
|
||||||
case SE_Skill_Base_Damage_Mod:
|
case SE_Skill_Base_Damage_Mod:
|
||||||
|
case SE_Buy_AA_Rank:
|
||||||
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -4372,6 +4380,17 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SE_Weapon_Stance:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If we click off the spell buff (or fades naturally) giving us
|
||||||
|
Weapon Stance effects it should remove all associated buff.
|
||||||
|
*/
|
||||||
|
if (weaponstance.spellbonus_buff_spell_id) {
|
||||||
|
BuffFadeBySpellID(weaponstance.spellbonus_buff_spell_id);
|
||||||
|
}
|
||||||
|
weaponstance.spellbonus_enabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6598,7 +6617,7 @@ bool Mob::TryDivineSave()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellOnTarget(4789, this); //Touch of the Divine=4789, an Invulnerability/HoT/Purify effect
|
SpellOnTarget(SPELL_TOUCH_OF_THE_DIVINE, this); //Touch of the Divine=4789, an Invulnerability/HoT/Purify effect
|
||||||
SendHPUpdate();
|
SendHPUpdate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user