Merge branch 'master' into aa

This commit is contained in:
KimLS 2015-06-08 09:58:59 -07:00
commit 361c93b689
22 changed files with 347 additions and 339 deletions

File diff suppressed because it is too large Load Diff

View File

@ -726,6 +726,7 @@ struct AA_Array
{ {
uint32 AA; uint32 AA;
uint32 value; uint32 value;
uint32 charges;
}; };
@ -4321,14 +4322,6 @@ struct AA_Action {
/*12*/ uint32 exp_value; /*12*/ uint32 exp_value;
}; };
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct { struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability /*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent; /*04*/ uint32 aapoints_unspent;
@ -4346,12 +4339,12 @@ struct AltAdvStats_Struct {
}; };
struct PlayerAA_Struct { // Is this still used? struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY]; AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct AATable_Struct { struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent /*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY]; /*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct Weather_Struct { struct Weather_Struct {

View File

@ -2120,7 +2120,7 @@ namespace RoF
{ {
outapp->WriteUInt32(emu->aa_array[r].AA); outapp->WriteUInt32(emu->aa_array[r].AA);
outapp->WriteUInt32(emu->aa_array[r].value); outapp->WriteUInt32(emu->aa_array[r].value);
outapp->WriteUInt32(0); outapp->WriteUInt32(emu->aa_array[r].charges);
} }
// Fill the other 60 AAs with zeroes // Fill the other 60 AAs with zeroes
@ -2818,9 +2818,9 @@ namespace RoF
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i) for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
{ {
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill; eq->aa_list[i].AA = emu->aa_list[i].AA;
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value; eq->aa_list[i].value = emu->aa_list[i].value;
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08; eq->aa_list[i].charges = emu->aa_list[i].charges;
} }
FINISH_ENCODE(); FINISH_ENCODE();
@ -2868,9 +2868,9 @@ namespace RoF
OUT(cost); OUT(cost);
OUT(seq); OUT(seq);
OUT(current_level); OUT(current_level);
eq->unknown037 = 1; // Introduced during HoT eq->prereq_skill_count = 1; // min 1
OUT(prereq_skill); OUT(prereq_skill);
eq->unknown045 = 1; // New Mar 21 2012 - Seen 1 eq->prereq_minpoints_count = 1; // min 1
OUT(prereq_minpoints); OUT(prereq_minpoints);
eq->type = emu->sof_type; eq->type = emu->sof_type;
OUT(spellid); OUT(spellid);
@ -2886,6 +2886,7 @@ namespace RoF
OUT(cost2); OUT(cost2);
eq->aa_expansion = emu->aa_expansion; eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category; eq->special_category = emu->special_category;
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++) {

View File

@ -2200,7 +2200,7 @@ namespace RoF2
{ {
outapp->WriteUInt32(emu->aa_array[r].AA); outapp->WriteUInt32(emu->aa_array[r].AA);
outapp->WriteUInt32(emu->aa_array[r].value); outapp->WriteUInt32(emu->aa_array[r].value);
outapp->WriteUInt32(0); outapp->WriteUInt32(emu->aa_array[r].charges);
} }
// Fill the other 60 AAs with zeroes // Fill the other 60 AAs with zeroes
@ -2907,9 +2907,9 @@ namespace RoF2
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i) for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
{ {
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill; eq->aa_list[i].AA = emu->aa_list[i].AA;
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value; eq->aa_list[i].value = emu->aa_list[i].value;
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08; eq->aa_list[i].charges = emu->aa_list[i].charges;
} }
FINISH_ENCODE(); FINISH_ENCODE();
@ -2957,9 +2957,9 @@ namespace RoF2
OUT(cost); OUT(cost);
OUT(seq); OUT(seq);
OUT(current_level); OUT(current_level);
eq->unknown037 = 1; // Introduced during HoT eq->prereq_skill_count = 1; // min 1
OUT(prereq_skill); OUT(prereq_skill);
eq->unknown045 = 1; // New Mar 21 2012 - Seen 1 eq->prereq_minpoints_count = 1; // min 1
OUT(prereq_minpoints); OUT(prereq_minpoints);
eq->type = emu->sof_type; eq->type = emu->sof_type;
OUT(spellid); OUT(spellid);
@ -2976,6 +2976,7 @@ namespace RoF2
eq->aa_expansion = emu->aa_expansion; eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category; eq->special_category = emu->special_category;
OUT(total_abilities); OUT(total_abilities);
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
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);

