mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-25 14:38:20 +00:00
More aa work, it actually loads yay
This commit is contained in:
@@ -4220,7 +4220,7 @@ struct UseAA_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//new AA stuff
|
//new AA stuff
|
||||||
|
//reference only
|
||||||
struct AARankInfo_Struct
|
struct AARankInfo_Struct
|
||||||
{
|
{
|
||||||
uint32 id;
|
uint32 id;
|
||||||
@@ -4244,6 +4244,7 @@ struct AARankInfo_Struct
|
|||||||
int32 expansion;
|
int32 expansion;
|
||||||
int32 category;
|
int32 category;
|
||||||
uint8 expendable;
|
uint8 expendable;
|
||||||
|
uint8 grant_only;
|
||||||
uint32 total_effects;
|
uint32 total_effects;
|
||||||
uint32 total_prereqs;
|
uint32 total_prereqs;
|
||||||
};
|
};
|
||||||
|
|||||||
+63
-8
@@ -1804,11 +1804,11 @@ namespace UF
|
|||||||
// OUT(unknown00224[48]);
|
// OUT(unknown00224[48]);
|
||||||
//NOTE: new client supports 300 AAs, our internal rep/PP
|
//NOTE: new client supports 300 AAs, our internal rep/PP
|
||||||
//only supports 240..
|
//only supports 240..
|
||||||
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
//for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
||||||
OUT(aa_array[r].AA);
|
// OUT(aa_array[r].AA);
|
||||||
OUT(aa_array[r].value);
|
// OUT(aa_array[r].value);
|
||||||
OUT(aa_array[r].charges);
|
// OUT(aa_array[r].charges);
|
||||||
}
|
//}
|
||||||
// OUT(unknown02220[4]);
|
// OUT(unknown02220[4]);
|
||||||
OUT(mana);
|
OUT(mana);
|
||||||
OUT(cur_hp);
|
OUT(cur_hp);
|
||||||
@@ -2145,13 +2145,66 @@ namespace UF
|
|||||||
|
|
||||||
ENCODE(OP_SendAATable)
|
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);
|
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
|
||||||
SETUP_VAR_ENCODE(SendAA_Struct);
|
SETUP_VAR_ENCODE(SendAA_Struct);
|
||||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
|
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
|
// Check clientver field to verify this AA should be sent for SoF
|
||||||
// clientver 1 is for all clients and 6 is for Underfoot
|
// clientver 1 is for all clients and 6 is for Underfoot
|
||||||
if (emu->clientver <= 6)
|
if(emu->clientver <= 6)
|
||||||
{
|
{
|
||||||
OUT(id);
|
OUT(id);
|
||||||
eq->unknown004 = 1;
|
eq->unknown004 = 1;
|
||||||
@@ -2174,7 +2227,7 @@ namespace UF
|
|||||||
OUT(spell_type);
|
OUT(spell_type);
|
||||||
OUT(spell_refresh);
|
OUT(spell_refresh);
|
||||||
OUT(classes);
|
OUT(classes);
|
||||||
OUT(berserker);
|
//OUT(berserker);
|
||||||
//eq->max_level = emu->sof_max_level;
|
//eq->max_level = emu->sof_max_level;
|
||||||
OUT(max_level);
|
OUT(max_level);
|
||||||
OUT(last_id);
|
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
|
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
||||||
OUT(total_abilities);
|
OUT(total_abilities);
|
||||||
unsigned int r;
|
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].skill_id);
|
||||||
OUT(abilities[r].base1);
|
OUT(abilities[r].base1);
|
||||||
OUT(abilities[r].base2);
|
OUT(abilities[r].base2);
|
||||||
@@ -2193,7 +2246,9 @@ namespace UF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Out(Logs::General, Logs::Status, "%s", DumpPacketToString(__packet).c_str());
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_SendCharInfo)
|
ENCODE(OP_SendCharInfo)
|
||||||
|
|||||||
@@ -3886,8 +3886,7 @@ struct SendAA_Struct {
|
|||||||
/*0049*/ uint32 spellid;
|
/*0049*/ uint32 spellid;
|
||||||
/*0053*/ uint32 spell_type;
|
/*0053*/ uint32 spell_type;
|
||||||
/*0057*/ uint32 spell_refresh;
|
/*0057*/ uint32 spell_refresh;
|
||||||
/*0061*/ uint16 classes;
|
/*0061*/ uint32 classes;
|
||||||
/*0063*/ uint16 berserker; //seems to be 1 if its a berserker ability
|
|
||||||
/*0065*/ uint32 max_level;
|
/*0065*/ uint32 max_level;
|
||||||
/*0069*/ uint32 last_id;
|
/*0069*/ uint32 last_id;
|
||||||
/*0073*/ uint32 next_id;
|
/*0073*/ uint32 next_id;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
|||||||
|
|
||||||
SET(zone_sources
|
SET(zone_sources
|
||||||
aa.cpp
|
aa.cpp
|
||||||
|
aa_ability.cpp
|
||||||
aggro.cpp
|
aggro.cpp
|
||||||
attack.cpp
|
attack.cpp
|
||||||
beacon.cpp
|
beacon.cpp
|
||||||
|
|||||||
+294
-21
@@ -1097,22 +1097,24 @@ void Client::SendAATimers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendAATable() {
|
void Client::SendAATable() {
|
||||||
|
Log.Out(Logs::General, Logs::Status, "SendAATable()");
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_RespondAA, sizeof(AATable_Struct));
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_RespondAA, sizeof(AATable_Struct));
|
||||||
|
|
||||||
AATable_Struct* aa2 = (AATable_Struct *)outapp->pBuffer;
|
AATable_Struct* aa2 = (AATable_Struct *)outapp->pBuffer;
|
||||||
aa2->aa_spent = GetAAPointsSpent();
|
//aa2->aa_spent = GetAAPointsSpent();
|
||||||
|
//
|
||||||
uint32 i;
|
//uint32 i;
|
||||||
for(i=0;i < MAX_PP_AA_ARRAY;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].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].value = aa[i]->value;
|
||||||
aa2->aa_list[i].charges = aa[i]->charges;
|
// aa2->aa_list[i].charges = aa[i]->charges;
|
||||||
}
|
//}
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendPreviousAA(uint32 id, int seq){
|
void Client::SendPreviousAA(uint32 id, int seq){
|
||||||
|
Log.Out(Logs::General, Logs::Status, "SendPreviousAA(%u, %i)", id, seq);
|
||||||
uint32 value=0;
|
uint32 value=0;
|
||||||
SendAA_Struct* saa2 = nullptr;
|
SendAA_Struct* saa2 = nullptr;
|
||||||
if(id==0)
|
if(id==0)
|
||||||
@@ -1148,11 +1150,13 @@ void Client::SendPreviousAA(uint32 id, int seq){
|
|||||||
}
|
}
|
||||||
|
|
||||||
database.FillAAEffects(saa);
|
database.FillAAEffects(saa);
|
||||||
|
Log.Out(Logs::General, Logs::Status, "%s", DumpPacketToString(outapp).c_str());
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendAA(uint32 id, int seq) {
|
void Client::SendAA(uint32 id, int seq) {
|
||||||
|
Log.Out(Logs::General, Logs::Status, "SendAA(%u, %i)", id, seq);
|
||||||
|
|
||||||
uint32 value=0;
|
uint32 value=0;
|
||||||
SendAA_Struct* saa2 = nullptr;
|
SendAA_Struct* saa2 = nullptr;
|
||||||
@@ -1368,6 +1372,7 @@ void Client::SendAA(uint32 id, int seq) {
|
|||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SendAATable);
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SendAATable);
|
||||||
outapp->size=size;
|
outapp->size=size;
|
||||||
outapp->pBuffer=(uchar*)saa;
|
outapp->pBuffer=(uchar*)saa;
|
||||||
|
|
||||||
if(id==0 && value && (orig_val < saa->max_level)) //send previous AA only on zone in
|
if(id==0 && value && (orig_val < saa->max_level)) //send previous AA only on zone in
|
||||||
SendPreviousAA(id, seq);
|
SendPreviousAA(id, seq);
|
||||||
|
|
||||||
@@ -1377,10 +1382,13 @@ void Client::SendAA(uint32 id, int seq) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendAAList(){
|
void Client::SendAAList(){
|
||||||
// int total = zone->GetTotalAAs();
|
Log.Out(Logs::General, Logs::Status, "SendAAList()");
|
||||||
// for(int i=0;i < total;i++){
|
int total = zone->GetTotalAAs();
|
||||||
// SendAA(0,i);
|
|
||||||
// }
|
total = total > 2 ? 2 : total;
|
||||||
|
for(int i=0;i < total;i++){
|
||||||
|
SendAA(0,i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Client::GetAA(uint32 aa_id) const {
|
uint32 Client::GetAA(uint32 aa_id) const {
|
||||||
@@ -2080,39 +2088,300 @@ Mob *AA_SwarmPetInfo::GetOwner()
|
|||||||
return entity_list.GetMobID(owner_id);
|
return entity_list.GetMobID(owner_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::SendAlternateAdvancementList() {
|
||||||
|
for(auto &aa : zone->aa_abilities) {
|
||||||
|
SendAlternateAdvancement(aa.first, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//New AA
|
//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() {
|
void Zone::LoadAlternateAdvancement() {
|
||||||
Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Data...");
|
Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Data...");
|
||||||
if(!database.LoadAlternateAdvancementAbilities(zone->aa_abilities,
|
if(!database.LoadAlternateAdvancementAbilities(aa_abilities,
|
||||||
zone->aa_ranks))
|
aa_ranks))
|
||||||
{
|
{
|
||||||
zone->aa_abilities.clear();
|
aa_abilities.clear();
|
||||||
zone->aa_ranks.clear();
|
aa_ranks.clear();
|
||||||
Log.Out(Logs::General, Logs::Status, "Failed to load Alternate Advancement Data");
|
Log.Out(Logs::General, Logs::Status, "Failed to load Alternate Advancement Data");
|
||||||
return;
|
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");
|
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,
|
bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std::unique_ptr<AA::Ability>> &abilities,
|
||||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> &ranks)
|
std::unordered_map<int, std::unique_ptr<AA::Rank>> &ranks)
|
||||||
{
|
{
|
||||||
Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Abilities...");
|
Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Abilities...");
|
||||||
abilities.clear();
|
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);
|
auto results = QueryDatabase(query);
|
||||||
if(results.Success()) {
|
if(results.Success()) {
|
||||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||||
AA::Ability *ability = new AA::Ability;
|
AA::Ability *ability = new AA::Ability;
|
||||||
int id = atoi(row[0]);
|
int id = atoi(row[0]);
|
||||||
|
|
||||||
ability->name = row[1];
|
ability->name = row[1];
|
||||||
ability->expansion = atoi(row[2]);
|
ability->expansion = atoi(row[2]);
|
||||||
ability->category = atoi(row[3]);
|
ability->category = atoi(row[3]);
|
||||||
ability->classes = atoi(row[4]);
|
ability->classes = atoi(row[4]);
|
||||||
ability->expendable = atoi(row[5]) != 0 ? true : false;
|
ability->type = atoi(row[5]);
|
||||||
ability->first_rank_id = atoi(row[6]);
|
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);
|
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) {
|
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||||
AA::Rank *rank = new AA::Rank;
|
AA::Rank *rank = new AA::Rank;
|
||||||
int id = atoi(row[0]);
|
int id = atoi(row[0]);
|
||||||
|
rank->id = id;
|
||||||
rank->upper_hotkey_sid = atoi(row[1]);
|
rank->upper_hotkey_sid = atoi(row[1]);
|
||||||
rank->lower_hotkey_sid = atoi(row[2]);
|
rank->lower_hotkey_sid = atoi(row[2]);
|
||||||
rank->title_sid = atoi(row[3]);
|
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->recast_time = atoi(row[9]);
|
||||||
rank->prev_id = atoi(row[10]);
|
rank->prev_id = atoi(row[10]);
|
||||||
rank->next_id = atoi(row[11]);
|
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);
|
ranks[id] = std::unique_ptr<AA::Rank>(rank);
|
||||||
}
|
}
|
||||||
@@ -2204,4 +2478,3 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
+14
-1
@@ -30,14 +30,27 @@
|
|||||||
namespace AA
|
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;
|
std::string name;
|
||||||
int expansion;
|
int expansion;
|
||||||
int category;
|
int category;
|
||||||
int classes;
|
int classes;
|
||||||
|
uint32 account_time_required;
|
||||||
|
bool grant_only;
|
||||||
|
int type;
|
||||||
bool expendable;
|
bool expendable;
|
||||||
int first_rank_id;
|
int first_rank_id;
|
||||||
|
int max_level;
|
||||||
|
Rank *first;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -22,8 +22,14 @@
|
|||||||
namespace AA
|
namespace AA
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Rank
|
class Ability;
|
||||||
|
class Rank
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
Rank() { }
|
||||||
|
~Rank() { }
|
||||||
|
|
||||||
|
int id;
|
||||||
int upper_hotkey_sid;
|
int upper_hotkey_sid;
|
||||||
int lower_hotkey_sid;
|
int lower_hotkey_sid;
|
||||||
int title_sid;
|
int title_sid;
|
||||||
@@ -34,7 +40,11 @@ struct Rank
|
|||||||
int spell_type;
|
int spell_type;
|
||||||
int recast_time;
|
int recast_time;
|
||||||
int prev_id;
|
int prev_id;
|
||||||
|
Rank *prev;
|
||||||
int next_id;
|
int next_id;
|
||||||
|
Rank *next;
|
||||||
|
int total_cost;
|
||||||
|
Ability *base_ability;
|
||||||
std::unordered_map<int, RankEffect> effects;
|
std::unordered_map<int, RankEffect> effects;
|
||||||
std::vector<RankPrereq> prereqs;
|
std::vector<RankPrereq> prereqs;
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-1
@@ -759,7 +759,11 @@ public:
|
|||||||
|
|
||||||
inline PTimerList &GetPTimers() { return(p_timers); }
|
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 SendAAList();
|
||||||
void ResetAA();
|
void ResetAA();
|
||||||
void SendClearAA();
|
void SendClearAA();
|
||||||
|
|||||||
@@ -1091,8 +1091,10 @@ void Client::Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_Connect_OP_SendAATable(const EQApplicationPacket *app)
|
void Client::Handle_Connect_OP_SendAATable(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
Log.Out(Logs::General, Logs::Error, "SendAAList()");
|
//SendAAList();
|
||||||
SendAAList();
|
|
||||||
|
SendAlternateAdvancementList();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1153,7 +1155,6 @@ void Client::Handle_Connect_OP_TGB(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app)
|
void Client::Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
Log.Out(Logs::General, Logs::Error, "SendAATable()");
|
|
||||||
SendAATable();
|
SendAATable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ public:
|
|||||||
|
|
||||||
//new AA
|
//new AA
|
||||||
void LoadAlternateAdvancement();
|
void LoadAlternateAdvancement();
|
||||||
|
AA::Ability *GetAlternateAdvancementAbility(int id);
|
||||||
|
AA::Rank *GetAlternateAdvancementRank(int rank_id);
|
||||||
|
|
||||||
//old AA
|
//old AA
|
||||||
void LoadAAs();
|
void LoadAAs();
|
||||||
@@ -319,10 +321,13 @@ private:
|
|||||||
int totalBS;
|
int totalBS;
|
||||||
ZoneSpellsBlocked *blocked_spells;
|
ZoneSpellsBlocked *blocked_spells;
|
||||||
|
|
||||||
|
public:
|
||||||
//new AA
|
//new AA
|
||||||
std::unordered_map<int, std::unique_ptr<AA::Ability>> aa_abilities;
|
std::unordered_map<int, std::unique_ptr<AA::Ability>> aa_abilities;
|
||||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> aa_ranks;
|
std::unordered_map<int, std::unique_ptr<AA::Rank>> aa_ranks;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
//old AA
|
//old AA
|
||||||
int totalAAs;
|
int totalAAs;
|
||||||
SendAA_Struct **aas; //array of AA structs
|
SendAA_Struct **aas; //array of AA structs
|
||||||
|
|||||||
Reference in New Issue
Block a user