void Client::ResetAA(){ RefundAA(); uint32 i; for (i = 0; i<MAX_PP_AA_ARRAY; i++){ aa[i]->AA = 0; aa[i]->value = 0; m_pp.aa_array[MAX_PP_AA_ARRAY].AA = 0; m_pp.aa_array[MAX_PP_AA_ARRAY].value = 0; } std::map<uint32, uint8>::iterator itr; for (itr = aa_points.begin(); itr != aa_points.end(); ++itr) aa_points[itr->first] = 0; database.DeleteCharacterAAs(this->CharacterID()); SaveAA(); SendAATable(); Kick(); }
void Client::RefundAA() { int refunded = 0; auto rank_value = aa_ranks.begin(); while(rank_value != aa_ranks.end()) { auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_value->first, rank_value->second.first); auto ability = ability_rank.first; auto rank = ability_rank.second; if(!ability) { ++rank_value; continue; } if(ability->charges > 0 && rank_value->second.second < 1) { ++rank_value; continue; } if(ability->grant_only) { ++rank_value; continue; } refunded += rank->total_cost; rank_value = aa_ranks.erase(rank_value); } if(refunded > 0) { m_pp.aapoints += refunded; SaveAA(); Save(); } SendAlternateAdvancementTable(); SendAlternateAdvancementPoints(); SendAlternateAdvancementStats(); }
void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost) { int rank_id = rank->base_ability->first_rank_id; if(rank->base_ability->charges > 0) { uint32 charges = 0; GetAA(rank_id, &charges); if(charges > 0) { return; } 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); } } int cost = !ignore_cost ? rank->cost : 0; m_pp.aapoints -= 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(cost).c_str(), cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()); /* QS: Player_Log_AA_Purchases */ 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, cost, GetZoneID(), GetInstanceID()); QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc); } } else { Message_StringID(15, AA_GAIN_ABILITY, std::to_string(rank->title_sid).c_str(), std::to_string(cost).c_str(), cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()); /* QS: Player_Log_AA_Purchases */ 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, cost, GetZoneID(), GetInstanceID()); QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc); } } CalcBonuses(); if(cost > 0) { if(title_manager.IsNewAATitleAvailable(m_pp.aapoints_spent, GetBaseClass())) NotifyNewTitlesAvailable(); } }
void Client::BuyAA(AA_Action* action) { Log.Out(Logs::Detail, Logs::AA, "Starting to buy AA %d", action->ability); //find the AA information from the database SendAA_Struct* aa2 = zone->FindAA(action->ability); if (!aa2) { //hunt for a lower level... int i; int a; for (i = 1; i<MAX_AA_ACTION_RANKS; i++){ a = action->ability - i; if (a <= 0) break; Log.Out(Logs::Detail, Logs::AA, "Could not find AA %d, trying potential parent %d", action->ability, a); aa2 = zone->FindAA(a); if (aa2 != nullptr) break; } } if (aa2 == nullptr) return; //invalid ability... if (aa2->special_category == 1 || aa2->special_category == 2) return; // Not purchasable progression style AAs if (aa2->special_category == 8 && aa2->cost == 0) return; // Not purchasable racial AAs(set a cost to make them purchasable) uint32 cur_level = GetAA(aa2->id); if ((aa2->id + cur_level) != action->ability) { //got invalid AA Log.Out(Logs::Detail, Logs::AA, "Unable to find or match AA %d (found %d + lvl %d)", action->ability, aa2->id, cur_level); return; } if (aa2->account_time_required) { if ((Timer::GetTimeSeconds() - account_creation) < aa2->account_time_required) { return; } } uint32 real_cost; std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(action->ability); if (RequiredLevel != AARequiredLevelAndCost.end()) { real_cost = RequiredLevel->second.Cost; } else real_cost = aa2->cost + (aa2->cost_inc * cur_level); if (m_pp.aapoints >= real_cost && cur_level < aa2->max_level) { SetAA(aa2->id, cur_level + 1); Log.Out(Logs::Detail, Logs::AA, "Set AA %d to level %d", aa2->id, cur_level + 1); m_pp.aapoints -= real_cost; /* Do Player Profile rank calculations and set player profile */ SaveAA(); /* Save to Database to avoid having to write the whole AA array to the profile, only write changes*/ // database.SaveCharacterAA(this->CharacterID(), aa2->id, (cur_level + 1)); SendAATable(); /* We are building these messages ourself instead of using the stringID to work around patch discrepencies these are AA_GAIN_ABILITY (410) & AA_IMPROVE (411), respectively, in both Titanium & SoF. not sure about 6.2 */ /* Initial purchase of an AA ability */ if (cur_level < 1){ Message(15, "You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1) ? "points" : "point"); /* 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); } } /* Ranked purchase of an AA ability */ else{ Message(15, "You have improved %s %d at a cost of %d ability %s.", aa2->name, cur_level + 1, real_cost, (real_cost > 1) ? "points" : "point"); /* 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); } } SendAAStats(); CalcBonuses(); //Bugs client, comment out for now until titles can be worked out. //if(title_manager.IsNewAATitleAvailable(m_pp.aapoints_spent, GetBaseClass())) // NotifyNewTitlesAvailable(); } }