diff --git a/zone/aa.cpp b/zone/aa.cpp index 5cbb5da14..8a4df6293 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -902,7 +902,7 @@ void Client::SendAlternateAdvancementPoints() { AA::Rank *rank = aa.second->GetRankByPointsSpent(ranks); if(rank) { aa2->aa_list[i].AA = rank->id; - aa2->aa_list[i].value = ranks; + aa2->aa_list[i].value = rank->total_cost; aa2->aa_list[i].charges = charges; i++; } @@ -993,10 +993,37 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) { return; } - if(!CanPurchaseAlternateAdvancementRank(rank, true)) { + if(!CanPurchaseAlternateAdvancementRank(rank, true, true)) { return; } + FinishAlternateAdvancementPurchase(rank); +} + +bool Client::GrantAlternateAdvancementAbility(int aa_id, int points) { + auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa_id, points); + auto ability = ability_rank.first; + auto rank = ability_rank.second; + + if(!rank) { + return false; + } + + if(!rank->base_ability) { + return false; + } + + if(!CanPurchaseAlternateAdvancementRank(rank, true, false)) { + return false; + } + + FinishAlternateAdvancementPurchase(rank); + return true; +} + +void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank) { + int rank_id = rank->base_ability->first_rank_id; + if(rank->base_ability->charges > 0) { uint32 charges = 0; GetAA(rank_id, &charges); @@ -1006,7 +1033,8 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) { } SetAA(rank_id, rank->current_value, rank->base_ability->charges); - } else { + } + else { SetAA(rank_id, rank->current_value, 0); //if not max then send next aa @@ -1029,17 +1057,18 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) { std::to_string(AA_POINTS).c_str()); /* QS: Player_Log_AA_Purchases */ - if (RuleB(QueryServ, PlayerLogAAPurchases)){ + if(RuleB(QueryServ, PlayerLogAAPurchases)){ std::string event_desc = StringFormat("Ranked AA Purchase :: aa_id:%i at cost:%i in zoneid:%i instid:%i", rank->id, rank->cost, GetZoneID(), GetInstanceID()); QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc); } - } else { + } + else { Message_StringID(15, AA_GAIN_ABILITY, std::to_string(rank->title_sid).c_str(), std::to_string(rank->cost).c_str(), std::to_string(AA_POINTS).c_str()); /* QS: Player_Log_AA_Purchases */ - if (RuleB(QueryServ, PlayerLogAAPurchases)){ + if(RuleB(QueryServ, PlayerLogAAPurchases)){ std::string event_desc = StringFormat("Initial AA Purchase :: aa_id:%i at cost:%i in zoneid:%i instid:%i", rank->id, rank->cost, GetZoneID(), GetInstanceID()); QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc); } @@ -1061,7 +1090,7 @@ void Client::IncrementAlternateAdvancementRank(int rank_id) { return; } - if(!CanPurchaseAlternateAdvancementRank(rank, false)) { + if(!CanPurchaseAlternateAdvancementRank(rank, false, true)) { return; } @@ -1443,7 +1472,7 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) { return true; } -bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price) { +bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price, bool check_grant) { AA::Ability *ability = rank->base_ability; if(!ability) @@ -1454,7 +1483,7 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price) } //You can't purchase grant only AAs they can only be assigned - if(ability->grant_only) { + if(check_grant && ability->grant_only) { return false; } @@ -1692,45 +1721,6 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_mapGetAlternateAdvancementAbilityAndRank(aa_id, points); - auto ability = ability_rank.first; - auto rank = ability_rank.second; - - if(!ability) { - return; - } - - if(ability->charges > 0) { - return; - } - - if(!ability->grant_only) { - return; - } - - if(!CanUseAlternateAdvancementRank(rank)) { - return; - } - - SetAA(ability->first_rank_id, rank->current_value, 0); - - if(IsClient()) { - Client *c = CastToClient(); - - if(rank->next) { - c->SendAlternateAdvancementRank(rank->base_ability->id, rank->next->current_value); - } - - c->SendAlternateAdvancementPoints(); - c->SendAlternateAdvancementStats(); - c->CalcBonuses(); - } -} - bool Mob::CheckAATimer(int timer) { if (timer >= aaTimerMax) diff --git a/zone/client.cpp b/zone/client.cpp index ae0ceedff..240902d09 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -532,10 +532,6 @@ bool Client::SaveAA() { if(!ability) continue; - if(ability->grant_only) { - continue; - } - if(rank.second.first > 0) { AA::Rank *r = ability->GetRankByPointsSpent(rank.second.first); diff --git a/zone/client.h b/zone/client.h index 44e86f971..8b0522162 100644 --- a/zone/client.h +++ b/zone/client.h @@ -763,6 +763,7 @@ public: void SendAlternateAdvancementTable(); void SendAlternateAdvancementStats(); void PurchaseAlternateAdvancementRank(int rank_id); + bool GrantAlternateAdvancementAbility(int aa_id, int points); void IncrementAlternateAdvancementRank(int rank_id); void ActivateAlternateAdvancementAbility(int rank_id, int target_id); void SendAlternateAdvancementPoints(); @@ -1262,6 +1263,8 @@ protected: int16 GetFocusEffect(focusType type, uint16 spell_id); uint16 GetSympatheticFocusEffect(focusType type, uint16 spell_id); + void FinishAlternateAdvancementPurchase(AA::Rank *rank); + Mob* bind_sight_target; glm::vec4 m_AutoAttackPosition; diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 37f379a06..8f2106b04 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1027,6 +1027,11 @@ void Lua_Client::IncrementAA(int aa) { self->IncrementAlternateAdvancementRank(aa); } +bool Lua_Client::GrantAlternateAdvancementAbility(int aa_id, int points) { + Lua_Safe_Call_Bool(); + self->GrantAlternateAdvancementAbility(aa_id, points); +} + void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z) { Lua_Safe_Call_Void(); self->MarkSingleCompassLoc(in_x, in_y, in_z); @@ -1500,6 +1505,7 @@ luabind::scope lua_register_client() { .def("AddLevelBasedExp", (void(Lua_Client::*)(int))&Lua_Client::AddLevelBasedExp) .def("AddLevelBasedExp", (void(Lua_Client::*)(int,int))&Lua_Client::AddLevelBasedExp) .def("IncrementAA", (void(Lua_Client::*)(int))&Lua_Client::IncrementAA) + .def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int))&Lua_Client::GrantAlternateAdvancementAbility) .def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float))&Lua_Client::MarkSingleCompassLoc) .def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float,int))&Lua_Client::MarkSingleCompassLoc) .def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(void))&Lua_Client::GetNextAvailableSpellBookSlot) diff --git a/zone/lua_client.h b/zone/lua_client.h index 8f930fc26..a20f4fb57 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -233,6 +233,7 @@ public: void AddLevelBasedExp(int exp_pct); void AddLevelBasedExp(int exp_pct, int max_level); void IncrementAA(int aa); + bool GrantAlternateAdvancementAbility(int aa_id, int points); void MarkSingleCompassLoc(float in_x, float in_y, float in_z); void MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count); int GetNextAvailableSpellBookSlot(); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 31719d364..9662d1931 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1210,11 +1210,6 @@ bool Lua_Mob::SetAA(int rank_id, int new_value, int charges) { return self->SetAA(rank_id, new_value, charges); } -void Lua_Mob::GrantAlternateAdvancementAbility(int aa_id, int points) { - Lua_Safe_Call_Void(); - self->GrantAlternateAdvancementAbility(aa_id, points); -} - bool Lua_Mob::DivineAura() { Lua_Safe_Call_Bool(); return self->DivineAura(); @@ -2097,7 +2092,6 @@ luabind::scope lua_register_mob() { .def("GetAAByAAID", (int(Lua_Mob::*)(int))&Lua_Mob::GetAAByAAID) .def("SetAA", (bool(Lua_Mob::*)(int,int))&Lua_Mob::SetAA) .def("SetAA", (bool(Lua_Mob::*)(int,int,int))&Lua_Mob::SetAA) - .def("GrantAlternateAdvancementAbility", (void(Lua_Mob::*)(int, int))&Lua_Mob::GrantAlternateAdvancementAbility) .def("DivineAura", (bool(Lua_Mob::*)(void))&Lua_Mob::DivineAura) .def("SetOOCRegen", (void(Lua_Mob::*)(int))&Lua_Mob::SetOOCRegen) .def("GetEntityVariable", (const char*(Lua_Mob::*)(const char*))&Lua_Mob::GetEntityVariable) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 914f46c5d..4f427aca5 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -252,7 +252,6 @@ public: int GetAAByAAID(int id); bool SetAA(int rank_id, int new_value); bool SetAA(int rank_id, int new_value, int charges); - void GrantAlternateAdvancementAbility(int aa_id, int points); bool DivineAura(); void SetOOCRegen(int regen); const char* GetEntityVariable(const char *name); diff --git a/zone/mob.h b/zone/mob.h index c9ba4471d..60a40711b 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -965,12 +965,11 @@ public: bool SetAA(uint32 rank_id, uint32 new_value, uint32 charges = 0); void ClearAAs() { aa_ranks.clear(); } bool CanUseAlternateAdvancementRank(AA::Rank *rank); - bool CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price); + bool CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price, bool check_grant); int GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in); void ExpendAlternateAdvancementCharge(uint32 aa_id); void CalcAABonuses(StatBonuses* newbon); void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon); - void GrantAlternateAdvancementAbility(int aa_id, int points); bool CheckAATimer(int timer); protected: diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index eea9918cd..c836e378e 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -4894,6 +4894,34 @@ XS(XS_Client_IncrementAA) XSRETURN_EMPTY; } +XS(XS_Client_GrantAlternateAdvancementAbility); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_GrantAlternateAdvancementAbility) +{ + dXSARGS; + if(items != 3) + Perl_croak(aTHX_ "Usage: Client::GrantAlternateAdvancementAbility(THIS, aa_id, points)"); + { + Client * THIS; + bool RETVAL; + int aa_id = (int)SvIV(ST(1)); + int points = (int)SvIV(ST(2)); + + if(sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Client"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GrantAlternateAdvancementAbility(aa_id, points); + ST(0) = boolSV(RETVAL); + sv_2mortal(ST(0)); + } + XSRETURN(1); +} + XS(XS_Client_GetAALevel); XS(XS_Client_GetAALevel) { @@ -6437,6 +6465,7 @@ XS(boot_Client) newXSproto(strcpy(buf, "GetIP"), XS_Client_GetIP, file, "$"); newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$"); newXSproto(strcpy(buf, "IncrementAA"), XS_Client_IncrementAA, file, "$$"); + newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Client_GrantAlternateAdvancementAbility, file, "$$$"); newXSproto(strcpy(buf, "GetAALevel"), XS_Client_GetAALevel, file, "$$"); newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$"); newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$"); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 612d9f868..dcd999a3e 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -6438,31 +6438,6 @@ XS(XS_Mob_SetAA) XSRETURN(1); } -XS(XS_Mob_GrantAlternateAdvancementAbility); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_GrantAlternateAdvancementAbility) -{ - dXSARGS; - if(items != 3) - Perl_croak(aTHX_ "Usage: Mob::GrantAlternateAdvancementAbility(THIS, aa_id, points)"); - { - Mob * THIS; - int aa_id = (int)SvIV(ST(1)); - int points = (int)SvIV(ST(2)); - - if(sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Mob *, tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Mob"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - - THIS->GrantAlternateAdvancementAbility(aa_id, points); - } - XSRETURN_EMPTY; -} - XS(XS_Mob_DivineAura); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_DivineAura) { @@ -8708,7 +8683,6 @@ XS(boot_Mob) newXSproto(strcpy(buf, "GetAA"), XS_Mob_GetAA, file, "$$"); newXSproto(strcpy(buf, "GetAAByAAID"), XS_Mob_GetAAByAAID, file, "$$"); newXSproto(strcpy(buf, "SetAA"), XS_Mob_SetAA, file, "$$$;$"); - newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Mob_GrantAlternateAdvancementAbility, file, "$$$"); newXSproto(strcpy(buf, "DivineAura"), XS_Mob_DivineAura, file, "$"); newXSproto(strcpy(buf, "AddFeignMemory"), XS_Mob_AddFeignMemory, file, "$$"); newXSproto(strcpy(buf, "RemoveFromFeignMemory"), XS_Mob_RemoveFromFeignMemory, file, "$$");