Merge branch 'master' into aa

This commit is contained in:
KimLS
2015-06-08 09:58:59 -07:00
22 changed files with 347 additions and 339 deletions
+18 -9
View File
@@ -1104,9 +1104,9 @@ void Client::SendAATable() {
uint32 i;
for(i=0;i < MAX_PP_AA_ARRAY;i++){
aa2->aa_list[i].aa_skill = aa[i]->AA;
aa2->aa_list[i].aa_value = aa[i]->value;
aa2->aa_list[i].unknown08 = 0;
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);
@@ -1395,26 +1395,33 @@ uint32 Client::GetAA(uint32 aa_id) const {
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++;
else
aa[cur]->AA = 0;
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++;
else
aa[cur]->AA = 0;
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;
}
}
@@ -1485,8 +1492,10 @@ void Client::ResetAA(){
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;
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;
+9 -4
View File
@@ -549,17 +549,22 @@ bool Client::SaveAA(){
}
}
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 && aa[a]->value){
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)"
" VALUES (%u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value);
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);
}
rquery = rquery + StringFormat(", (%u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value);
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;
}
+15 -5
View File
@@ -1442,22 +1442,32 @@ 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]; }
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 "
"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]);
i = atoi(row[0]) - offset;
m_pp.aa_array[i].AA = atoi(row[1]);
m_pp.aa_array[i].value = atoi(row[2]);
aa[i]->AA = atoi(row[1]);
aa[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;
+4 -4
View File
@@ -1710,10 +1710,10 @@ bool ZoneDatabase::SaveCharacterCurrency(uint32 character_id, PlayerProfile_Stru
return true;
}
bool ZoneDatabase::SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level){
std::string rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, aa_id, aa_value)"
" VALUES (%u, %u, %u)",
character_id, aa_id, current_level);
bool ZoneDatabase::SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level, uint32 charges){
std::string rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, aa_id, aa_value, charges)"
" VALUES (%u, %u, %u, %u)",
character_id, aa_id, current_level, charges);
auto results = QueryDatabase(rquery);
Log.Out(Logs::General, Logs::None, "Saving AA for character ID: %u, aa_id: %u current_level: %u", character_id, aa_id, current_level);
return true;
+1 -1
View File
@@ -279,7 +279,7 @@ public:
bool SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, const glm::vec4& position, uint8 is_home);
bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level);
bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level, uint32 charges);
bool SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
bool SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
bool SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color);