mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-04 03:13:52 +00:00
More work, looks a lot better than before, tomorrow i hope to get actual client implementation done
This commit is contained in:
parent
33c1c7c3e4
commit
d5e697c061
395
zone/aa.cpp
395
zone/aa.cpp
@ -1254,37 +1254,37 @@ void Client::SendAA(uint32 id, int seq) {
|
||||
if (RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (saa2->hotkey_sid == 4294967295u))
|
||||
aa_stack = true;
|
||||
|
||||
if (aa_stack){
|
||||
uint32 aa_AA = 0;
|
||||
uint32 aa_value = 0;
|
||||
for (int i = 0; i < MAX_PP_AA_ARRAY; i++) {
|
||||
if (aa[i]) {
|
||||
aa_AA = aa[i]->AA;
|
||||
aa_value = aa[i]->value;
|
||||
|
||||
if (aa_AA){
|
||||
|
||||
if (aa_value > 0)
|
||||
aa_AA -= aa_value-1;
|
||||
|
||||
saa_pp = zone->FindAA(aa_AA);
|
||||
|
||||
if (saa_pp){
|
||||
|
||||
if (saa_pp->sof_next_skill == saa2->sof_next_skill){
|
||||
|
||||
if (saa_pp->id == saa2->id)
|
||||
break; //You already have this in the player profile.
|
||||
else if ((saa_pp->sof_current_level < saa2->sof_current_level) && (aa_value < saa_pp->max_level))
|
||||
return; //DISABLE DISPLAY HIGHER - You have not reached max level yet of your current AA.
|
||||
else if ((saa_pp->sof_current_level < saa2->sof_current_level) && (aa_value == saa_pp->max_level) && (saa_pp->sof_next_id == saa2->id))
|
||||
IsBaseLevel = false; //ALLOW DISPLAY HIGHER
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//if (aa_stack){
|
||||
// uint32 aa_AA = 0;
|
||||
// uint32 aa_value = 0;
|
||||
// for (int i = 0; i < MAX_PP_AA_ARRAY; i++) {
|
||||
// if (aa[i]) {
|
||||
// aa_AA = aa[i]->AA;
|
||||
// aa_value = aa[i]->value;
|
||||
//
|
||||
// if (aa_AA){
|
||||
//
|
||||
// if (aa_value > 0)
|
||||
// aa_AA -= aa_value-1;
|
||||
//
|
||||
// saa_pp = zone->FindAA(aa_AA);
|
||||
//
|
||||
// if (saa_pp){
|
||||
//
|
||||
// if (saa_pp->sof_next_skill == saa2->sof_next_skill){
|
||||
//
|
||||
// if (saa_pp->id == saa2->id)
|
||||
// break; //You already have this in the player profile.
|
||||
// else if ((saa_pp->sof_current_level < saa2->sof_current_level) && (aa_value < saa_pp->max_level))
|
||||
// return; //DISABLE DISPLAY HIGHER - You have not reached max level yet of your current AA.
|
||||
// else if ((saa_pp->sof_current_level < saa2->sof_current_level) && (aa_value == saa_pp->max_level) && (saa_pp->sof_next_id == saa2->id))
|
||||
// IsBaseLevel = false; //ALLOW DISPLAY HIGHER
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//Hide higher tiers of multi tiered AA's if the base level is not fully purchased.
|
||||
if (aa_stack && IsBaseLevel && saa2->sof_current_level > 0)
|
||||
@ -1399,51 +1399,6 @@ void Client::SendAAList(){
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Client::GetAA(uint32 aa_id) const {
|
||||
std::map<uint32,uint8>::const_iterator res;
|
||||
res = aa_points.find(aa_id);
|
||||
if(res != aa_points.end()) {
|
||||
return(res->second);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool Client::SetAA(uint32 aa_id, uint32 new_value) {
|
||||
aa_points[aa_id] = new_value;
|
||||
uint32 cur;
|
||||
auto sendaa = zone->FindAA(aa_id); // this is a bit hacky
|
||||
uint32 charges = sendaa->special_category == 7 && new_value ? 1 : 0;
|
||||
for(cur=0;cur < MAX_PP_AA_ARRAY;cur++){
|
||||
if((aa[cur]->value > 1) && ((aa[cur]->AA - aa[cur]->value + 1)== aa_id)){
|
||||
aa[cur]->value = new_value;
|
||||
if(new_value > 0)
|
||||
aa[cur]->AA++;
|
||||
aa[cur]->charges = charges;
|
||||
return true;
|
||||
}
|
||||
else if((aa[cur]->value == 1) && (aa[cur]->AA == aa_id)){
|
||||
aa[cur]->value = new_value;
|
||||
if(new_value > 0)
|
||||
aa[cur]->AA++;
|
||||
aa[cur]->charges = charges;
|
||||
return true;
|
||||
}
|
||||
// hack to prevent expendable exploit, we should probably be reshuffling the array to fix the hole
|
||||
else if(aa[cur]->value == 0 && new_value == 1 && aa[cur]->AA == aa_id) {
|
||||
aa[cur]->value = new_value;
|
||||
aa[cur]->charges = charges;
|
||||
return true;
|
||||
}
|
||||
else if(aa[cur]->AA==0){ //end of list
|
||||
aa[cur]->AA = aa_id;
|
||||
aa[cur]->value = new_value;
|
||||
aa[cur]->charges = charges;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SendAA_Struct* Zone::FindAA(uint32 id) {
|
||||
return aas_send[id];
|
||||
}
|
||||
@ -1503,39 +1458,39 @@ bool ZoneDatabase::LoadAAEffects2() {
|
||||
}
|
||||
|
||||
void Client::ResetAA(){
|
||||
RefundAA();
|
||||
uint32 i;
|
||||
for (i=0; i < MAX_PP_AA_ARRAY; i++) {
|
||||
aa[i]->AA = 0;
|
||||
aa[i]->value = 0;
|
||||
aa[i]->charges = 0;
|
||||
m_pp.aa_array[i].AA = 0;
|
||||
m_pp.aa_array[i].value = 0;
|
||||
m_pp.aa_array[i].charges= 0;
|
||||
}
|
||||
|
||||
std::map<uint32,uint8>::iterator itr;
|
||||
for(itr = aa_points.begin(); itr != aa_points.end(); ++itr)
|
||||
aa_points[itr->first] = 0;
|
||||
|
||||
for(int i = 0; i < _maxLeaderAA; ++i)
|
||||
m_pp.leader_abilities.ranks[i] = 0;
|
||||
|
||||
m_pp.group_leadership_points = 0;
|
||||
m_pp.raid_leadership_points = 0;
|
||||
m_pp.group_leadership_exp = 0;
|
||||
m_pp.raid_leadership_exp = 0;
|
||||
|
||||
database.DeleteCharacterAAs(this->CharacterID());
|
||||
SaveAA();
|
||||
SendClearAA();
|
||||
SendAAList();
|
||||
SendAATable();
|
||||
SendAAStats();
|
||||
database.DeleteCharacterLeadershipAAs(this->CharacterID());
|
||||
// undefined for these clients
|
||||
if (GetClientVersionBit() & BIT_TitaniumAndEarlier)
|
||||
Kick();
|
||||
// RefundAA();
|
||||
// uint32 i;
|
||||
// for (i=0; i < MAX_PP_AA_ARRAY; i++) {
|
||||
// aa[i]->AA = 0;
|
||||
// aa[i]->value = 0;
|
||||
// aa[i]->charges = 0;
|
||||
// m_pp.aa_array[i].AA = 0;
|
||||
// m_pp.aa_array[i].value = 0;
|
||||
// m_pp.aa_array[i].charges= 0;
|
||||
// }
|
||||
//
|
||||
// std::map<uint32,uint8>::iterator itr;
|
||||
// for(itr = aa_points.begin(); itr != aa_points.end(); ++itr)
|
||||
// aa_points[itr->first] = 0;
|
||||
//
|
||||
// for(int i = 0; i < _maxLeaderAA; ++i)
|
||||
// m_pp.leader_abilities.ranks[i] = 0;
|
||||
//
|
||||
// m_pp.group_leadership_points = 0;
|
||||
// m_pp.raid_leadership_points = 0;
|
||||
// m_pp.group_leadership_exp = 0;
|
||||
// m_pp.raid_leadership_exp = 0;
|
||||
//
|
||||
// database.DeleteCharacterAAs(this->CharacterID());
|
||||
// SaveAA();
|
||||
// SendClearAA();
|
||||
// SendAAList();
|
||||
// SendAATable();
|
||||
// SendAAStats();
|
||||
// database.DeleteCharacterLeadershipAAs(this->CharacterID());
|
||||
// // undefined for these clients
|
||||
// if (GetClientVersionBit() & BIT_TitaniumAndEarlier)
|
||||
// Kick();
|
||||
}
|
||||
|
||||
void Client::SendClearAA()
|
||||
@ -2096,19 +2051,23 @@ Mob *AA_SwarmPetInfo::GetOwner()
|
||||
return entity_list.GetMobID(owner_id);
|
||||
}
|
||||
|
||||
void Client::SendAlternateAdvancementList() {
|
||||
//for(auto &aa : zone->aa_abilities) {
|
||||
// SendAlternateAdvancement(aa.first, 5);
|
||||
//}
|
||||
|
||||
SendAlternateAdvancementRank(1, 5);
|
||||
SendAlternateAdvancementRank(1, 6);
|
||||
SendAlternateAdvancementRank(2, 1);
|
||||
//SendAlternateAdvancement(1, 5);
|
||||
//SendAlternateAdvancement(2, 5);
|
||||
//New AA
|
||||
void Client::SendAlternateAdvancementTable() {
|
||||
for(auto &aa : zone->aa_abilities) {
|
||||
auto ranks = GetAA(aa.second->first_rank_id);
|
||||
if(ranks) {
|
||||
if(aa.second->GetMaxLevel() == ranks) {
|
||||
SendAlternateAdvancementRank(aa.first, ranks);
|
||||
} else {
|
||||
SendAlternateAdvancementRank(aa.first, ranks);
|
||||
SendAlternateAdvancementRank(aa.first, ranks + 1);
|
||||
}
|
||||
} else {
|
||||
SendAlternateAdvancementRank(aa.first, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//New AA
|
||||
void Client::SendAlternateAdvancementRank(int aa_id, int level) {
|
||||
if(!zone)
|
||||
return;
|
||||
@ -2126,53 +2085,9 @@ void Client::SendAlternateAdvancementRank(int aa_id, int level) {
|
||||
if(!rank)
|
||||
return;
|
||||
|
||||
if(rank->account_time_required) {
|
||||
if((Timer::GetTimeSeconds() - account_creation) < rank->account_time_required)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide Quest/Progression AAs unless player has been granted the first level using $client->IncrementAA(skill_id).
|
||||
if(ability->category == 1 || ability->category == 2) {
|
||||
//if(GetAA(saa2->id) == 0)
|
||||
// return;
|
||||
|
||||
if(rank->expansion > 0) {
|
||||
AA::Ability *qaa = zone->GetAlternateAdvancementAbility(aa_id + 1);
|
||||
//if(qaa && qaa->expansion == rank->expansion && GetAA(aa_id) > 0) {
|
||||
// return;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
// Passive and Active Shroud AAs
|
||||
// For now we skip them
|
||||
if(ability->category == 3 || ability->category == 4) {
|
||||
if(!CanUseAlternateAdvancementRank(rank)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for racial/Drakkin blood line AAs
|
||||
if(ability->category == 8)
|
||||
{
|
||||
uint32 client_race = GetBaseRace();
|
||||
|
||||
// Drakkin Bloodlines
|
||||
if(rank->expansion > 522)
|
||||
{
|
||||
if(client_race != 522)
|
||||
return;
|
||||
|
||||
int heritage = this->GetDrakkinHeritage() + 523; // 523 = Drakkin Race(522) + Bloodline
|
||||
|
||||
if(heritage != rank->expansion)
|
||||
return;
|
||||
}
|
||||
else if(client_race != rank->expansion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int size = sizeof(AARankInfo_Struct) + (sizeof(AARankEffect_Struct) * rank->effects.size()) + (sizeof(AARankPrereq_Struct) * rank->prereqs.size());
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, size);
|
||||
@ -2220,10 +2135,126 @@ void Client::SendAlternateAdvancementRank(int aa_id, int level) {
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
AA::Ability *Zone::GetAlternateAdvancementAbility(int id) {
|
||||
auto iter = aa_abilities.find(id);
|
||||
if(iter != aa_abilities.end()) {
|
||||
return iter->second.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AA::Ability *Zone::GetAlternateAdvancementAbilityByRank(int rank_id) {
|
||||
AA::Rank *rank = GetAlternateAdvancementRank(rank_id);
|
||||
|
||||
if(!rank)
|
||||
return nullptr;
|
||||
|
||||
return rank->base_ability;
|
||||
}
|
||||
|
||||
AA::Rank *Zone::GetAlternateAdvancementRank(int rank_id) {
|
||||
auto iter = aa_ranks.find(rank_id);
|
||||
if(iter != aa_ranks.end()) {
|
||||
return iter->second.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32 Mob::GetAA(uint32 rank_id) const {
|
||||
if(zone) {
|
||||
AA::Ability *ability = zone->GetAlternateAdvancementAbilityByRank(rank_id);
|
||||
if(!ability)
|
||||
return 0;
|
||||
|
||||
auto iter = aa_ranks.find(ability->id);
|
||||
if(iter != aa_ranks.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Mob::SetAA(uint32 rank_id, uint32 new_value) {
|
||||
if(zone) {
|
||||
AA::Ability *ability = zone->GetAlternateAdvancementAbilityByRank(rank_id);
|
||||
|
||||
if(!ability) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(new_value > ability->GetMaxLevel()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aa_ranks[ability->id] = new_value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
||||
AA::Ability *ability = rank->base_ability;
|
||||
|
||||
if(!ability)
|
||||
return false;
|
||||
|
||||
// Passive and Active Shroud AAs
|
||||
// For now we skip them
|
||||
if(ability->category == 3 || ability->category == 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for racial/Drakkin blood line AAs
|
||||
if(ability->category == 8)
|
||||
{
|
||||
uint32 client_race = GetBaseRace();
|
||||
|
||||
// Drakkin Bloodlines
|
||||
if(rank->expansion > 522)
|
||||
{
|
||||
if(client_race != 522)
|
||||
return false;
|
||||
|
||||
int heritage = this->GetDrakkinHeritage() + 523; // 523 = Drakkin Race(522) + Bloodline
|
||||
|
||||
if(heritage != rank->expansion)
|
||||
return false;
|
||||
}
|
||||
else if(client_race != rank->expansion)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank) {
|
||||
AA::Ability *ability = rank->base_ability;
|
||||
|
||||
if(!ability)
|
||||
return false;
|
||||
|
||||
if(!CanUseAlternateAdvancementRank(rank)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//You can't purchase grant only AAs they can only be assigned
|
||||
if(ability->grant_only) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//check other stuff like price later
|
||||
return true;
|
||||
}
|
||||
|
||||
void Zone::LoadAlternateAdvancement() {
|
||||
Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Data...");
|
||||
if(!database.LoadAlternateAdvancementAbilities(aa_abilities,
|
||||
aa_ranks))
|
||||
if(!database.LoadAlternateAdvancementAbilities(aa_abilities,
|
||||
aa_ranks))
|
||||
{
|
||||
aa_abilities.clear();
|
||||
aa_ranks.clear();
|
||||
@ -2244,7 +2275,8 @@ void Zone::LoadAlternateAdvancement() {
|
||||
|
||||
if(current->prev) {
|
||||
current->total_cost = current->cost + current->prev->total_cost;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
current->total_cost = current->cost;
|
||||
}
|
||||
|
||||
@ -2257,24 +2289,6 @@ void Zone::LoadAlternateAdvancement() {
|
||||
Log.Out(Logs::General, Logs::Status, "Loaded Alternate Advancement Data");
|
||||
}
|
||||
|
||||
AA::Ability *Zone::GetAlternateAdvancementAbility(int id) {
|
||||
auto iter = aa_abilities.find(id);
|
||||
if(iter != aa_abilities.end()) {
|
||||
return iter->second.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AA::Rank *Zone::GetAlternateAdvancementRank(int rank_id) {
|
||||
auto iter = aa_ranks.find(rank_id);
|
||||
if(iter != aa_ranks.end()) {
|
||||
return iter->second.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std::unique_ptr<AA::Ability>> &abilities,
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> &ranks)
|
||||
{
|
||||
@ -2285,7 +2299,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
||||
if(results.Success()) {
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
AA::Ability *ability = new AA::Ability;
|
||||
int id = atoi(row[0]);
|
||||
ability->id = atoi(row[0]);
|
||||
ability->name = row[1];
|
||||
ability->category = atoi(row[2]);
|
||||
ability->classes = atoi(row[3]);
|
||||
@ -2295,7 +2309,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
||||
ability->first_rank_id = atoi(row[7]);
|
||||
ability->first = nullptr;
|
||||
|
||||
abilities[id] = std::unique_ptr<AA::Ability>(ability);
|
||||
abilities[ability->id] = std::unique_ptr<AA::Ability>(ability);
|
||||
}
|
||||
} else {
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to load Alternate Advancement Abilities");
|
||||
@ -2312,8 +2326,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
||||
if(results.Success()) {
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
AA::Rank *rank = new AA::Rank;
|
||||
int id = atoi(row[0]);
|
||||
rank->id = id;
|
||||
rank->id = atoi(row[0]);
|
||||
rank->upper_hotkey_sid = atoi(row[1]);
|
||||
rank->lower_hotkey_sid = atoi(row[2]);
|
||||
rank->title_sid = atoi(row[3]);
|
||||
@ -2332,7 +2345,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
||||
rank->next = nullptr;
|
||||
rank->prev = nullptr;
|
||||
|
||||
ranks[id] = std::unique_ptr<AA::Rank>(rank);
|
||||
ranks[rank->id] = std::unique_ptr<AA::Rank>(rank);
|
||||
}
|
||||
} else {
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to load Alternate Advancement Ability Ranks");
|
||||
|
||||
@ -41,6 +41,7 @@ public:
|
||||
Rank *GetRankByPointsSpent(int current_level);
|
||||
int GetMaxLevel(bool force_calc = false);
|
||||
|
||||
int id;
|
||||
std::string name;
|
||||
int category;
|
||||
int classes;
|
||||
|
||||
@ -639,20 +639,21 @@ void Client::CalcAABonuses(StatBonuses* newbon) {
|
||||
uint32 slots = 0;
|
||||
uint32 aa_AA = 0;
|
||||
uint32 aa_value = 0;
|
||||
if(this->aa) {
|
||||
for (i = 0; i < MAX_PP_AA_ARRAY; i++) { //iterate through all of the client's AAs
|
||||
if (this->aa[i]) { // make sure aa exists or we'll crash zone
|
||||
aa_AA = this->aa[i]->AA; //same as aaid from the aa_effects table
|
||||
aa_value = this->aa[i]->value; //how many points in it
|
||||
if (aa_AA > 0 || aa_value > 0) { //do we have the AA? if 1 of the 2 is set, we can assume we do
|
||||
//slots = database.GetTotalAALevels(aa_AA); //find out how many effects from aa_effects table
|
||||
slots = zone->GetTotalAALevels(aa_AA); //find out how many effects from aa_effects, which is loaded into memory
|
||||
if (slots > 0) //and does it have any effects? may be able to put this above, not sure if it runs on each iteration
|
||||
ApplyAABonuses(aa_AA, slots, newbon); //add the bonuses
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//aa old
|
||||
//if(this->aa) {
|
||||
// for (i = 0; i < MAX_PP_AA_ARRAY; i++) { //iterate through all of the client's AAs
|
||||
// if (this->aa[i]) { // make sure aa exists or we'll crash zone
|
||||
// aa_AA = this->aa[i]->AA; //same as aaid from the aa_effects table
|
||||
// aa_value = this->aa[i]->value; //how many points in it
|
||||
// if (aa_AA > 0 || aa_value > 0) { //do we have the AA? if 1 of the 2 is set, we can assume we do
|
||||
// //slots = database.GetTotalAALevels(aa_AA); //find out how many effects from aa_effects table
|
||||
// slots = zone->GetTotalAALevels(aa_AA); //find out how many effects from aa_effects, which is loaded into memory
|
||||
// if (slots > 0) //and does it have any effects? may be able to put this above, not sure if it runs on each iteration
|
||||
// ApplyAABonuses(aa_AA, slots, newbon); //add the bonuses
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -176,7 +176,6 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
admin = 0;
|
||||
lsaccountid = 0;
|
||||
shield_target = nullptr;
|
||||
SQL_log = nullptr;
|
||||
guild_id = GUILD_NONE;
|
||||
guildrank = 0;
|
||||
GuildBanker = false;
|
||||
@ -524,47 +523,48 @@ void Client::ReportConnectingState() {
|
||||
}
|
||||
|
||||
bool Client::SaveAA(){
|
||||
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<points; rank++) {
|
||||
std::map<uint32, AALevelCost_Struct>::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);
|
||||
//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<points; rank++) {
|
||||
// std::map<uint32, AALevelCost_Struct>::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);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -761,7 +761,7 @@ public:
|
||||
|
||||
//New AA Methods
|
||||
void SendAlternateAdvancementRank(int aa_id, int level);
|
||||
void SendAlternateAdvancementList();
|
||||
void SendAlternateAdvancementTable();
|
||||
|
||||
//old AA Methods
|
||||
void SendAAList();
|
||||
@ -787,8 +787,6 @@ public:
|
||||
void DisableAAEffect(aaEffectType type);
|
||||
bool CheckAAEffect(aaEffectType type);
|
||||
void HandleAAAction(aaID activate);
|
||||
uint32 GetAA(uint32 aa_id) const;
|
||||
bool SetAA(uint32 aa_id, uint32 new_value);
|
||||
inline uint32 GetAAPointsSpent() { return m_pp.aapoints_spent; }
|
||||
int16 CalcAAFocusEffect(focusType type, uint16 focus_spell, uint16 spell_id);
|
||||
int16 CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id);
|
||||
@ -1493,11 +1491,7 @@ private:
|
||||
|
||||
uint32 tribute_master_id;
|
||||
|
||||
FILE *SQL_log;
|
||||
uint32 max_AAXP;
|
||||
uint32 staminacount;
|
||||
AA_Array* aa[MAX_PP_AA_ARRAY]; //this list contains pointers into our player profile
|
||||
std::map<uint32,uint8> aa_points;
|
||||
bool npcflag;
|
||||
uint8 npclevel;
|
||||
bool feigned;
|
||||
|
||||
@ -1091,7 +1091,7 @@ void Client::Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_Connect_OP_SendAATable(const EQApplicationPacket *app)
|
||||
{
|
||||
SendAlternateAdvancementList();
|
||||
SendAlternateAdvancementTable();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1440,58 +1440,60 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
if (m_pp.ldon_points_available < 0 || m_pp.ldon_points_available > 2000000000){ m_pp.ldon_points_available = 0; }
|
||||
|
||||
/* Initialize AA's : Move to function eventually */
|
||||
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++)
|
||||
aa[a] = &m_pp.aa_array[a];
|
||||
query = StringFormat(
|
||||
"SELECT "
|
||||
"slot, "
|
||||
"aa_id, "
|
||||
"aa_value, "
|
||||
"charges "
|
||||
"FROM "
|
||||
"`character_alternate_abilities` "
|
||||
"WHERE `id` = %u ORDER BY `slot`", this->CharacterID());
|
||||
results = database.QueryDatabase(query); i = 0;
|
||||
int offset = 0; // offset to fix the hole from expendables
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
i = atoi(row[0]) - offset;
|
||||
m_pp.aa_array[i].AA = atoi(row[1]);
|
||||
m_pp.aa_array[i].value = atoi(row[2]);
|
||||
m_pp.aa_array[i].charges = atoi(row[3]);
|
||||
/* A used expendable could cause there to be a "hole" in the array, this is very bad. Bad things like keeping your expendable after use.
|
||||
We could do a few things, one of them being reshuffling when the hole is created or defer the fixing until a later point, like during load!
|
||||
Or just never making a hole in the array and just have hacks every where. Fixing the hole at load really just keeps 1 hack in Client::SendAATable
|
||||
and keeping this offset that will cause the next AA to be pushed back over the hole. We also need to clean up on save so we don't have multiple
|
||||
entries for a single AA.
|
||||
*/
|
||||
if (m_pp.aa_array[i].value == 0)
|
||||
offset++;
|
||||
}
|
||||
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++){
|
||||
uint32 id = aa[a]->AA;
|
||||
//watch for invalid AA IDs
|
||||
if (id == aaNone)
|
||||
continue;
|
||||
if (id >= aaHighestID) {
|
||||
aa[a]->AA = aaNone;
|
||||
aa[a]->value = 0;
|
||||
continue;
|
||||
}
|
||||
if (aa[a]->value == 0) {
|
||||
aa[a]->AA = aaNone;
|
||||
continue;
|
||||
}
|
||||
if (aa[a]->value > HIGHEST_AA_VALUE) {
|
||||
aa[a]->AA = aaNone;
|
||||
aa[a]->value = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aa[a]->value > 1) /* hack in some stuff for sony's new AA method (where each level of each aa.has a seperate ID) */
|
||||
aa_points[(id - aa[a]->value + 1)] = aa[a]->value;
|
||||
else
|
||||
aa_points[id] = aa[a]->value;
|
||||
}
|
||||
//aa old
|
||||
//for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++)
|
||||
// aa[a] = &m_pp.aa_array[a];
|
||||
//query = StringFormat(
|
||||
// "SELECT "
|
||||
// "slot, "
|
||||
// "aa_id, "
|
||||
// "aa_value, "
|
||||
// "charges "
|
||||
// "FROM "
|
||||
// "`character_alternate_abilities` "
|
||||
// "WHERE `id` = %u ORDER BY `slot`", this->CharacterID());
|
||||
//results = database.QueryDatabase(query); i = 0;
|
||||
//int offset = 0; // offset to fix the hole from expendables
|
||||
//for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
// i = atoi(row[0]) - offset;
|
||||
// m_pp.aa_array[i].AA = atoi(row[1]);
|
||||
// m_pp.aa_array[i].value = atoi(row[2]);
|
||||
// m_pp.aa_array[i].charges = atoi(row[3]);
|
||||
// /* A used expendable could cause there to be a "hole" in the array, this is very bad. Bad things like keeping your expendable after use.
|
||||
// We could do a few things, one of them being reshuffling when the hole is created or defer the fixing until a later point, like during load!
|
||||
// Or just never making a hole in the array and just have hacks every where. Fixing the hole at load really just keeps 1 hack in Client::SendAATable
|
||||
// and keeping this offset that will cause the next AA to be pushed back over the hole. We also need to clean up on save so we don't have multiple
|
||||
// entries for a single AA.
|
||||
// */
|
||||
// if (m_pp.aa_array[i].value == 0)
|
||||
// offset++;
|
||||
//}
|
||||
//for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++){
|
||||
// uint32 id = aa[a]->AA;
|
||||
// //watch for invalid AA IDs
|
||||
// if (id == aaNone)
|
||||
// continue;
|
||||
// if (id >= aaHighestID) {
|
||||
// aa[a]->AA = aaNone;
|
||||
// aa[a]->value = 0;
|
||||
// continue;
|
||||
// }
|
||||
// if (aa[a]->value == 0) {
|
||||
// aa[a]->AA = aaNone;
|
||||
// continue;
|
||||
// }
|
||||
// if (aa[a]->value > HIGHEST_AA_VALUE) {
|
||||
// aa[a]->AA = aaNone;
|
||||
// aa[a]->value = 0;
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// //aa old
|
||||
// // if (aa[a]->value > 1) /* hack in some stuff for sony's new AA method (where each level of each aa.has a seperate ID) */
|
||||
// // aa_points[(id - aa[a]->value + 1)] = aa[a]->value;
|
||||
// // else
|
||||
// // aa_points[id] = aa[a]->value;
|
||||
//}
|
||||
|
||||
if (SPDAT_RECORDS > 0) {
|
||||
for (uint32 z = 0; z<MAX_PP_MEMSPELL; z++) {
|
||||
|
||||
11
zone/mob.h
11
zone/mob.h
@ -23,6 +23,7 @@
|
||||
#include "hate_list.h"
|
||||
#include "pathing.h"
|
||||
#include "position.h"
|
||||
#include "aa_ability.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
@ -860,7 +861,6 @@ public:
|
||||
uint32 GetZoneID() const; //for perl
|
||||
virtual int32 CheckAggroAmount(uint16 spell_id, bool isproc = false);
|
||||
virtual int32 CheckHealAggroAmount(uint16 spell_id, uint32 heal_possible = 0);
|
||||
virtual uint32 GetAA(uint32 aa_id) const { return(0); }
|
||||
|
||||
uint32 GetInstrumentMod(uint16 spell_id) const;
|
||||
int CalcSpellEffectValue(uint16 spell_id, int effect_id, int caster_level = 1, uint32 instrument_mod = 10, Mob *caster = nullptr, int ticsremaining = 0);
|
||||
@ -956,6 +956,12 @@ public:
|
||||
void Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int avoid_override, int Msg = 0);
|
||||
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;
|
||||
bool SetAA(uint32 rank_id, uint32 new_value);
|
||||
bool CanUseAlternateAdvancementRank(AA::Rank *rank);
|
||||
bool CanPurchaseAlternateAdvancementRank(AA::Rank *ran);
|
||||
|
||||
protected:
|
||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||
@ -969,7 +975,6 @@ protected:
|
||||
virtual bool AI_PursueCastCheck() { return(false); }
|
||||
virtual bool AI_IdleCastCheck() { return(false); }
|
||||
|
||||
|
||||
bool IsFullHP;
|
||||
bool moved;
|
||||
|
||||
@ -1311,6 +1316,8 @@ protected:
|
||||
bool bEnraged;
|
||||
bool destructibleobject;
|
||||
|
||||
std::unordered_map<uint32, uint32> aa_ranks;
|
||||
|
||||
private:
|
||||
void _StopSong(); //this is not what you think it is
|
||||
Mob* target;
|
||||
|
||||
@ -5231,24 +5231,25 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
||||
uint32 aa_AA = 0;
|
||||
uint32 aa_value = 0;
|
||||
|
||||
for (int i = 0; i < MAX_PP_AA_ARRAY; i++)
|
||||
{
|
||||
aa_AA = this->aa[i]->AA;
|
||||
aa_value = this->aa[i]->value;
|
||||
if (aa_AA < 1 || aa_value < 1)
|
||||
continue;
|
||||
|
||||
if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS)
|
||||
continue;
|
||||
|
||||
proc_spellid = CalcAAFocus(type, aa_AA, spell_id);
|
||||
|
||||
if (IsValidSpell(proc_spellid)){
|
||||
ProcChance = GetSympatheticProcChances(spell_id, GetAABase1(aa_AA, 1));
|
||||
if(zone->random.Roll(ProcChance))
|
||||
SympatheticProcList.push_back(proc_spellid);
|
||||
}
|
||||
}
|
||||
//aa old
|
||||
//for (int i = 0; i < MAX_PP_AA_ARRAY; i++)
|
||||
//{
|
||||
// aa_AA = this->aa[i]->AA;
|
||||
// aa_value = this->aa[i]->value;
|
||||
// if (aa_AA < 1 || aa_value < 1)
|
||||
// continue;
|
||||
//
|
||||
// if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS)
|
||||
// continue;
|
||||
//
|
||||
// proc_spellid = CalcAAFocus(type, aa_AA, spell_id);
|
||||
//
|
||||
// if (IsValidSpell(proc_spellid)){
|
||||
// ProcChance = GetSympatheticProcChances(spell_id, GetAABase1(aa_AA, 1));
|
||||
// if(zone->random.Roll(ProcChance))
|
||||
// SympatheticProcList.push_back(proc_spellid);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
if (SympatheticProcList.size() > 0)
|
||||
@ -5503,21 +5504,22 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
uint32 aa_AA = 0;
|
||||
uint32 aa_value = 0;
|
||||
|
||||
for (int i = 0; i < MAX_PP_AA_ARRAY; i++)
|
||||
{
|
||||
aa_AA = this->aa[i]->AA;
|
||||
aa_value = this->aa[i]->value;
|
||||
if (aa_AA < 1 || aa_value < 1)
|
||||
continue;
|
||||
|
||||
Total3 = CalcAAFocus(type, aa_AA, spell_id);
|
||||
if (Total3 > 0 && realTotal3 >= 0 && Total3 > realTotal3) {
|
||||
realTotal3 = Total3;
|
||||
}
|
||||
else if (Total3 < 0 && Total3 < realTotal3) {
|
||||
realTotal3 = Total3;
|
||||
}
|
||||
}
|
||||
//aa old
|
||||
//for (int i = 0; i < MAX_PP_AA_ARRAY; i++)
|
||||
//{
|
||||
// aa_AA = this->aa[i]->AA;
|
||||
// aa_value = this->aa[i]->value;
|
||||
// if (aa_AA < 1 || aa_value < 1)
|
||||
// continue;
|
||||
//
|
||||
// Total3 = CalcAAFocus(type, aa_AA, spell_id);
|
||||
// if (Total3 > 0 && realTotal3 >= 0 && Total3 > realTotal3) {
|
||||
// realTotal3 = Total3;
|
||||
// }
|
||||
// else if (Total3 < 0 && Total3 < realTotal3) {
|
||||
// realTotal3 = Total3;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
if(type == focusReagentCost && IsSummonPetSpell(spell_id) && GetAA(aaElementalPact))
|
||||
|
||||
@ -117,6 +117,7 @@ public:
|
||||
//new AA
|
||||
void LoadAlternateAdvancement();
|
||||
AA::Ability *GetAlternateAdvancementAbility(int id);
|
||||
AA::Ability *GetAlternateAdvancementAbilityByRank(int rank_id);
|
||||
AA::Rank *GetAlternateAdvancementRank(int rank_id);
|
||||
|
||||
//old AA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user