mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-05 03:42:26 +00:00
More aa work, it actually loads yay
This commit is contained in:
parent
361c93b689
commit
250d0cc903
@ -4220,7 +4220,7 @@ struct UseAA_Struct {
|
||||
};
|
||||
|
||||
//new AA stuff
|
||||
|
||||
//reference only
|
||||
struct AARankInfo_Struct
|
||||
{
|
||||
uint32 id;
|
||||
@ -4244,6 +4244,7 @@ struct AARankInfo_Struct
|
||||
int32 expansion;
|
||||
int32 category;
|
||||
uint8 expendable;
|
||||
uint8 grant_only;
|
||||
uint32 total_effects;
|
||||
uint32 total_prereqs;
|
||||
};
|
||||
|
||||
@ -1804,11 +1804,11 @@ namespace UF
|
||||
// OUT(unknown00224[48]);
|
||||
//NOTE: new client supports 300 AAs, our internal rep/PP
|
||||
//only supports 240..
|
||||
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
||||
OUT(aa_array[r].AA);
|
||||
OUT(aa_array[r].value);
|
||||
OUT(aa_array[r].charges);
|
||||
}
|
||||
//for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
||||
// OUT(aa_array[r].AA);
|
||||
// OUT(aa_array[r].value);
|
||||
// OUT(aa_array[r].charges);
|
||||
//}
|
||||
// OUT(unknown02220[4]);
|
||||
OUT(mana);
|
||||
OUT(cur_hp);
|
||||
@ -2145,13 +2145,66 @@ namespace UF
|
||||
|
||||
ENCODE(OP_SendAATable)
|
||||
{
|
||||
#if 1
|
||||
EQApplicationPacket *inapp = *p;
|
||||
*p = nullptr;
|
||||
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
|
||||
structs::SendAA_Struct *eq = (structs::SendAA_Struct*)outapp->pBuffer;
|
||||
|
||||
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
|
||||
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
|
||||
|
||||
eq->id = emu->id;
|
||||
eq->unknown004 = 1;
|
||||
eq->id = emu->id;
|
||||
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||
eq->desc_sid = emu->desc_sid;
|
||||
eq->title_sid = emu->title_sid;
|
||||
eq->class_type = emu->level_req;
|
||||
eq->cost = emu->cost;
|
||||
eq->seq = emu->seq;
|
||||
eq->current_level = emu->current_level;
|
||||
eq->type = emu->type;
|
||||
eq->spellid = emu->spell;
|
||||
eq->spell_type = emu->spell_type;
|
||||
eq->spell_refresh = emu->spell_refresh;
|
||||
eq->classes = emu->classes;
|
||||
eq->max_level = emu->max_level;
|
||||
eq->last_id = emu->prev_id;
|
||||
eq->next_id = emu->next_id;
|
||||
eq->cost2 = emu->total_cost;
|
||||
eq->grant_only = emu->grant_only > 0 ? true : false;
|
||||
eq->expendable_charges = emu->expendable ? 1 : 0;
|
||||
eq->aa_expansion = emu->expansion;
|
||||
eq->special_category = emu->category;
|
||||
eq->total_abilities = emu->total_effects;
|
||||
|
||||
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||
eq->abilities[i].skill_id = inapp->ReadUInt32();
|
||||
eq->abilities[i].base1 = inapp->ReadUInt32();
|
||||
eq->abilities[i].base2 = inapp->ReadUInt32();
|
||||
eq->abilities[i].slot = inapp->ReadUInt32();
|
||||
}
|
||||
|
||||
if(emu->total_prereqs > 0) {
|
||||
eq->prereq_skill = -(int)inapp->ReadUInt32();
|
||||
eq->prereq_minpoints = inapp->ReadUInt32();
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Status, "%s", DumpPacketToString(outapp).c_str());
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
#else
|
||||
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
|
||||
SETUP_VAR_ENCODE(SendAA_Struct);
|
||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
|
||||
|
||||
// Check clientver field to verify this AA should be sent for SoF
|
||||
// clientver 1 is for all clients and 6 is for Underfoot
|
||||
if (emu->clientver <= 6)
|
||||
if(emu->clientver <= 6)
|
||||
{
|
||||
OUT(id);
|
||||
eq->unknown004 = 1;
|
||||
@ -2174,7 +2227,7 @@ namespace UF
|
||||
OUT(spell_type);
|
||||
OUT(spell_refresh);
|
||||
OUT(classes);
|
||||
OUT(berserker);
|
||||
//OUT(berserker);
|
||||
//eq->max_level = emu->sof_max_level;
|
||||
OUT(max_level);
|
||||
OUT(last_id);
|
||||
@ -2185,7 +2238,7 @@ namespace UF
|
||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
||||
OUT(total_abilities);
|
||||
unsigned int r;
|
||||
for (r = 0; r < emu->total_abilities; r++) {
|
||||
for(r = 0; r < emu->total_abilities; r++) {
|
||||
OUT(abilities[r].skill_id);
|
||||
OUT(abilities[r].base1);
|
||||
OUT(abilities[r].base2);
|
||||
@ -2193,7 +2246,9 @@ namespace UF
|
||||
}
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Status, "%s", DumpPacketToString(__packet).c_str());
|
||||
FINISH_ENCODE();
|
||||
#endif
|
||||
}
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
|
||||
@ -3886,8 +3886,7 @@ struct SendAA_Struct {
|
||||
/*0049*/ uint32 spellid;
|
||||
/*0053*/ uint32 spell_type;
|
||||
/*0057*/ uint32 spell_refresh;
|
||||
/*0061*/ uint16 classes;
|
||||
/*0063*/ uint16 berserker; //seems to be 1 if its a berserker ability
|
||||
/*0061*/ uint32 classes;
|
||||
/*0065*/ uint32 max_level;
|
||||
/*0069*/ uint32 last_id;
|
||||
/*0073*/ uint32 next_id;
|
||||
|
||||
@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(zone_sources
|
||||
aa.cpp
|
||||
aa_ability.cpp
|
||||
aggro.cpp
|
||||
attack.cpp
|
||||
beacon.cpp
|
||||
|
||||
315
zone/aa.cpp
315
zone/aa.cpp
@ -1097,22 +1097,24 @@ void Client::SendAATimers() {
|
||||
}
|
||||
|
||||
void Client::SendAATable() {
|
||||
Log.Out(Logs::General, Logs::Status, "SendAATable()");
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_RespondAA, sizeof(AATable_Struct));
|
||||
|
||||
AATable_Struct* aa2 = (AATable_Struct *)outapp->pBuffer;
|
||||
aa2->aa_spent = GetAAPointsSpent();
|
||||
|
||||
uint32 i;
|
||||
for(i=0;i < MAX_PP_AA_ARRAY;i++){
|
||||
aa2->aa_list[i].AA = aa[i]->value ? aa[i]->AA : 0; // bit of a hack to prevent expendables punching a hole
|
||||
aa2->aa_list[i].value = aa[i]->value;
|
||||
aa2->aa_list[i].charges = aa[i]->charges;
|
||||
}
|
||||
//aa2->aa_spent = GetAAPointsSpent();
|
||||
//
|
||||
//uint32 i;
|
||||
//for(i=0;i < MAX_PP_AA_ARRAY;i++){
|
||||
// aa2->aa_list[i].AA = aa[i]->value ? aa[i]->AA : 0; // bit of a hack to prevent expendables punching a hole
|
||||
// aa2->aa_list[i].value = aa[i]->value;
|
||||
// aa2->aa_list[i].charges = aa[i]->charges;
|
||||
//}
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
void Client::SendPreviousAA(uint32 id, int seq){
|
||||
Log.Out(Logs::General, Logs::Status, "SendPreviousAA(%u, %i)", id, seq);
|
||||
uint32 value=0;
|
||||
SendAA_Struct* saa2 = nullptr;
|
||||
if(id==0)
|
||||
@ -1148,11 +1150,13 @@ void Client::SendPreviousAA(uint32 id, int seq){
|
||||
}
|
||||
|
||||
database.FillAAEffects(saa);
|
||||
Log.Out(Logs::General, Logs::Status, "%s", DumpPacketToString(outapp).c_str());
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
void Client::SendAA(uint32 id, int seq) {
|
||||
Log.Out(Logs::General, Logs::Status, "SendAA(%u, %i)", id, seq);
|
||||
|
||||
uint32 value=0;
|
||||
SendAA_Struct* saa2 = nullptr;
|
||||
@ -1368,6 +1372,7 @@ void Client::SendAA(uint32 id, int seq) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SendAATable);
|
||||
outapp->size=size;
|
||||
outapp->pBuffer=(uchar*)saa;
|
||||
|
||||
if(id==0 && value && (orig_val < saa->max_level)) //send previous AA only on zone in
|
||||
SendPreviousAA(id, seq);
|
||||
|
||||
@ -1377,10 +1382,13 @@ void Client::SendAA(uint32 id, int seq) {
|
||||
}
|
||||
|
||||
void Client::SendAAList(){
|
||||
// int total = zone->GetTotalAAs();
|
||||
// for(int i=0;i < total;i++){
|
||||
// SendAA(0,i);
|
||||
// }
|
||||
Log.Out(Logs::General, Logs::Status, "SendAAList()");
|
||||
int total = zone->GetTotalAAs();
|
||||
|
||||
total = total > 2 ? 2 : total;
|
||||
for(int i=0;i < total;i++){
|
||||
SendAA(0,i);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Client::GetAA(uint32 aa_id) const {
|
||||
@ -2080,39 +2088,300 @@ Mob *AA_SwarmPetInfo::GetOwner()
|
||||
return entity_list.GetMobID(owner_id);
|
||||
}
|
||||
|
||||
void Client::SendAlternateAdvancementList() {
|
||||
for(auto &aa : zone->aa_abilities) {
|
||||
SendAlternateAdvancement(aa.first, true);
|
||||
}
|
||||
}
|
||||
|
||||
//New AA
|
||||
void Client::SendAlternateAdvancement(int aa_id, bool first_login) {
|
||||
if(!zone)
|
||||
return;
|
||||
|
||||
AA::Ability *ability = zone->GetAlternateAdvancementAbility(aa_id);
|
||||
|
||||
if(!ability)
|
||||
return;
|
||||
|
||||
if(!(ability->classes & (1 << GetClass()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(ability->account_time_required) {
|
||||
if((Timer::GetTimeSeconds() - account_creation) < ability->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(ability->expansion > 0) {
|
||||
AA::Ability *qaa = zone->GetAlternateAdvancementAbility(aa_id + 1);
|
||||
//if(qaa && qaa->expansion == ability->expansion && GetAA(aa_id) > 0) {
|
||||
// return;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
// Passive and Active Shroud AAs
|
||||
// For now we skip them
|
||||
if(ability->category == 3 || ability->category == 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for racial/Drakkin blood line AAs
|
||||
if(ability->category == 8)
|
||||
{
|
||||
uint32 client_race = GetBaseRace();
|
||||
|
||||
// Drakkin Bloodlines
|
||||
if(ability->expansion > 522)
|
||||
{
|
||||
if(client_race != 522)
|
||||
return;
|
||||
|
||||
int heritage = this->GetDrakkinHeritage() + 523; // 523 = Drakkin Race(522) + Bloodline
|
||||
|
||||
if(heritage != ability->expansion)
|
||||
return;
|
||||
}
|
||||
else if(client_race != ability->expansion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Send first rank
|
||||
AA::Rank *rank = ability->first;
|
||||
if(!rank)
|
||||
return;
|
||||
|
||||
//Should move this to another function
|
||||
int size = sizeof(AARankInfo_Struct)+(sizeof(AARankEffect_Struct)* rank->effects.size()) + (sizeof(AARankPrereq_Struct)* rank->prereqs.size());
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, size);
|
||||
AARankInfo_Struct *aai = (AARankInfo_Struct*)outapp->pBuffer;
|
||||
|
||||
aai->id = rank->id;
|
||||
aai->upper_hotkey_sid = rank->upper_hotkey_sid;
|
||||
aai->lower_hotkey_sid = rank->lower_hotkey_sid;
|
||||
aai->title_sid = rank->title_sid;
|
||||
aai->desc_sid = rank->desc_sid;
|
||||
aai->level_req = rank->level_req;
|
||||
aai->cost = rank->cost;
|
||||
aai->seq = aa_id;
|
||||
aai->current_level = 1;
|
||||
aai->type = ability->type;
|
||||
aai->spell = rank->spell;
|
||||
aai->spell_type = rank->spell_type;
|
||||
aai->spell_refresh = rank->recast_time;
|
||||
aai->classes = ability->classes;
|
||||
aai->max_level = ability->GetMaxLevel();
|
||||
aai->prev_id = rank->prev_id;
|
||||
aai->next_id = rank->next_id;
|
||||
aai->total_cost = rank->total_cost;
|
||||
aai->expansion = ability->expansion;
|
||||
aai->category = ability->category;
|
||||
aai->expendable = ability->expendable;
|
||||
aai->grant_only = ability->grant_only;
|
||||
aai->total_effects = rank->effects.size();
|
||||
aai->total_prereqs = rank->prereqs.size();
|
||||
|
||||
outapp->SetWritePosition(sizeof(AARankInfo_Struct));
|
||||
for(auto effect : rank->effects) {
|
||||
outapp->WriteSInt32(effect.second.effect_id);
|
||||
outapp->WriteSInt32(effect.second.base1);
|
||||
outapp->WriteSInt32(effect.second.base2);
|
||||
outapp->WriteSInt32(effect.first);
|
||||
}
|
||||
|
||||
for(auto prereq : rank->prereqs) {
|
||||
outapp->WriteSInt32(prereq.aa_id);
|
||||
outapp->WriteSInt32(prereq.points);
|
||||
}
|
||||
|
||||
//if first_login then also send current rank if not maxed
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
//
|
||||
//if(size == 0)
|
||||
// return;
|
||||
//
|
||||
//uchar* buffer = new uchar[size];
|
||||
//SendAA_Struct* saa = (SendAA_Struct*)buffer;
|
||||
//memcpy(saa, saa2, size);
|
||||
//
|
||||
//if(saa->spellid == 0)
|
||||
// saa->spellid = 0xFFFFFFFF;
|
||||
//
|
||||
//value = GetAA(saa->id);
|
||||
//uint32 orig_val = value;
|
||||
//
|
||||
//if(value && saa->id){
|
||||
//
|
||||
// if(value < saa->max_level){
|
||||
// saa->id += value;
|
||||
// saa->next_id = saa->id + 1;
|
||||
// value++;
|
||||
// }
|
||||
//
|
||||
// else if(aa_stack && saa->sof_next_id){
|
||||
// saa->id += value - 1;
|
||||
// saa->next_id = saa->sof_next_id;
|
||||
//
|
||||
// //Prevent removal of previous AA from window if next AA belongs to a higher client version.
|
||||
// SendAA_Struct* saa_next = nullptr;
|
||||
// saa_next = zone->FindAA(saa->sof_next_id);
|
||||
//
|
||||
// // this check should work as long as we continue to just add the clients and just increase
|
||||
// // each number ....
|
||||
// if(saa_next && static_cast<int>(GetClientVersion()) < saa_next->clientver - 1) {
|
||||
// saa->next_id = 0xFFFFFFFF;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// else{
|
||||
// saa->id += value - 1;
|
||||
// saa->next_id = 0xFFFFFFFF;
|
||||
// }
|
||||
//
|
||||
// uint32 current_level_mod = 0;
|
||||
// if(aa_stack)
|
||||
// current_level_mod = saa->sof_current_level;
|
||||
//
|
||||
// saa->last_id = saa->id - 1;
|
||||
// saa->current_level = value + (current_level_mod);
|
||||
// saa->cost = saa2->cost + (saa2->cost_inc*(value - 1));
|
||||
// saa->cost2 = 0;
|
||||
// for(uint32 i = 0; i < value; i++) {
|
||||
// saa->cost2 += saa2->cost + (saa2->cost_inc * i);
|
||||
// }
|
||||
// saa->class_type = saa2->class_type + (saa2->level_inc*(value - 1));
|
||||
//}
|
||||
//
|
||||
//if(aa_stack){
|
||||
//
|
||||
// if(saa->sof_current_level >= 1 && value == 0)
|
||||
// saa->current_level = saa->sof_current_level + 1;
|
||||
//
|
||||
// saa->max_level = saa->sof_max_level;
|
||||
//}
|
||||
//
|
||||
//database.FillAAEffects(saa);
|
||||
//
|
||||
//if(value > 0)
|
||||
//{
|
||||
// // AA_Action stores the base ID
|
||||
// const AA_DBAction *caa = &AA_Actions[saa->id - value + 1][value - 1];
|
||||
//
|
||||
// if(caa && caa->reuse_time > 0)
|
||||
// saa->spell_refresh = CalcAAReuseTimer(caa);
|
||||
//}
|
||||
//
|
||||
////You can now use the level_inc field in the altadv_vars table to accomplish this, though still needed
|
||||
////for special cases like LOH/HT due to inability to implement correct stacking of AA's that use hotkeys.
|
||||
//std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(saa->id);
|
||||
//
|
||||
//if(RequiredLevel != AARequiredLevelAndCost.end())
|
||||
//{
|
||||
// saa->class_type = RequiredLevel->second.Level;
|
||||
// saa->cost = RequiredLevel->second.Cost;
|
||||
//}
|
||||
//
|
||||
//
|
||||
//EQApplicationPacket* outapp = new EQApplicationPacket(OP_SendAATable);
|
||||
//outapp->size = size;
|
||||
//outapp->pBuffer = (uchar*)saa;
|
||||
//if(id == 0 && value && (orig_val < saa->max_level)) //send previous AA only on zone in
|
||||
// SendPreviousAA(id, seq);
|
||||
//
|
||||
//QueuePacket(outapp);
|
||||
//safe_delete(outapp);
|
||||
////will outapp delete the buffer for us even though it didnt make it? --- Yes, it should
|
||||
}
|
||||
|
||||
void Zone::LoadAlternateAdvancement() {
|
||||
Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Data...");
|
||||
if(!database.LoadAlternateAdvancementAbilities(zone->aa_abilities,
|
||||
zone->aa_ranks))
|
||||
if(!database.LoadAlternateAdvancementAbilities(aa_abilities,
|
||||
aa_ranks))
|
||||
{
|
||||
zone->aa_abilities.clear();
|
||||
zone->aa_ranks.clear();
|
||||
aa_abilities.clear();
|
||||
aa_ranks.clear();
|
||||
Log.Out(Logs::General, Logs::Status, "Failed to load Alternate Advancement Data");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Status, "Processing Alternate Advancement Data...");
|
||||
for(const auto &ability : aa_abilities) {
|
||||
ability.second->first = GetAlternateAdvancementRank(ability.second->first_rank_id);
|
||||
|
||||
//process these ranks
|
||||
AA::Rank *current = ability.second->first;
|
||||
while(current) {
|
||||
current->prev = GetAlternateAdvancementRank(current->prev_id);
|
||||
current->next = GetAlternateAdvancementRank(current->next_id);
|
||||
current->base_ability = ability.second.get();
|
||||
|
||||
if(current->prev) {
|
||||
current->total_cost = current->cost + current->prev->total_cost;
|
||||
} else {
|
||||
current->total_cost = current->cost;
|
||||
}
|
||||
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
ability.second->GetMaxLevel(true);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Abilities...");
|
||||
abilities.clear();
|
||||
std::string query = "SELECT id, name, expansion, category, classes, expendable, first_rank_id FROM aa_ability";
|
||||
std::string query = "SELECT id, name, expansion, category, classes, type, expendable, account_time_required, grant_only, first_rank_id FROM aa_ability";
|
||||
auto results = QueryDatabase(query);
|
||||
if(results.Success()) {
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
AA::Ability *ability = new AA::Ability;
|
||||
int id = atoi(row[0]);
|
||||
|
||||
ability->name = row[1];
|
||||
ability->expansion = atoi(row[2]);
|
||||
ability->category = atoi(row[3]);
|
||||
ability->classes = atoi(row[4]);
|
||||
ability->expendable = atoi(row[5]) != 0 ? true : false;
|
||||
ability->first_rank_id = atoi(row[6]);
|
||||
ability->type = atoi(row[5]);
|
||||
ability->expendable = atoi(row[6]) != 0 ? true : false;
|
||||
ability->account_time_required = atoul(row[7]);
|
||||
ability->grant_only = atoi(row[8]) != 0 ? true : false;
|
||||
ability->first_rank_id = atoi(row[9]);
|
||||
ability->first = nullptr;
|
||||
|
||||
abilities[id] = std::unique_ptr<AA::Ability>(ability);
|
||||
}
|
||||
@ -2132,6 +2401,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
AA::Rank *rank = new AA::Rank;
|
||||
int id = atoi(row[0]);
|
||||
rank->id = id;
|
||||
rank->upper_hotkey_sid = atoi(row[1]);
|
||||
rank->lower_hotkey_sid = atoi(row[2]);
|
||||
rank->title_sid = atoi(row[3]);
|
||||
@ -2143,6 +2413,10 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
||||
rank->recast_time = atoi(row[9]);
|
||||
rank->prev_id = atoi(row[10]);
|
||||
rank->next_id = atoi(row[11]);
|
||||
rank->base_ability = nullptr;
|
||||
rank->total_cost = 0;
|
||||
rank->next = nullptr;
|
||||
rank->prev = nullptr;
|
||||
|
||||
ranks[id] = std::unique_ptr<AA::Rank>(rank);
|
||||
}
|
||||
@ -2204,4 +2478,3 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
69
zone/aa_ability.cpp
Normal file
69
zone/aa_ability.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/types.h"
|
||||
#include "aa_ability.h"
|
||||
|
||||
AA::Rank *AA::Ability::GetMaxRank() {
|
||||
if(!first)
|
||||
return nullptr;
|
||||
|
||||
Rank *current = first;
|
||||
while(current->next) {
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
AA::Rank *AA::Ability::GetRankByPointsSpent(int current_level) {
|
||||
if(!first)
|
||||
return nullptr;
|
||||
|
||||
if(current_level == 0) {
|
||||
return GetMaxRank();
|
||||
}
|
||||
|
||||
int i = 1;
|
||||
Rank *current = first;
|
||||
while(current->next) {
|
||||
if(1 == current_level) {
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
int AA::Ability::GetMaxLevel(bool force_calc) {
|
||||
if(!force_calc)
|
||||
return max_level;
|
||||
|
||||
max_level = 0;
|
||||
Rank *current = first;
|
||||
while(current) {
|
||||
max_level++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return max_level;
|
||||
}
|
||||
@ -30,14 +30,27 @@
|
||||
namespace AA
|
||||
{
|
||||
|
||||
struct Ability
|
||||
class Ability
|
||||
{
|
||||
public:
|
||||
Ability() { }
|
||||
~Ability() { }
|
||||
|
||||
Rank *GetMaxRank();
|
||||
Rank *GetRankByPointsSpent(int current_level);
|
||||
int GetMaxLevel(bool force_calc = false);
|
||||
|
||||
std::string name;
|
||||
int expansion;
|
||||
int category;
|
||||
int classes;
|
||||
uint32 account_time_required;
|
||||
bool grant_only;
|
||||
int type;
|
||||
bool expendable;
|
||||
int first_rank_id;
|
||||
int max_level;
|
||||
Rank *first;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -22,8 +22,14 @@
|
||||
namespace AA
|
||||
{
|
||||
|
||||
struct Rank
|
||||
class Ability;
|
||||
class Rank
|
||||
{
|
||||
public:
|
||||
Rank() { }
|
||||
~Rank() { }
|
||||
|
||||
int id;
|
||||
int upper_hotkey_sid;
|
||||
int lower_hotkey_sid;
|
||||
int title_sid;
|
||||
@ -34,7 +40,11 @@ struct Rank
|
||||
int spell_type;
|
||||
int recast_time;
|
||||
int prev_id;
|
||||
Rank *prev;
|
||||
int next_id;
|
||||
Rank *next;
|
||||
int total_cost;
|
||||
Ability *base_ability;
|
||||
std::unordered_map<int, RankEffect> effects;
|
||||
std::vector<RankPrereq> prereqs;
|
||||
};
|
||||
|
||||
@ -759,7 +759,11 @@ public:
|
||||
|
||||
inline PTimerList &GetPTimers() { return(p_timers); }
|
||||
|
||||
//AA Methods
|
||||
//New AA Methods
|
||||
void SendAlternateAdvancement(int aa_id, bool first_login = false);
|
||||
void SendAlternateAdvancementList();
|
||||
|
||||
//old AA Methods
|
||||
void SendAAList();
|
||||
void ResetAA();
|
||||
void SendClearAA();
|
||||
|
||||
@ -1091,8 +1091,10 @@ void Client::Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_Connect_OP_SendAATable(const EQApplicationPacket *app)
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Error, "SendAAList()");
|
||||
SendAAList();
|
||||
//SendAAList();
|
||||
|
||||
SendAlternateAdvancementList();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1153,7 +1155,6 @@ void Client::Handle_Connect_OP_TGB(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app)
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Error, "SendAATable()");
|
||||
SendAATable();
|
||||
}
|
||||
|
||||
|
||||
@ -116,6 +116,8 @@ public:
|
||||
|
||||
//new AA
|
||||
void LoadAlternateAdvancement();
|
||||
AA::Ability *GetAlternateAdvancementAbility(int id);
|
||||
AA::Rank *GetAlternateAdvancementRank(int rank_id);
|
||||
|
||||
//old AA
|
||||
void LoadAAs();
|
||||
@ -319,10 +321,13 @@ private:
|
||||
int totalBS;
|
||||
ZoneSpellsBlocked *blocked_spells;
|
||||
|
||||
public:
|
||||
//new AA
|
||||
std::unordered_map<int, std::unique_ptr<AA::Ability>> aa_abilities;
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> aa_ranks;
|
||||
|
||||
private:
|
||||
|
||||
//old AA
|
||||
int totalAAs;
|
||||
SendAA_Struct **aas; //array of AA structs
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user