View File

@ -877,7 +877,7 @@ struct AA_Array
{ {
uint32 AA; uint32 AA;
uint32 value; uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live uint32 charges; // expendable charges
}; };
struct Disciplines_Struct { struct Disciplines_Struct {
@ -4253,9 +4253,9 @@ struct SendAA_Struct {
/*0025*/ uint32 cost; /*0025*/ uint32 cost;
/*0029*/ uint32 seq; /*0029*/ uint32 seq;
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired /*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
/*0037*/ uint32 unknown037; // Introduced during HoT /*0037*/ uint32 prereq_skill_count; // mutliple prereqs at least 1, even no prereqs
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category # /*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
/*0045*/ uint32 unknown045; // New Mar 21 2012 - Seen 1 /*0045*/ uint32 prereq_minpoints_count; // mutliple prereqs at least 1, even no prereqs
/*0049*/ uint32 prereq_minpoints; //min points in the prereq /*0049*/ uint32 prereq_minpoints; //min points in the prereq
/*0053*/ uint32 type; /*0053*/ uint32 type;
/*0057*/ uint32 spellid; /*0057*/ uint32 spellid;
@ -4268,10 +4268,16 @@ struct SendAA_Struct {
/*0081*/ uint32 last_id; /*0081*/ uint32 last_id;
/*0085*/ uint32 next_id; /*0085*/ uint32 next_id;
/*0089*/ uint32 cost2; /*0089*/ uint32 cost2;
/*0093*/ uint8 unknown80[7]; /*0093*/ uint8 unknown93;
/*0094*/ uint8 grant_only; // VetAAs, progression, etc
/*0095*/ uint8 unknown95; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0096*/ uint32 expendable_charges; // max charges of the AA
/*0100*/ uint32 aa_expansion; /*0100*/ uint32 aa_expansion;
/*0104*/ uint32 special_category; /*0104*/ uint32 special_category;
/*0108*/ uint32 unknown0096; /*0108*/ uint8 shroud;
/*0109*/ uint8 unknown109;
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0111*/ uint8 unknown111;
/*0112*/ uint32 total_abilities; /*0112*/ uint32 total_abilities;
/*0116*/ AA_Ability abilities[0]; /*0116*/ AA_Ability abilities[0];
}; };
@ -4288,12 +4294,6 @@ struct AA_Action {
/*16*/ /*16*/
}; };
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct { struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability /*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
@ -4313,14 +4313,7 @@ struct AltAdvStats_Struct {
}; };
struct PlayerAA_Struct { // Is this still used? struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY]; AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AA_Values {
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
}; };
struct AATable_Struct { struct AATable_Struct {
@ -4330,7 +4323,7 @@ struct AATable_Struct {
/*12*/ uint32 aa_spent_archetype; // Seen 40 /*12*/ uint32 aa_spent_archetype; // Seen 40
/*16*/ uint32 aa_spent_class; // Seen 103 /*16*/ uint32 aa_spent_class; // Seen 103
/*20*/ uint32 aa_spent_special; // Seen 0 /*20*/ uint32 aa_spent_special; // Seen 0
/*24*/ AA_Values aa_list[MAX_PP_AA_ARRAY]; /*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct Weather_Struct { struct Weather_Struct {

View File

@ -866,7 +866,7 @@ struct AA_Array
{ {
uint32 AA; uint32 AA;
uint32 value; uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live uint32 charges; // expendable charges
}; };
struct Disciplines_Struct { struct Disciplines_Struct {
@ -4252,9 +4252,9 @@ struct SendAA_Struct {
/*0025*/ uint32 cost; /*0025*/ uint32 cost;
/*0029*/ uint32 seq; /*0029*/ uint32 seq;
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired /*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
/*0037*/ uint32 unknown037; // Introduced during HoT /*0037*/ uint32 prereq_skill_count; // mutliple prereqs at least 1, even no prereqs
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category # /*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
/*0045*/ uint32 unknown045; // New Mar 21 2012 - Seen 1 /*0045*/ uint32 prereq_minpoints_count; // mutliple prereqs at least 1, even no prereqs
/*0049*/ uint32 prereq_minpoints; //min points in the prereq /*0049*/ uint32 prereq_minpoints; //min points in the prereq
/*0053*/ uint32 type; /*0053*/ uint32 type;
/*0057*/ uint32 spellid; /*0057*/ uint32 spellid;
@ -4267,10 +4267,16 @@ struct SendAA_Struct {
/*0081*/ uint32 last_id; /*0081*/ uint32 last_id;
/*0085*/ uint32 next_id; /*0085*/ uint32 next_id;
/*0089*/ uint32 cost2; /*0089*/ uint32 cost2;
/*0093*/ uint8 unknown80[7]; /*0093*/ uint8 unknown93;
/*0094*/ uint8 grant_only; // VetAAs, progression, etc
/*0095*/ uint8 unknown95; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0096*/ uint32 expendable_charges; // max charges of the AA
/*0100*/ uint32 aa_expansion; /*0100*/ uint32 aa_expansion;
/*0104*/ uint32 special_category; /*0104*/ uint32 special_category;
/*0108*/ uint32 unknown0096; /*0108*/ uint8 shroud;
/*0109*/ uint8 unknown109;
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0111*/ uint8 unknown111;
/*0112*/ uint32 total_abilities; /*0112*/ uint32 total_abilities;
/*0116*/ AA_Ability abilities[0]; /*0116*/ AA_Ability abilities[0];
}; };
@ -4287,13 +4293,6 @@ struct AA_Action {
/*16*/ /*16*/
}; };
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct { struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability /*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent; /*04*/ uint32 aapoints_unspent;
@ -4312,14 +4311,7 @@ struct AltAdvStats_Struct {
}; };
struct PlayerAA_Struct { // Is this still used? struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY]; AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AA_Values {
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
}; };
struct AATable_Struct { struct AATable_Struct {
@ -4329,7 +4321,7 @@ struct AATable_Struct {
/*12*/ uint32 aa_spent_archetype; // Seen 40 /*12*/ uint32 aa_spent_archetype; // Seen 40
/*16*/ uint32 aa_spent_class; // Seen 103 /*16*/ uint32 aa_spent_class; // Seen 103
/*20*/ uint32 aa_spent_special; // Seen 0 /*20*/ uint32 aa_spent_special; // Seen 0
/*24*/ AA_Values aa_list[MAX_PP_AA_ARRAY]; /*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct Weather_Struct { struct Weather_Struct {

View File

@ -1558,6 +1558,7 @@ namespace SoD
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(unknown02220[4]); // OUT(unknown02220[4]);
OUT(mana); OUT(mana);
@ -1898,6 +1899,7 @@ namespace SoD
OUT(cost2); OUT(cost2);
eq->aa_expansion = emu->aa_expansion; eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category; eq->special_category = emu->special_category;
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++) {

View File

@ -666,7 +666,7 @@ struct AA_Array
{ {
uint32 AA; uint32 AA;
uint32 value; uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live uint32 charges; // expendable
}; };
@ -3819,10 +3819,16 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id; /*0069*/ uint32 last_id;
/*0073*/ uint32 next_id; /*0073*/ uint32 next_id;
/*0077*/ uint32 cost2; /*0077*/ uint32 cost2;
/*0081*/ uint8 unknown80[7]; /*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0088*/ uint32 aa_expansion; /*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category; /*0092*/ uint32 special_category;
/*0096*/ uint32 unknown0096; /*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0099*/ uint8 unknown99;
/*0100*/ uint32 total_abilities; /*0100*/ uint32 total_abilities;
/*0104*/ AA_Ability abilities[0]; /*0104*/ AA_Ability abilities[0];
}; };
@ -3838,12 +3844,6 @@ struct AA_Action {
/*12*/ uint32 exp_value; /*12*/ uint32 exp_value;
}; };
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct { struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability /*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent; /*04*/ uint32 aapoints_unspent;
@ -3861,12 +3861,12 @@ struct AltAdvStats_Struct {
}; };
struct PlayerAA_Struct { // Is this still used? struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY]; AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct AATable_Struct { struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent /*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY]; /*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct Weather_Struct { struct Weather_Struct {

View File

@ -1216,6 +1216,7 @@ namespace SoF
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(unknown02220[4]); // OUT(unknown02220[4]);
OUT(mana); OUT(mana);
@ -1557,6 +1558,7 @@ namespace SoF
OUT(cost2); OUT(cost2);
eq->aa_expansion = emu->aa_expansion; eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category; eq->special_category = emu->special_category;
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++) {

View File

@ -645,7 +645,7 @@ struct AA_Array
{ {
uint32 AA; uint32 AA;
uint32 value; uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live uint32 charges; // expendable charges
}; };
@ -3683,10 +3683,14 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id; /*0069*/ uint32 last_id;
/*0073*/ uint32 next_id; /*0073*/ uint32 next_id;
/*0077*/ uint32 cost2; /*0077*/ uint32 cost2;
/*0081*/ uint8 unknown80[7]; /*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0088*/ uint32 aa_expansion; /*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category; /*0092*/ uint32 special_category;
/*0096*/ uint16 unknown0096; /*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0098*/ uint32 total_abilities; /*0098*/ uint32 total_abilities;
/*0102*/ AA_Ability abilities[0]; /*0102*/ AA_Ability abilities[0];
}; };
@ -3702,12 +3706,6 @@ struct AA_Action {
/*12*/ uint32 exp_value; /*12*/ uint32 exp_value;
}; };
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct { struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability /*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent; /*04*/ uint32 aapoints_unspent;
@ -3725,12 +3723,12 @@ struct AltAdvStats_Struct {
}; };
struct PlayerAA_Struct { struct PlayerAA_Struct {
AA_Skills aa_list[MAX_PP_AA_ARRAY]; AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct AATable_Struct { struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent /*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY]; /*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct Weather_Struct { struct Weather_Struct {

View File

@ -1098,8 +1098,8 @@ namespace Titanium
unsigned int r; unsigned int r;
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) { for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
OUT(aa_list[r].aa_skill); OUT(aa_list[r].AA);
OUT(aa_list[r].aa_value); OUT(aa_list[r].value);
} }
FINISH_ENCODE(); FINISH_ENCODE();

View File

@ -3179,11 +3179,6 @@ struct AA_Action {
/*12*/ uint32 exp_value; /*12*/ uint32 exp_value;
}; };
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
};
struct AAExpUpdate_Struct { struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability /*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent; /*04*/ uint32 aapoints_unspent;
@ -3201,11 +3196,11 @@ struct AltAdvStats_Struct {
}; };
struct PlayerAA_Struct { struct PlayerAA_Struct {
AA_Skills aa_list[MAX_PP_AA_ARRAY]; AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct AATable_Struct { struct AATable_Struct {
AA_Skills aa_list[MAX_PP_AA_ARRAY]; AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct Weather_Struct { struct Weather_Struct {

View File

@ -1807,6 +1807,7 @@ namespace UF
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(unknown02220[4]); // OUT(unknown02220[4]);
OUT(mana); OUT(mana);
@ -2134,9 +2135,9 @@ namespace UF
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i) for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
{ {
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill; eq->aa_list[i].AA = emu->aa_list[i].AA;
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value; eq->aa_list[i].value = emu->aa_list[i].value;
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08; eq->aa_list[i].charges = emu->aa_list[i].charges;
} }
FINISH_ENCODE(); FINISH_ENCODE();
@ -2181,6 +2182,7 @@ namespace UF
OUT(cost2); OUT(cost2);
eq->aa_expansion = emu->aa_expansion; eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category; eq->special_category = emu->special_category;
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++) {

View File

@ -713,7 +713,7 @@ struct AA_Array
{ {
uint32 AA; uint32 AA;
uint32 value; uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Underfoot uint32 charges; // expendable
}; };
@ -3892,10 +3892,16 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id; /*0069*/ uint32 last_id;
/*0073*/ uint32 next_id; /*0073*/ uint32 next_id;
/*0077*/ uint32 cost2; /*0077*/ uint32 cost2;
/*0081*/ uint8 unknown80[7]; /*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0088*/ uint32 aa_expansion; /*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category; /*0092*/ uint32 special_category;
/*0096*/ uint32 unknown0096; /*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0099*/ uint8 unknown99;
/*0100*/ uint32 total_abilities; /*0100*/ uint32 total_abilities;
/*0104*/ AA_Ability abilities[0]; /*0104*/ AA_Ability abilities[0];
}; };
@ -3911,11 +3917,6 @@ struct AA_Action {
/*12*/ uint32 exp_value; /*12*/ uint32 exp_value;
}; };
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct { struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability /*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
@ -3934,7 +3935,7 @@ struct AltAdvStats_Struct {
}; };
struct PlayerAA_Struct { // Is this still used? struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY]; AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct AATable_Struct { struct AATable_Struct {
@ -3944,7 +3945,7 @@ struct AATable_Struct {
/*12*/ int32 unknown012; /*12*/ int32 unknown012;
/*16*/ int32 unknown016; /*16*/ int32 unknown016;
/*20*/ int32 unknown020; /*20*/ int32 unknown020;
/*24*/ AA_Skills aa_list[MAX_PP_AA_ARRAY]; /*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
}; };
struct Weather_Struct { struct Weather_Struct {

View File

@ -30,7 +30,7 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/ */
#define CURRENT_BINARY_DATABASE_VERSION 9082 #define CURRENT_BINARY_DATABASE_VERSION 9083
#define COMPILE_DATE __DATE__ #define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__ #define COMPILE_TIME __TIME__
#ifndef WIN32 #ifndef WIN32

View File

@ -336,6 +336,7 @@
9080|2015_05_23_PetBuffInstrumentMod.sql|SHOW COLUMNS FROM `character_pet_buffs` LIKE 'instrument_mod'|empty| 9080|2015_05_23_PetBuffInstrumentMod.sql|SHOW COLUMNS FROM `character_pet_buffs` LIKE 'instrument_mod'|empty|
9081|2015_05_23_dbstr_us.sql|SHOW TABLES LIKE 'db_str'|empty| 9081|2015_05_23_dbstr_us.sql|SHOW TABLES LIKE 'db_str'|empty|
9082|2015_05_25_npc_types_texture_fields.sql|SHOW COLUMNS FROM `npc_types` LIKE 'armtexture'|empty| 9082|2015_05_25_npc_types_texture_fields.sql|SHOW COLUMNS FROM `npc_types` LIKE 'armtexture'|empty|
9083|2015_06_07_aa_update.sql|SHOW COLUMNS FROM `character_alternate_abilities` LIKE 'charges'|empty|
# Upgrade conditions: # Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not # This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1 @@
ALTER TABLE character_alternate_abilities ADD COLUMN charges SMALLINT(11) UNSIGNED NOT NULL DEFAULT 0;

View File

@ -1104,9 +1104,9 @@ void Client::SendAATable() {
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_skill = aa[i]->AA; 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_value = aa[i]->value; aa2->aa_list[i].value = aa[i]->value;
aa2->aa_list[i].unknown08 = 0; aa2->aa_list[i].charges = aa[i]->charges;
} }
QueuePacket(outapp); QueuePacket(outapp);
safe_delete(outapp); safe_delete(outapp);
@ -1395,26 +1395,33 @@ uint32 Client::GetAA(uint32 aa_id) const {
bool Client::SetAA(uint32 aa_id, uint32 new_value) { bool Client::SetAA(uint32 aa_id, uint32 new_value) {
aa_points[aa_id] = new_value; aa_points[aa_id] = new_value;
uint32 cur; 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++){ for(cur=0;cur < MAX_PP_AA_ARRAY;cur++){
if((aa[cur]->value > 1) && ((aa[cur]->AA - aa[cur]->value + 1)== aa_id)){ if((aa[cur]->value > 1) && ((aa[cur]->AA - aa[cur]->value + 1)== aa_id)){
aa[cur]->value = new_value; aa[cur]->value = new_value;
if(new_value > 0) if(new_value > 0)
aa[cur]->AA++; aa[cur]->AA++;
else aa[cur]->charges = charges;
aa[cur]->AA = 0;
return true; return true;
} }
else if((aa[cur]->value == 1) && (aa[cur]->AA == aa_id)){ else if((aa[cur]->value == 1) && (aa[cur]->AA == aa_id)){
aa[cur]->value = new_value; aa[cur]->value = new_value;
if(new_value > 0) if(new_value > 0)
aa[cur]->AA++; aa[cur]->AA++;
else aa[cur]->charges = charges;
aa[cur]->AA = 0; 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; return true;
} }
else if(aa[cur]->AA==0){ //end of list else if(aa[cur]->AA==0){ //end of list
aa[cur]->AA = aa_id; aa[cur]->AA = aa_id;
aa[cur]->value = new_value; aa[cur]->value = new_value;
aa[cur]->charges = charges;
return true; return true;
} }
} }
@ -1485,8 +1492,10 @@ void Client::ResetAA(){
for (i=0; i < MAX_PP_AA_ARRAY; i++) { for (i=0; i < MAX_PP_AA_ARRAY; i++) {
aa[i]->AA = 0; aa[i]->AA = 0;
aa[i]->value = 0; aa[i]->value = 0;
m_pp.aa_array[MAX_PP_AA_ARRAY].AA = 0; aa[i]->charges = 0;
m_pp.aa_array[MAX_PP_AA_ARRAY].value = 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; std::map<uint32,uint8>::iterator itr;

View File

@ -549,17 +549,22 @@ bool Client::SaveAA(){
} }
} }
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa; m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
int highest = 0;
for (int a = 0; a < MAX_PP_AA_ARRAY; a++) { 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){ if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value)" rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value, charges)"
" VALUES (%u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value); " VALUES (%u, %u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value, aa[a]->charges);
first_entry = 1; 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); 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; return true;
} }

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; } 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 */ /* 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( query = StringFormat(
"SELECT " "SELECT "
"slot, " "slot, "
"aa_id, " "aa_id, "
"aa_value " "aa_value, "
"charges "
"FROM " "FROM "
"`character_alternate_abilities` " "`character_alternate_abilities` "
"WHERE `id` = %u ORDER BY `slot`", this->CharacterID()); "WHERE `id` = %u ORDER BY `slot`", this->CharacterID());
results = database.QueryDatabase(query); i = 0; 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) { 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].AA = atoi(row[1]);
m_pp.aa_array[i].value = atoi(row[2]); m_pp.aa_array[i].value = atoi(row[2]);
aa[i]->AA = atoi(row[1]); m_pp.aa_array[i].charges = atoi(row[3]);
aa[i]->value = atoi(row[2]); /* 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++){ for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++){
uint32 id = aa[a]->AA; uint32 id = aa[a]->AA;

View File

@ -1710,10 +1710,10 @@ bool ZoneDatabase::SaveCharacterCurrency(uint32 character_id, PlayerProfile_Stru
return true; return true;
} }
bool ZoneDatabase::SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 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)" std::string rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, aa_id, aa_value, charges)"
" VALUES (%u, %u, %u)", " VALUES (%u, %u, %u, %u)",
character_id, aa_id, current_level); character_id, aa_id, current_level, charges);
auto results = QueryDatabase(rquery); 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); 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; return true;

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 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 SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); 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 SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
bool SaveCharacterMemorizedSpell(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); bool SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color);