From 985d969384e9a4b64668f96070cffd843db50224 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 11 Jun 2015 17:04:59 -0700 Subject: [PATCH] AA purchasing works --- zone/aa.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++----- zone/client.cpp | 80 ++++++++++++++++----------------- zone/mob.h | 2 +- 3 files changed, 143 insertions(+), 54 deletions(-) diff --git a/zone/aa.cpp b/zone/aa.cpp index 4bbdf88a6..868c1f62c 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -1796,13 +1796,14 @@ void Client::SendAlternateAdvancementPoints() { int i = 0; for(auto &aa : zone->aa_abilities) { - auto ranks = GetAA(aa.second->first_rank_id); + uint32 charges = 0; + auto ranks = GetAA(aa.second->first_rank_id, &charges); if(ranks) { 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].charges = 0; // todo send charges + aa2->aa_list[i].charges = charges; i++; } } @@ -1815,6 +1816,65 @@ void Client::SendAlternateAdvancementPoints() { } void Client::PurchaseAlternateAdvancementRank(int rank_id) { + AA::Rank *rank = zone->GetAlternateAdvancementRank(rank_id); + if(!rank) { + return; + } + + if(!rank->base_ability) { + return; + } + + if(!CanPurchaseAlternateAdvancementRank(rank)) { + return; + } + + if(rank->base_ability->charges > 0) { + SetAA(rank_id, rank->current_value, rank->base_ability->charges); + } else { + SetAA(rank_id, rank->current_value, 0); + + //if not max then send next aa + if(rank->next) { + SendAlternateAdvancementRank(rank->base_ability->id, rank->next->current_value); + } + } + + m_pp.aapoints -= rank->cost; + SaveAA(); + + SendAlternateAdvancementPoints(); + SendAlternateAdvancementStats(); + + if(rank->prev) { + Message_StringID(15, AA_IMPROVE, + std::to_string(rank->title_sid).c_str(), + std::to_string(rank->prev->current_value).c_str(), + std::to_string(rank->cost).c_str(), + std::to_string(AA_POINTS).c_str()); + + //QS stuff broke with new aa, todo: fix later + /* QS: Player_Log_AA_Purchases */ + // if (RuleB(QueryServ, PlayerLogAAPurchases)){ + // std::string event_desc = StringFormat("Ranked AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID()); + // QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc); + // } + } 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 stuff broke with new aa, todo: fix later + /* QS: Player_Log_AA_Purchases */ + // if (RuleB(QueryServ, PlayerLogAAPurchases)){ + // std::string event_desc = StringFormat("Initial AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID()); + // QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc); + // } + } + + CalcBonuses(); + if(title_manager.IsNewAATitleAvailable(m_pp.aapoints_spent, GetBaseClass())) + NotifyNewTitlesAvailable(); } bool ZoneDatabase::LoadAlternateAdvancement(Client *c) { @@ -1872,7 +1932,7 @@ AA::Rank *Zone::GetAlternateAdvancementRank(int rank_id) { return nullptr; } -uint32 Mob::GetAA(uint32 rank_id) const { +uint32 Mob::GetAA(uint32 rank_id, uint32 *charges) const { if(zone) { AA::Ability *ability = zone->GetAlternateAdvancementAbilityByRank(rank_id); if(!ability) @@ -1880,6 +1940,9 @@ uint32 Mob::GetAA(uint32 rank_id) const { auto iter = aa_ranks.find(ability->id); if(iter != aa_ranks.end()) { + if(charges) { + *charges = iter->second.second; + } return iter->second.first; } } @@ -1915,10 +1978,6 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) { return false; } - if(!(RuleI(World, ExpansionSettings) & (1 << rank->expansion))) { - return false; - } - // Passive and Active Shroud AAs // For now we skip them if(ability->category == 3 || ability->category == 4) { @@ -1965,14 +2024,50 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank) { return false; } - //check that we have previous rank already + if(!(RuleI(World, ExpansionSettings) & (1 << rank->expansion))) { + return false; + } + + //check level req + if(rank->level_req > GetLevel()) { + return false; + } + + uint32 current_charges = 0; + auto points = GetAA(rank->id, ¤t_charges); + + //check that we are on previous rank already (if exists) if(rank->prev) { - //rank->prev-> + if(points != rank->prev->current_value) { + return false; + } + } + + //if expendable only let us purchase if we have no charges already + //not quite sure on how this functions client side atm + //I intend to look into it later to make sure the behavior is right + if(ability->charges > 0 && current_charges > 0) { + return false; } //check prereqs + for(auto &prereq : rank->prereqs) { + AA::Ability *prereq_ability = zone->GetAlternateAdvancementAbility(prereq.aa_id); - //check price + if(prereq_ability) { + auto ranks = GetAA(prereq_ability->first_rank_id); + if(ranks < prereq.points) { + return false; + } + } + } + + //check price, if client + if(IsClient()) { + if(rank->cost > CastToClient()->GetAAPoints()) { + return false; + } + } return true; } diff --git a/zone/client.cpp b/zone/client.cpp index 24968f005..f36609b9c 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -523,49 +523,43 @@ void Client::ReportConnectingState() { }; } -bool Client::SaveAA(){ - //aa old - //int first_entry = 0; - //std::string rquery; - ///* Save Player AA */ - //int spentpoints = 0; - //for (int a = 0; a < MAX_PP_AA_ARRAY; a++) { - // uint32 points = aa[a]->value; - // if (points > HIGHEST_AA_VALUE) { - // aa[a]->value = HIGHEST_AA_VALUE; - // points = HIGHEST_AA_VALUE; - // } - // if (points > 0) { - // SendAA_Struct* curAA = zone->FindAA(aa[a]->AA - aa[a]->value + 1); - // if (curAA) { - // for (int rank = 0; rank::iterator RequiredLevel = AARequiredLevelAndCost.find(aa[a]->AA - aa[a]->value + 1 + rank); - // if (RequiredLevel != AARequiredLevelAndCost.end()) { - // spentpoints += RequiredLevel->second.Cost; - // } - // else - // spentpoints += (curAA->cost + (curAA->cost_inc * rank)); - // } - // } - // } - //} - //m_pp.aapoints_spent = spentpoints + m_epp.expended_aa; - //int highest = 0; - //for (int a = 0; a < MAX_PP_AA_ARRAY; a++) { - // if (aa[a]->AA > 0) { // those with value 0 will be cleaned up on next load - // if (first_entry != 1){ - // rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value, charges)" - // " VALUES (%u, %u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value, aa[a]->charges); - // first_entry = 1; - // } else { - // rquery = rquery + StringFormat(", (%u, %u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value, aa[a]->charges); - // } - // highest = a; - // } - //} - //auto results = database.QueryDatabase(rquery); - ///* This is another part of the hack to clean up holes left by expendable AAs */ - //rquery = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u AND `slot` > %d", character_id, highest); +bool Client::SaveAA() { + std::string dquery; + std::string iquery; + int spentpoints = 0; + int i = 0; + for(auto &rank : aa_ranks) { + AA::Ability *ability = zone->GetAlternateAdvancementAbility(rank.first); + if(!ability) + continue; + + if(rank.second.first > 0) { + AA::Rank *r = ability->GetRankByPointsSpent(rank.second.first); + + if(!r) + continue; + + spentpoints += r->total_cost; + + if(i == 0) { + iquery = StringFormat("INSERT INTO `character_alternate_abilities` (id, slot, aa_id, aa_value, charges)" + " VALUES (%u, %u, %u, %u, %u)", character_id, i, ability->first_rank_id, rank.second.first, rank.second.second); + } else { + iquery += StringFormat(", (%u, %u, %u, %u, %u)", character_id, i, ability->first_rank_id, rank.second.first, rank.second.second); + } + i++; + } + } + + m_pp.aapoints_spent = spentpoints + m_epp.expended_aa; + + dquery = StringFormat("DELETE FROM `character_alternate_abilities` WHERE id=%u", character_id); + database.QueryDatabase(dquery); + + if(iquery.length() > 0) { + database.QueryDatabase(iquery); + } + return true; } diff --git a/zone/mob.h b/zone/mob.h index bbc841f48..ce9fe3634 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -957,7 +957,7 @@ public: void Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg = 0); //aa new - uint32 GetAA(uint32 rank_id) const; + uint32 GetAA(uint32 rank_id, uint32 *charges = nullptr) const; bool SetAA(uint32 rank_id, uint32 new_value, uint32 charges = 0); void ClearAAs() { aa_ranks.clear(); } bool CanUseAlternateAdvancementRank(AA::Rank *rank);