mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Spells] Implemented SPA 476 SE_Weapons_Stance and Live-like AA Enable/Disable Toggle (#1477)
* Work started on SPA 476 defines * bonus structure add bonus structure set up * updates spa476 updates spa476 * spell bonus now functional spell bonus working well. * major update with debug messages aa, item and spell now working * Pre clean up, effect implemented working for AA, spells, items, all checked for stacking issues. * removed debug messages removed debug messages * spdat description added spdat description added * minor fix removed debug shout removed unneeded code check. * syntax updates, minor fixes syntax updates, minor fixes * syntax fixes syntax fixes * improvements to code moved function to check at swap item. Easier to manage and more live like behavior. Required minor adjustment Still working on AA toggle. * updates to aa buy, functionalish * Syntax / Formatting * Add break / default to switch * updates * completed v2 * Major revisions Main function check moved to when items are swapped and out of when ever bonus are recalculated. AA Toggle and data structure now more accurate to live. * Update aa.cpp * debug removed * implemented SE_Buy_AA_Rank Closer to live. * Update aa.cpp broadening AA toggle to be more general use. * improved various checks aa toggle is now broadly implemented to be usable with any passive effect. Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
parent
c69446c460
commit
51ad6d65dc
@ -1236,6 +1236,7 @@ bool IsEffectIgnoredInStacking(int spa)
|
||||
case SE_Ff_CasterClass:
|
||||
case SE_Ff_Same_Caster:
|
||||
case SE_Proc_Timer_Modifier:
|
||||
case SE_Weapon_Stance:
|
||||
case SE_TwinCastBlocker:
|
||||
case SE_Fc_CastTimeAmt:
|
||||
case SE_Fc_CastTimeMod2:
|
||||
|
||||
@ -64,6 +64,7 @@
|
||||
#define SPELL_SHAPECHANGE70 6503
|
||||
#define SPELL_MANA_BURN 2751
|
||||
#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
|
||||
#define SPELL_THE_DAINS_JUSTICE 1476
|
||||
#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_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_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_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_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_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
|
||||
|
||||
208
zone/aa.cpp
208
zone/aa.cpp
@ -1162,6 +1162,7 @@ void Client::IncrementAlternateAdvancementRank(int rank_id) {
|
||||
|
||||
void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
||||
AA::Rank *rank = zone->GetAlternateAdvancementRank(rank_id);
|
||||
|
||||
if(!rank) {
|
||||
return;
|
||||
}
|
||||
@ -1178,9 +1179,11 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
||||
if(!CanUseAlternateAdvancementRank(rank)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool use_toggle_passive_hotkey = UseTogglePassiveHotkey(*rank);
|
||||
|
||||
//make sure it is not a passive
|
||||
if(!rank->effects.empty()) {
|
||||
if(!rank->effects.empty() && !use_toggle_passive_hotkey) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1188,7 +1191,6 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
||||
// We don't have the AA
|
||||
if (!GetAA(rank_id, &charges))
|
||||
return;
|
||||
|
||||
//if expendable make sure we have charges
|
||||
if(ability->charges > 0 && charges < 1)
|
||||
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(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;
|
||||
if (use_toggle_passive_hotkey) {
|
||||
TogglePassiveAlternativeAdvancement(*rank, ability->id);
|
||||
}
|
||||
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 {
|
||||
if(!CastSpell(rank->spell, target_id, EQ::spells::CastingSlot::AltAbility, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, nullptr, rank->id)) {
|
||||
return;
|
||||
else {
|
||||
if (!CastSpell(rank->spell, target_id, EQ::spells::CastingSlot::AltAbility, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, nullptr, rank->id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1287,16 +1295,16 @@ int Mob::GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in) {
|
||||
}
|
||||
|
||||
void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
||||
for(auto &iter : aa_ranks) {
|
||||
for (auto &iter : aa_ranks) {
|
||||
AA::Ability *ability = zone->GetAlternateAdvancementAbility(iter.first);
|
||||
if(ability && aa_id == ability->id) {
|
||||
if(iter.second.second > 0) {
|
||||
if (ability && aa_id == ability->id) {
|
||||
if (iter.second.second > 0) {
|
||||
iter.second.second -= 1;
|
||||
|
||||
if(iter.second.second == 0) {
|
||||
if(IsClient()) {
|
||||
if (iter.second.second == 0) {
|
||||
if (IsClient()) {
|
||||
AA::Rank *r = ability->GetRankByPointsSpent(iter.second.first);
|
||||
if(r) {
|
||||
if (r) {
|
||||
CastToClient()->GetEPP().expended_aa += r->cost;
|
||||
}
|
||||
}
|
||||
@ -1307,7 +1315,7 @@ void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
||||
aa_ranks.erase(iter.first);
|
||||
}
|
||||
|
||||
if(IsClient()) {
|
||||
if (IsClient()) {
|
||||
Client *c = CastToClient();
|
||||
c->SaveAA();
|
||||
c->SendAlternateAdvancementPoints();
|
||||
@ -1796,3 +1804,169 @@ bool Mob::CheckAATimer(int timer)
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -154,6 +154,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
|
||||
SetShieldEquiped(false);
|
||||
SetTwoHandBluntEquiped(false);
|
||||
SetTwoHanderEquipped(false);
|
||||
SetDuelWeaponsEquiped(false);
|
||||
|
||||
unsigned int i;
|
||||
// Update: MainAmmo should only calc skill mods (TODO: Check for other cases)
|
||||
@ -171,8 +172,13 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
|
||||
SetTwoHandBluntEquiped(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);
|
||||
}
|
||||
}
|
||||
|
||||
if (CanThisClassDualWield()) {
|
||||
SetDuelWeaponsEquiped(true);
|
||||
}
|
||||
|
||||
//tribute items
|
||||
@ -1555,6 +1561,25 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
newbon->Pet_Add_Atk += base1;
|
||||
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:
|
||||
{
|
||||
if (newbon->ExtraAttackChance[SBIndex::EXTRA_ATTACK_CHANCE] < base1) {
|
||||
@ -1583,6 +1608,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// to do
|
||||
case SE_PetDiscipline:
|
||||
break;
|
||||
@ -1603,6 +1629,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
case SE_TrapCircumvention:
|
||||
break;
|
||||
|
||||
|
||||
// not handled here
|
||||
case SE_HastenedAASkill:
|
||||
// not handled here but don't want to clutter debug log -- these may need to be verified to ignore
|
||||
@ -3474,6 +3501,38 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
new_bonus->Pet_Add_Atk += 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;
|
||||
}
|
||||
|
||||
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
||||
if (IsAISpellEffect) {
|
||||
|
||||
|
||||
241
zone/client.cpp
241
zone/client.cpp
@ -1412,7 +1412,7 @@ bool Client::UpdateLDoNPoints(uint32 theme_id, int points) {
|
||||
mmc_points += (mir_points + m_pp.ldon_points_mir);
|
||||
mir_points = (0 - m_pp.ldon_points_mir);
|
||||
}
|
||||
|
||||
|
||||
if(m_pp.ldon_points_mmc < (0 - mmc_points)) {
|
||||
ruj_points += (mmc_points + m_pp.ldon_points_mmc);
|
||||
mmc_points = (0 - m_pp.ldon_points_mmc);
|
||||
@ -2419,9 +2419,9 @@ bool Client::CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who,
|
||||
parse->EventPlayer(EVENT_USE_SKILL, this, buffer, 0);
|
||||
if (against_who) {
|
||||
if (
|
||||
against_who->GetSpecialAbility(IMMUNE_AGGRO) ||
|
||||
against_who->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) ||
|
||||
against_who->IsClient() ||
|
||||
against_who->GetSpecialAbility(IMMUNE_AGGRO) ||
|
||||
against_who->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) ||
|
||||
against_who->IsClient() ||
|
||||
GetLevelCon(against_who->GetLevel()) == CON_GRAY
|
||||
) {
|
||||
//false by default
|
||||
@ -9966,7 +9966,7 @@ void Client::MovePCDynamicZone(const std::string& zone_name, int zone_version, b
|
||||
MovePCDynamicZone(zone_id, zone_version, msg_if_invalid);
|
||||
}
|
||||
|
||||
void Client::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clipping) {
|
||||
void Client::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clipping) {
|
||||
BuffFadeByEffect(SE_Levitate);
|
||||
if (CheckLosFN(target_x, target_y, target_z, 6.0f) || ignore_los) {
|
||||
auto outapp_fling = new EQApplicationPacket(OP_Fling, sizeof(fling_struct));
|
||||
@ -9975,7 +9975,7 @@ void Client::Fling(float value, float target_x, float target_y, float target_z,
|
||||
flingTo->collision = 0;
|
||||
else
|
||||
flingTo->collision = -1;
|
||||
|
||||
|
||||
flingTo->travel_time = -1;
|
||||
flingTo->unk3 = 1;
|
||||
flingTo->disable_fall_damage = 1;
|
||||
@ -10030,7 +10030,7 @@ std::vector<int> Client::GetLearnableDisciplines(uint8 min_level, uint8 max_leve
|
||||
if (learnable) {
|
||||
learnable_disciplines.push_back(spell_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return learnable_disciplines;
|
||||
}
|
||||
|
||||
@ -10040,7 +10040,7 @@ std::vector<int> Client::GetLearnedDisciplines() {
|
||||
if (IsValidSpell(m_pp.disciplines.values[index])) {
|
||||
learned_disciplines.push_back(m_pp.disciplines.values[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return learned_disciplines;
|
||||
}
|
||||
|
||||
@ -10050,7 +10050,7 @@ std::vector<int> Client::GetMemmedSpells() {
|
||||
if (IsValidSpell(m_pp.mem_spells[index])) {
|
||||
memmed_spells.push_back(m_pp.mem_spells[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return memmed_spells;
|
||||
}
|
||||
|
||||
@ -10096,7 +10096,7 @@ std::vector<int> Client::GetScribeableSpells(uint8 min_level, uint8 max_level) {
|
||||
if (scribeable) {
|
||||
scribeable_spells.push_back(spell_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return scribeable_spells;
|
||||
}
|
||||
|
||||
@ -10174,7 +10174,7 @@ void Client::SendToInstance(std::string instance_type, std::string zone_short_na
|
||||
return;
|
||||
}
|
||||
|
||||
DataBucket::SetData(full_bucket_name, itoa(instance_id), itoa(duration));
|
||||
DataBucket::SetData(full_bucket_name, itoa(instance_id), itoa(duration));
|
||||
}
|
||||
|
||||
AssignToInstance(instance_id);
|
||||
@ -10221,7 +10221,7 @@ void Client::RemoveItem(uint32 item_id, uint32 quantity)
|
||||
};
|
||||
int removed_count = 0;
|
||||
const size_t size = sizeof(slots) / sizeof(slots[0]);
|
||||
for (int slot_index = 0; slot_index < size; ++slot_index) {
|
||||
for (int slot_index = 0; slot_index < size; ++slot_index) {
|
||||
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
|
||||
if (removed_count == quantity) {
|
||||
break;
|
||||
@ -10249,3 +10249,220 @@ void Client::SetGMStatus(int newStatus) {
|
||||
if (this->Admin() != 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 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; }
|
||||
bool GetInterrogateInvState() { return interrogateinv_flag; }
|
||||
|
||||
|
||||
@ -1717,6 +1717,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
/* Task Packets */
|
||||
LoadClientTaskState();
|
||||
|
||||
ApplyWeaponsStance();
|
||||
|
||||
m_expedition_id = ExpeditionsRepository::GetIDByMemberID(database, CharacterID());
|
||||
|
||||
/**
|
||||
|
||||
@ -106,6 +106,8 @@
|
||||
#define PET_BUTTON_SPELLHOLD 9
|
||||
|
||||
#define AURA_HARDCAP 2
|
||||
#define WEAPON_STANCE_TYPE_MAX 2
|
||||
|
||||
|
||||
typedef enum { //focus types
|
||||
focusSpellHaste = 1, //@Fc, SPA: 127, SE_IncreaseSpellHaste, On Caster, cast time mod pct, base: pct
|
||||
@ -325,7 +327,7 @@ struct Buffs_Struct {
|
||||
int32 ExtraDIChance;
|
||||
int16 RootBreakChance; //Not saved to dbase
|
||||
uint32 instrument_mod;
|
||||
int16 focusproclimit_time; //timer to limit number of procs from focus effects
|
||||
int16 focusproclimit_time; //timer to limit number of procs from focus effects
|
||||
int16 focusproclimit_procamt; //amount of procs that can be cast before timer limiter is set
|
||||
bool persistant_buff;
|
||||
bool client; //True if the caster is a client
|
||||
@ -545,7 +547,7 @@ struct StatBonuses {
|
||||
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_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
|
||||
int8 Packrat; //weight reduction for items, 1 point = 10%
|
||||
@ -682,6 +684,20 @@ struct Shielders_Struct {
|
||||
uint16 shielder_bonus;
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
uint16 increment;
|
||||
|
||||
@ -2026,6 +2026,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
|
||||
// Step 8: Re-calc stats
|
||||
CalcBonuses();
|
||||
ApplyWeaponsStance();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -234,6 +234,7 @@ Mob::Mob(
|
||||
has_shieldequiped = false;
|
||||
has_twohandbluntequiped = false;
|
||||
has_twohanderequipped = false;
|
||||
has_duelweaponsequiped = false;
|
||||
can_facestab = false;
|
||||
has_numhits = false;
|
||||
has_MGB = false;
|
||||
@ -408,6 +409,14 @@ Mob::Mob(
|
||||
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;
|
||||
pseudo_rooted = false;
|
||||
|
||||
|
||||
@ -432,6 +432,8 @@ public:
|
||||
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
|
||||
bool HasTwoHanderEquipped() { return has_twohanderequipped; }
|
||||
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; }
|
||||
void SetFacestab(bool val) { can_facestab = val; }
|
||||
virtual uint16 GetSkill(EQ::skills::SkillType skill_num) const { return 0; }
|
||||
@ -1128,6 +1130,10 @@ public:
|
||||
Shielders_Struct shielder[MAX_SHIELDERS];
|
||||
Trade* trade;
|
||||
|
||||
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 float GetCWPP() const { return(static_cast<float>(cur_wp_pause)); }
|
||||
inline int GetCWP() const { return(cur_wp); }
|
||||
@ -1489,6 +1495,7 @@ protected:
|
||||
bool has_shieldequiped;
|
||||
bool has_twohandbluntequiped;
|
||||
bool has_twohanderequipped;
|
||||
bool has_duelweaponsequiped;
|
||||
bool can_facestab;
|
||||
bool has_numhits;
|
||||
bool has_MGB;
|
||||
|
||||
@ -2950,6 +2950,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Weapon_Stance: {
|
||||
if (IsClient()) {
|
||||
CastToClient()->ApplyWeaponsStance();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_PersistentEffect:
|
||||
MakeAura(spell_id);
|
||||
break;
|
||||
@ -3229,6 +3236,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
case SE_AddExtraAttackPct_1h_Primary:
|
||||
case SE_AddExtraAttackPct_1h_Secondary:
|
||||
case SE_Skill_Base_Damage_Mod:
|
||||
case SE_Buy_AA_Rank:
|
||||
|
||||
{
|
||||
break;
|
||||
@ -4359,6 +4367,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6585,7 +6604,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();
|
||||
return true;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user