mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
Merge conflicts abound and now are fixed
This commit is contained in:
commit
214873c139
@ -150,4 +150,26 @@ static ClientVersion ClientVersionFromBit(uint32 clientVersionBit)
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 ExpansionFromClientVersion(ClientVersion clientVersion)
|
||||
{
|
||||
switch(clientVersion)
|
||||
{
|
||||
case ClientVersion::Unknown:
|
||||
case ClientVersion::Client62:
|
||||
case ClientVersion::Titanium:
|
||||
return 0x000007FFU;
|
||||
case ClientVersion::SoF:
|
||||
return 0x00007FFFU;
|
||||
case ClientVersion::SoD:
|
||||
return 0x0000FFFFU;
|
||||
case ClientVersion::UF:
|
||||
return 0x0001FFFFU;
|
||||
case ClientVersion::RoF:
|
||||
case ClientVersion::RoF2:
|
||||
return 0x000FFFFFU;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CLIENTVERSIONS_H */
|
||||
|
||||
@ -548,4 +548,5 @@ N(OP_ZoneServerInfo),
|
||||
N(OP_ZoneServerReady),
|
||||
N(OP_ZoneSpawns),
|
||||
N(OP_ZoneUnavail),
|
||||
N(OP_ResetAA),
|
||||
// mail and chat opcodes located in ../mail_oplist.h
|
||||
|
||||
@ -4219,6 +4219,52 @@ struct UseAA_Struct {
|
||||
uint32 end;
|
||||
};
|
||||
|
||||
//new AA stuff
|
||||
//reference only
|
||||
struct AARankInfo_Struct
|
||||
{
|
||||
uint32 id;
|
||||
int32 upper_hotkey_sid;
|
||||
int32 lower_hotkey_sid;
|
||||
int32 title_sid;
|
||||
int32 desc_sid;
|
||||
int32 level_req;
|
||||
int32 cost;
|
||||
uint32 seq;
|
||||
uint32 current_level;
|
||||
uint32 type;
|
||||
int32 spell;
|
||||
int32 spell_type;
|
||||
int32 spell_refresh;
|
||||
int32 classes;
|
||||
int32 max_level;
|
||||
int32 prev_id;
|
||||
int32 next_id;
|
||||
int32 total_cost;
|
||||
int32 expansion;
|
||||
int32 category;
|
||||
uint32 charges;
|
||||
uint8 grant_only;
|
||||
uint32 total_effects;
|
||||
uint32 total_prereqs;
|
||||
};
|
||||
|
||||
struct AARankPrereq_Struct
|
||||
{
|
||||
int32 aa_id;
|
||||
int32 points;
|
||||
};
|
||||
|
||||
struct AARankEffect_Struct
|
||||
{
|
||||
int32 effect_id;
|
||||
int32 base1;
|
||||
int32 base2;
|
||||
int32 slot;
|
||||
};
|
||||
|
||||
//old AA stuff
|
||||
|
||||
struct AA_Ability {
|
||||
/*00*/ uint32 skill_id;
|
||||
/*04*/ uint32 base1;
|
||||
@ -4273,7 +4319,7 @@ struct SendAA_Struct {
|
||||
struct AA_Action {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint32 ability;
|
||||
/*08*/ uint32 unknown08;
|
||||
/*08*/ uint32 target_id;
|
||||
/*12*/ uint32 exp_value;
|
||||
};
|
||||
|
||||
|
||||
@ -2810,7 +2810,7 @@ namespace RoF
|
||||
|
||||
eq->aa_spent = emu->aa_spent;
|
||||
// These fields may need to be correctly populated at some point
|
||||
eq->aapoints_assigned = emu->aa_spent + 1;
|
||||
eq->aapoints_assigned = emu->aa_spent;
|
||||
eq->aa_spent_general = 0;
|
||||
eq->aa_spent_archetype = 0;
|
||||
eq->aa_spent_class = 0;
|
||||
@ -2846,58 +2846,81 @@ namespace RoF
|
||||
|
||||
ENCODE(OP_SendAATable)
|
||||
{
|
||||
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));
|
||||
EQApplicationPacket *inapp = *p;
|
||||
*p = nullptr;
|
||||
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||
|
||||
// Check clientver field to verify this AA should be sent for SoF
|
||||
// clientver 1 is for all clients and 5 is for Live
|
||||
if (emu->clientver <= 7)
|
||||
{
|
||||
OUT(id);
|
||||
eq->unknown004 = 1;
|
||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? -1 : (emu->sof_next_skill);
|
||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? -1 : (emu->sof_next_skill);
|
||||
eq->title_sid = emu->sof_next_skill;
|
||||
eq->desc_sid = emu->sof_next_skill;
|
||||
OUT(class_type);
|
||||
OUT(cost);
|
||||
OUT(seq);
|
||||
OUT(current_level);
|
||||
eq->prereq_skill_count = 1; // min 1
|
||||
OUT(prereq_skill);
|
||||
eq->prereq_minpoints_count = 1; // min 1
|
||||
OUT(prereq_minpoints);
|
||||
eq->type = emu->sof_type;
|
||||
OUT(spellid);
|
||||
eq->unknown057 = 1; // Introduced during HoT
|
||||
OUT(spell_type);
|
||||
OUT(spell_refresh);
|
||||
OUT(classes);
|
||||
OUT(berserker);
|
||||
//eq->max_level = emu->sof_max_level;
|
||||
OUT(max_level);
|
||||
OUT(last_id);
|
||||
OUT(next_id);
|
||||
OUT(cost2);
|
||||
eq->aa_expansion = emu->aa_expansion;
|
||||
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);
|
||||
unsigned int r;
|
||||
for (r = 0; r < emu->total_abilities; r++) {
|
||||
OUT(abilities[r].skill_id);
|
||||
OUT(abilities[r].base1);
|
||||
OUT(abilities[r].base2);
|
||||
OUT(abilities[r].slot);
|
||||
}
|
||||
// the structs::SendAA_Struct includes enough space for 1 prereq which is the min even if it has no prereqs
|
||||
auto prereq_size = emu->total_prereqs > 1 ? (emu->total_prereqs - 1) * 8 : 0;
|
||||
auto outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability) + prereq_size);
|
||||
inapp->SetReadPosition(sizeof(AARankInfo_Struct)+emu->total_effects * sizeof(AARankEffect_Struct));
|
||||
|
||||
|
||||
std::vector<int32> skill;
|
||||
std::vector<int32> points;
|
||||
for(auto i = 0; i < emu->total_prereqs; ++i) {
|
||||
skill.push_back(inapp->ReadUInt32());
|
||||
points.push_back(inapp->ReadUInt32());
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
outapp->WriteUInt32(emu->id);
|
||||
outapp->WriteUInt8(1);
|
||||
outapp->WriteSInt32(emu->upper_hotkey_sid);
|
||||
outapp->WriteSInt32(emu->lower_hotkey_sid);
|
||||
outapp->WriteSInt32(emu->title_sid);
|
||||
outapp->WriteSInt32(emu->desc_sid);
|
||||
outapp->WriteSInt32(emu->level_req);
|
||||
outapp->WriteSInt32(emu->cost);
|
||||
outapp->WriteUInt32(emu->seq);
|
||||
outapp->WriteUInt32(emu->current_level);
|
||||
|
||||
if(emu->total_prereqs) {
|
||||
outapp->WriteUInt32(emu->total_prereqs);
|
||||
for(auto &e : skill)
|
||||
outapp->WriteSInt32(e);
|
||||
outapp->WriteUInt32(emu->total_prereqs);
|
||||
for(auto &e : points)
|
||||
outapp->WriteSInt32(e);
|
||||
}
|
||||
else {
|
||||
outapp->WriteUInt32(1);
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(1);
|
||||
outapp->WriteUInt32(0);
|
||||
}
|
||||
|
||||
outapp->WriteSInt32(emu->type);
|
||||
outapp->WriteSInt32(emu->spell);
|
||||
outapp->WriteSInt32(1);
|
||||
outapp->WriteSInt32(emu->spell_type);
|
||||
outapp->WriteSInt32(emu->spell_refresh);
|
||||
outapp->WriteSInt32(emu->classes);
|
||||
outapp->WriteSInt32(emu->max_level);
|
||||
outapp->WriteSInt32(emu->prev_id);
|
||||
outapp->WriteSInt32(emu->next_id);
|
||||
outapp->WriteSInt32(emu->total_cost);
|
||||
outapp->WriteUInt8(0);
|
||||
outapp->WriteUInt8(emu->grant_only);
|
||||
outapp->WriteUInt8(0);
|
||||
outapp->WriteUInt32(emu->charges);
|
||||
outapp->WriteSInt32(emu->expansion);
|
||||
outapp->WriteSInt32(emu->category);
|
||||
outapp->WriteUInt8(0); // shroud
|
||||
outapp->WriteUInt8(0); // unknown109
|
||||
outapp->WriteUInt8(0); // loh
|
||||
outapp->WriteUInt8(0); // unknown111
|
||||
outapp->WriteUInt32(emu->total_effects);
|
||||
|
||||
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
|
||||
for(auto i = 0; i < emu->total_effects; ++i) {
|
||||
outapp->WriteUInt32(inapp->ReadUInt32()); // skill_id
|
||||
outapp->WriteUInt32(inapp->ReadUInt32()); // base1
|
||||
outapp->WriteUInt32(inapp->ReadUInt32()); // base2
|
||||
outapp->WriteUInt32(inapp->ReadUInt32()); // slot
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
}
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
|
||||
@ -2466,7 +2466,8 @@ namespace RoF2
|
||||
outapp->WriteUInt32(emu->lastlogin);
|
||||
outapp->WriteUInt32(emu->timePlayedMin);
|
||||
outapp->WriteUInt32(emu->timeentitledonaccount);
|
||||
outapp->WriteUInt32(0x0007ffff); // Expansion bitmask
|
||||
outapp->WriteUInt32(emu->expansions);
|
||||
//outapp->WriteUInt32(0x0007ffff); // Expansion bitmask
|
||||
|
||||
outapp->WriteUInt32(structs::MAX_PP_LANGUAGE);
|
||||
|
||||
@ -2899,7 +2900,7 @@ namespace RoF2
|
||||
|
||||
eq->aa_spent = emu->aa_spent;
|
||||
// These fields may need to be correctly populated at some point
|
||||
eq->aapoints_assigned = emu->aa_spent + 1;
|
||||
eq->aapoints_assigned = emu->aa_spent;
|
||||
eq->aa_spent_general = 0;
|
||||
eq->aa_spent_archetype = 0;
|
||||
eq->aa_spent_class = 0;
|
||||
@ -2935,58 +2936,80 @@ namespace RoF2
|
||||
|
||||
ENCODE(OP_SendAATable)
|
||||
{
|
||||
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));
|
||||
EQApplicationPacket *inapp = *p;
|
||||
*p = nullptr;
|
||||
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||
|
||||
// the structs::SendAA_Struct includes enough space for 1 prereq which is the min even if it has no prereqs
|
||||
auto prereq_size = emu->total_prereqs > 1 ? (emu->total_prereqs - 1) * 8 : 0;
|
||||
auto outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability) + prereq_size);
|
||||
inapp->SetReadPosition(sizeof(AARankInfo_Struct)+emu->total_effects * sizeof(AARankEffect_Struct));
|
||||
|
||||
|
||||
// Check clientver field to verify this AA should be sent for SoF
|
||||
// clientver 1 is for all clients and 5 is for Live
|
||||
if (emu->clientver <= 8)
|
||||
{
|
||||
OUT(id);
|
||||
eq->unknown004 = 1;
|
||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? -1 : (emu->sof_next_skill);
|
||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? -1 : (emu->sof_next_skill);
|
||||
eq->title_sid = emu->sof_next_skill;
|
||||
eq->desc_sid = emu->sof_next_skill;
|
||||
OUT(class_type);
|
||||
OUT(cost);
|
||||
OUT(seq);
|
||||
OUT(current_level);
|
||||
eq->prereq_skill_count = 1; // min 1
|
||||
OUT(prereq_skill);
|
||||
eq->prereq_minpoints_count = 1; // min 1
|
||||
OUT(prereq_minpoints);
|
||||
eq->type = emu->sof_type;
|
||||
OUT(spellid);
|
||||
eq->unknown057 = 1; // Introduced during HoT
|
||||
OUT(spell_type);
|
||||
OUT(spell_refresh);
|
||||
OUT(classes);
|
||||
OUT(berserker);
|
||||
//eq->max_level = emu->sof_max_level;
|
||||
OUT(max_level);
|
||||
OUT(last_id);
|
||||
OUT(next_id);
|
||||
OUT(cost2);
|
||||
eq->aa_expansion = emu->aa_expansion;
|
||||
eq->special_category = emu->special_category;
|
||||
OUT(total_abilities);
|
||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
||||
unsigned int r;
|
||||
for (r = 0; r < emu->total_abilities; r++) {
|
||||
OUT(abilities[r].skill_id);
|
||||
OUT(abilities[r].base1);
|
||||
OUT(abilities[r].base2);
|
||||
OUT(abilities[r].slot);
|
||||
}
|
||||
std::vector<int32> skill;
|
||||
std::vector<int32> points;
|
||||
for(auto i = 0; i < emu->total_prereqs; ++i) {
|
||||
skill.push_back(inapp->ReadUInt32());
|
||||
points.push_back(inapp->ReadUInt32());
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
outapp->WriteUInt32(emu->id);
|
||||
outapp->WriteUInt8(1);
|
||||
outapp->WriteSInt32(emu->upper_hotkey_sid);
|
||||
outapp->WriteSInt32(emu->lower_hotkey_sid);
|
||||
outapp->WriteSInt32(emu->title_sid);
|
||||
outapp->WriteSInt32(emu->desc_sid);
|
||||
outapp->WriteSInt32(emu->level_req);
|
||||
outapp->WriteSInt32(emu->cost);
|
||||
outapp->WriteUInt32(emu->seq);
|
||||
outapp->WriteUInt32(emu->current_level);
|
||||
|
||||
if (emu->total_prereqs) {
|
||||
outapp->WriteUInt32(emu->total_prereqs);
|
||||
for (auto &e : skill)
|
||||
outapp->WriteSInt32(e);
|
||||
outapp->WriteUInt32(emu->total_prereqs);
|
||||
for (auto &e : points)
|
||||
outapp->WriteSInt32(e);
|
||||
} else {
|
||||
outapp->WriteUInt32(1);
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(1);
|
||||
outapp->WriteUInt32(0);
|
||||
}
|
||||
|
||||
outapp->WriteSInt32(emu->type);
|
||||
outapp->WriteSInt32(emu->spell);
|
||||
outapp->WriteSInt32(1);
|
||||
outapp->WriteSInt32(emu->spell_type);
|
||||
outapp->WriteSInt32(emu->spell_refresh);
|
||||
outapp->WriteSInt32(emu->classes);
|
||||
outapp->WriteSInt32(emu->max_level);
|
||||
outapp->WriteSInt32(emu->prev_id);
|
||||
outapp->WriteSInt32(emu->next_id);
|
||||
outapp->WriteSInt32(emu->total_cost);
|
||||
outapp->WriteUInt8(0);
|
||||
outapp->WriteUInt8(emu->grant_only);
|
||||
outapp->WriteUInt8(0);
|
||||
outapp->WriteUInt32(emu->charges);
|
||||
outapp->WriteSInt32(emu->expansion);
|
||||
outapp->WriteSInt32(emu->category);
|
||||
outapp->WriteUInt8(0); // shroud
|
||||
outapp->WriteUInt8(0); // unknown109
|
||||
outapp->WriteUInt8(0); // loh
|
||||
outapp->WriteUInt8(0); // unknown111
|
||||
outapp->WriteUInt32(emu->total_effects);
|
||||
|
||||
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
|
||||
for(auto i = 0; i < emu->total_effects; ++i) {
|
||||
outapp->WriteUInt32(inapp->ReadUInt32()); // skill_id
|
||||
outapp->WriteUInt32(inapp->ReadUInt32()); // base1
|
||||
outapp->WriteUInt32(inapp->ReadUInt32()); // base2
|
||||
outapp->WriteUInt32(inapp->ReadUInt32()); // slot
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
}
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
|
||||
@ -4289,7 +4289,7 @@ struct AA_List {
|
||||
struct AA_Action {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint32 ability;
|
||||
/*08*/ uint32 unknown08;
|
||||
/*08*/ uint32 target_id;
|
||||
/*12*/ uint32 exp_value;
|
||||
/*16*/
|
||||
};
|
||||
|
||||
@ -4288,7 +4288,7 @@ struct AA_List {
|
||||
struct AA_Action {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint32 ability;
|
||||
/*08*/ uint32 unknown08;
|
||||
/*08*/ uint32 target_id;
|
||||
/*12*/ uint32 exp_value;
|
||||
/*16*/
|
||||
};
|
||||
|
||||
@ -1677,8 +1677,8 @@ namespace SoD
|
||||
OUT(copper_bank);
|
||||
OUT(platinum_shared);
|
||||
// OUT(unknown13156[84]);
|
||||
//OUT(expansions);
|
||||
eq->expansions = 16383;
|
||||
OUT(expansions);
|
||||
//eq->expansions = 16383;
|
||||
// OUT(unknown13244[12]);
|
||||
OUT(autosplit);
|
||||
// OUT(unknown13260[16]);
|
||||
@ -1862,55 +1862,56 @@ namespace SoD
|
||||
|
||||
ENCODE(OP_SendAATable)
|
||||
{
|
||||
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));
|
||||
EQApplicationPacket *inapp = *p;
|
||||
*p = nullptr;
|
||||
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||
|
||||
// Check clientver field to verify this AA should be sent for SoF
|
||||
// clientver 1 is for all clients and 5 is for SoD
|
||||
if (emu->clientver <= 5)
|
||||
{
|
||||
OUT(id);
|
||||
eq->unknown004 = 1;
|
||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
||||
eq->title_sid = emu->sof_next_skill;
|
||||
eq->desc_sid = emu->sof_next_skill;
|
||||
OUT(class_type);
|
||||
OUT(cost);
|
||||
OUT(seq);
|
||||
OUT(current_level);
|
||||
OUT(prereq_skill);
|
||||
OUT(prereq_minpoints);
|
||||
eq->type = emu->sof_type;
|
||||
OUT(spellid);
|
||||
OUT(spell_type);
|
||||
OUT(spell_refresh);
|
||||
OUT(classes);
|
||||
OUT(berserker);
|
||||
//eq->max_level = emu->sof_max_level;
|
||||
OUT(max_level);
|
||||
OUT(last_id);
|
||||
OUT(next_id);
|
||||
OUT(cost2);
|
||||
eq->aa_expansion = emu->aa_expansion;
|
||||
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);
|
||||
unsigned int r;
|
||||
for (r = 0; r < emu->total_abilities; r++) {
|
||||
OUT(abilities[r].skill_id);
|
||||
OUT(abilities[r].base1);
|
||||
OUT(abilities[r].base2);
|
||||
OUT(abilities[r].slot);
|
||||
}
|
||||
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;
|
||||
eq->expendable_charges = emu->charges;
|
||||
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();
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
if(emu->total_prereqs > 0) {
|
||||
eq->prereq_skill = inapp->ReadUInt32();
|
||||
eq->prereq_minpoints = inapp->ReadUInt32();
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
}
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
|
||||
@ -3813,8 +3813,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;
|
||||
@ -3840,7 +3839,7 @@ struct AA_List {
|
||||
struct AA_Action {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint32 ability;
|
||||
/*08*/ uint32 unknown08;
|
||||
/*08*/ uint32 target_id;
|
||||
/*12*/ uint32 exp_value;
|
||||
};
|
||||
|
||||
|
||||
@ -1335,8 +1335,8 @@ namespace SoF
|
||||
OUT(copper_bank);
|
||||
OUT(platinum_shared);
|
||||
// OUT(unknown13156[84]);
|
||||
//OUT(expansions);
|
||||
eq->expansions = 16383;
|
||||
OUT(expansions);
|
||||
//eq->expansions = 16383;
|
||||
// OUT(unknown13244[12]);
|
||||
OUT(autosplit);
|
||||
// OUT(unknown13260[16]);
|
||||
@ -1520,56 +1520,56 @@ namespace SoF
|
||||
|
||||
ENCODE(OP_SendAATable)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
|
||||
EQApplicationPacket *inapp = *p;
|
||||
*p = nullptr;
|
||||
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||
|
||||
SETUP_VAR_ENCODE(SendAA_Struct);
|
||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
|
||||
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;
|
||||
|
||||
// Check clientver field to verify this AA should be sent for SoF
|
||||
// clientver 1 is for all clients and 4 is for SoF
|
||||
if (emu->clientver <= 4)
|
||||
{
|
||||
OUT(id);
|
||||
eq->unknown004 = 1;
|
||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
||||
eq->title_sid = emu->sof_next_skill;
|
||||
eq->desc_sid = emu->sof_next_skill;
|
||||
OUT(class_type);
|
||||
OUT(cost);
|
||||
OUT(seq);
|
||||
OUT(current_level);
|
||||
OUT(prereq_skill);
|
||||
OUT(prereq_minpoints);
|
||||
eq->type = emu->sof_type;
|
||||
OUT(spellid);
|
||||
OUT(spell_type);
|
||||
OUT(spell_refresh);
|
||||
OUT(classes);
|
||||
OUT(berserker);
|
||||
//eq->max_level = emu->sof_max_level;
|
||||
OUT(max_level);
|
||||
OUT(last_id);
|
||||
OUT(next_id);
|
||||
OUT(cost2);
|
||||
eq->aa_expansion = emu->aa_expansion;
|
||||
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);
|
||||
unsigned int r;
|
||||
for (r = 0; r < emu->total_abilities; r++) {
|
||||
OUT(abilities[r].skill_id);
|
||||
OUT(abilities[r].base1);
|
||||
OUT(abilities[r].base2);
|
||||
OUT(abilities[r].slot);
|
||||
}
|
||||
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;
|
||||
eq->expendable_charges = emu->charges;
|
||||
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();
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
if(emu->total_prereqs > 0) {
|
||||
eq->prereq_skill = inapp->ReadUInt32();
|
||||
eq->prereq_minpoints = inapp->ReadUInt32();
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
}
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
@ -1665,8 +1665,6 @@ namespace SoF
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
//hack hack hack
|
||||
|
||||
@ -3677,8 +3677,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;
|
||||
@ -3702,7 +3701,7 @@ struct AA_List {
|
||||
struct AA_Action {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint32 ability;
|
||||
/*08*/ uint32 unknown08;
|
||||
/*08*/ uint32 target_id;
|
||||
/*12*/ uint32 exp_value;
|
||||
};
|
||||
|
||||
|
||||
@ -1107,50 +1107,52 @@ namespace Titanium
|
||||
|
||||
ENCODE(OP_SendAATable)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
|
||||
EQApplicationPacket *inapp = *p;
|
||||
*p = nullptr;
|
||||
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||
|
||||
SETUP_VAR_ENCODE(SendAA_Struct);
|
||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
|
||||
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;
|
||||
|
||||
// Check clientver field to verify this AA should be sent for Titanium
|
||||
// clientver 1 is for all clients and 3 is for Titanium
|
||||
if (emu->clientver <= 3)
|
||||
{
|
||||
OUT(id);
|
||||
eq->unknown004 = 1;
|
||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->id - emu->current_level + 1);
|
||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->id - emu->current_level + 1);
|
||||
eq->title_sid = emu->id - emu->current_level + 1;
|
||||
eq->desc_sid = emu->id - emu->current_level + 1;
|
||||
OUT(class_type);
|
||||
OUT(cost);
|
||||
OUT(seq);
|
||||
OUT(current_level);
|
||||
OUT(prereq_skill);
|
||||
OUT(prereq_minpoints);
|
||||
OUT(type);
|
||||
OUT(spellid);
|
||||
OUT(spell_type);
|
||||
OUT(spell_refresh);
|
||||
OUT(classes);
|
||||
OUT(berserker);
|
||||
OUT(max_level);
|
||||
OUT(last_id);
|
||||
OUT(next_id);
|
||||
OUT(cost2);
|
||||
OUT(unknown80[0]);
|
||||
OUT(unknown80[1]);
|
||||
OUT(total_abilities);
|
||||
unsigned int r;
|
||||
for (r = 0; r < emu->total_abilities; r++) {
|
||||
OUT(abilities[r].skill_id);
|
||||
OUT(abilities[r].base1);
|
||||
OUT(abilities[r].base2);
|
||||
OUT(abilities[r].slot);
|
||||
}
|
||||
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->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();
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
if(emu->total_prereqs > 0) {
|
||||
eq->prereq_skill = inapp->ReadUInt32();
|
||||
eq->prereq_minpoints = inapp->ReadUInt32();
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
}
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
|
||||
@ -3157,8 +3157,7 @@ struct SendAA_Struct {
|
||||
/*0052*/ uint32 spellid;
|
||||
/*0056*/ uint32 spell_type;
|
||||
/*0060*/ uint32 spell_refresh;
|
||||
/*0064*/ uint16 classes;
|
||||
/*0066*/ uint16 berserker; //seems to be 1 if its a berserker ability
|
||||
/*0064*/ uint32 classes;
|
||||
/*0068*/ uint32 max_level;
|
||||
/*0072*/ uint32 last_id;
|
||||
/*0076*/ uint32 next_id;
|
||||
@ -3175,7 +3174,7 @@ struct AA_List {
|
||||
struct AA_Action {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint32 ability;
|
||||
/*08*/ uint32 unknown08;
|
||||
/*08*/ uint32 target_id;
|
||||
/*12*/ uint32 exp_value;
|
||||
};
|
||||
|
||||
|
||||
@ -1805,11 +1805,13 @@ namespace UF
|
||||
//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);
|
||||
eq->aa_array[r].AA = emu->aa_array[r].AA;
|
||||
eq->aa_array[r].value = emu->aa_array[r].value;
|
||||
eq->aa_array[r].charges = emu->aa_array[r].charges;
|
||||
}
|
||||
|
||||
// OUT(unknown02220[4]);
|
||||
|
||||
OUT(mana);
|
||||
OUT(cur_hp);
|
||||
OUT(STR);
|
||||
@ -1939,8 +1941,8 @@ namespace UF
|
||||
OUT(copper_bank);
|
||||
OUT(platinum_shared);
|
||||
// OUT(unknown13156[84]);
|
||||
//OUT(expansions);
|
||||
eq->expansions = 0xffff;
|
||||
OUT(expansions);
|
||||
//eq->expansions = 0x1ffff;
|
||||
// OUT(unknown13244[12]);
|
||||
OUT(autosplit);
|
||||
// OUT(unknown13260[16]);
|
||||
@ -2128,7 +2130,7 @@ namespace UF
|
||||
|
||||
eq->aa_spent = emu->aa_spent;
|
||||
eq->aa_assigned = emu->aa_spent;
|
||||
eq->aa_spent3 = emu->aa_spent;
|
||||
eq->aa_spent3 = 0;
|
||||
eq->unknown012 = 0;
|
||||
eq->unknown016 = 0;
|
||||
eq->unknown020 = 0;
|
||||
@ -2145,55 +2147,56 @@ namespace UF
|
||||
|
||||
ENCODE(OP_SendAATable)
|
||||
{
|
||||
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));
|
||||
EQApplicationPacket *inapp = *p;
|
||||
*p = nullptr;
|
||||
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||
|
||||
// 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)
|
||||
{
|
||||
OUT(id);
|
||||
eq->unknown004 = 1;
|
||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
||||
eq->title_sid = emu->sof_next_skill;
|
||||
eq->desc_sid = emu->sof_next_skill;
|
||||
OUT(class_type);
|
||||
OUT(cost);
|
||||
OUT(seq);
|
||||
OUT(current_level);
|
||||
OUT(prereq_skill);
|
||||
OUT(prereq_minpoints);
|
||||
eq->type = emu->sof_type;
|
||||
OUT(spellid);
|
||||
OUT(spell_type);
|
||||
OUT(spell_refresh);
|
||||
OUT(classes);
|
||||
OUT(berserker);
|
||||
//eq->max_level = emu->sof_max_level;
|
||||
OUT(max_level);
|
||||
OUT(last_id);
|
||||
OUT(next_id);
|
||||
OUT(cost2);
|
||||
eq->aa_expansion = emu->aa_expansion;
|
||||
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);
|
||||
unsigned int r;
|
||||
for (r = 0; r < emu->total_abilities; r++) {
|
||||
OUT(abilities[r].skill_id);
|
||||
OUT(abilities[r].base1);
|
||||
OUT(abilities[r].base2);
|
||||
OUT(abilities[r].slot);
|
||||
}
|
||||
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;
|
||||
eq->expendable_charges = emu->charges;
|
||||
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();
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
if(emu->total_prereqs > 0) {
|
||||
eq->prereq_skill = inapp->ReadUInt32();
|
||||
eq->prereq_minpoints = inapp->ReadUInt32();
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -3913,7 +3912,7 @@ struct AA_List {
|
||||
struct AA_Action {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint32 ability;
|
||||
/*08*/ uint32 unknown08;
|
||||
/*08*/ uint32 target_id;
|
||||
/*12*/ uint32 exp_value;
|
||||
};
|
||||
|
||||
|
||||
@ -139,8 +139,4 @@ protected:
|
||||
std::map<pTimerType, PersistentTimer *> _list;
|
||||
};
|
||||
|
||||
//code prettying macros
|
||||
#define AA_Choose3(val, v1, v2, v3) (val==1?v1:(val==2?v2:v3))
|
||||
#define AA_Choose5(val, v1, v2, v3, v4, v5) (val==1?v1:(val==2?v2:(val==3?v3:(val==4?v4:v5))))
|
||||
|
||||
#endif
|
||||
|
||||
@ -99,6 +99,7 @@ RULE_BOOL(Character, EnableXTargetting, true) // Enable Extended Targetting Wind
|
||||
RULE_BOOL(Character, KeepLevelOverMax, false) // Don't delevel a character that has somehow gone over the level cap
|
||||
RULE_INT(Character, FoodLossPerUpdate, 35) // How much food/water you lose per stamina update
|
||||
RULE_INT(Character, BaseInstrumentSoftCap, 36) // Softcap for instrument mods, 36 commonly referred to as "3.6" as well.
|
||||
RULE_BOOL(Character, UseSpellFileSongCap, true) // When they removed the AA that increased the cap they removed the above and just use the spell field
|
||||
RULE_INT(Character, BaseRunSpeedCap, 158) // Base Run Speed Cap, on live it's 158% which will give you a runspeed of 1.580 hard capped to 225.
|
||||
RULE_INT(Character, OrnamentationAugmentType, 20) //Ornamentation Augment Type
|
||||
RULE_REAL(Character, EnvironmentDamageMulipliter, 1)
|
||||
@ -185,6 +186,7 @@ RULE_INT(World, MinGMAntiHackStatus, 1) //Minimum GM status to check against Ant
|
||||
RULE_INT(World, SoFStartZoneID, -1) //Sets the Starting Zone for SoF Clients separate from Titanium Clients (-1 is disabled)
|
||||
RULE_INT(World, TitaniumStartZoneID, -1) //Sets the Starting Zone for Titanium Clients (-1 is disabled). Replaces the old method.
|
||||
RULE_INT(World, ExpansionSettings, 16383) // Sets the expansion settings for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS.
|
||||
RULE_BOOL(World, UseClientBasedExpansionSettings, true) // if true it will overrule World, ExpansionSettings and set someone's expansion based on the client they're using
|
||||
RULE_INT(World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = Rallos Zek RuleSet, 2 = Tallon/Vallon Zek Ruleset, 4 = Sullon Zek Ruleset, 6 = Discord Ruleset, anything above 6 is the Discord Ruleset without the no-drop restrictions removed. TODO: Edit IsAttackAllowed in Zone to accomodate for these rules.
|
||||
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
|
||||
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
|
||||
|
||||
@ -1682,6 +1682,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
||||
sp[tempid].not_extendable = atoi(row[197]) != 0;
|
||||
sp[tempid].suspendable = atoi(row[200]) != 0;
|
||||
sp[tempid].viral_range = atoi(row[201]);
|
||||
sp[tempid].songcap = atoi(row[202]);
|
||||
sp[tempid].no_block = atoi(row[205]);
|
||||
sp[tempid].spellgroup=atoi(row[207]);
|
||||
sp[tempid].rank = atoi(row[208]);
|
||||
@ -2021,7 +2022,7 @@ const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
|
||||
|
||||
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
|
||||
std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = QueryDatabase(query);
|
||||
auto row = results.begin();
|
||||
memset(message, '\0', sizeof(InspectMessage_Struct));
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
@ -2031,7 +2032,7 @@ void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMes
|
||||
|
||||
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) {
|
||||
std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, EscapeString(message->text).c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = QueryDatabase(query);
|
||||
}
|
||||
|
||||
void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) {
|
||||
|
||||
@ -381,47 +381,47 @@ typedef enum {
|
||||
#define SE_GiveDoubleAttack 225 // implemented[AA] - Allow any class to double attack with set chance.
|
||||
#define SE_TwoHandBash 226 // *not implemented as bonus
|
||||
#define SE_ReduceSkillTimer 227 // implemented
|
||||
//#define SE_ReduceFallDamage 228 // not implented as bonus - reduce the damage that you take from falling
|
||||
#define SE_ReduceFallDamage 228 // not implented as bonus - reduce the damage that you take from falling
|
||||
#define SE_PersistantCasting 229 // implemented
|
||||
//#define SE_ExtendedShielding 230 // not used as bonus - increase range of /shield ability
|
||||
#define SE_ExtendedShielding 230 // not used as bonus - increase range of /shield ability
|
||||
#define SE_StunBashChance 231 // implemented - increase chance to stun from bash.
|
||||
#define SE_DivineSave 232 // implemented (base1 == % chance on death to insta-res) (base2 == spell cast on save)
|
||||
#define SE_Metabolism 233 // implemented - Modifies food/drink consumption rates.
|
||||
//#define SE_ReduceApplyPoisonTime 234 // not implemented as bonus - reduces the time to apply poison
|
||||
#define SE_ReduceApplyPoisonTime 234 // not implemented as bonus - reduces the time to apply poison
|
||||
#define SE_ChannelChanceSpells 235 // implemented[AA] - chance to channel from SPELLS *No longer used on live.
|
||||
//#define SE_FreePet 236 // not used
|
||||
#define SE_GivePetGroupTarget 237 // implemented[AA] - (Pet Affinity)
|
||||
#define SE_IllusionPersistence 238 // implemented - lends persistence to your illusionary disguises, causing them to last until you die or the illusion is forcibly removed.
|
||||
//#define SE_FeignedCastOnChance 239 // *not implemented as bonus - ability gives you an increasing chance for your feigned deaths to not be revealed by spells cast upon you.
|
||||
#define SE_FeignedCastOnChance 239 // *not implemented as bonus - ability gives you an increasing chance for your feigned deaths to not be revealed by spells cast upon you.
|
||||
//#define SE_StringUnbreakable 240 // not used [Likely related to above - you become immune to feign breaking on a resisted spell and have a good chance of feigning through a spell that successfully lands upon you.]
|
||||
#define SE_ImprovedReclaimEnergy 241 // implemented - increase the amount of mana returned to you when reclaiming your pet.
|
||||
#define SE_IncreaseChanceMemwipe 242 // implemented - increases the chance to wipe hate with memory blurr
|
||||
#define SE_CharmBreakChance 243 // implemented - Total Domination
|
||||
#define SE_RootBreakChance 244 // implemented[AA] reduce the chance that your root will break.
|
||||
//#define SE_TrapCircumvention 245 // *not implemented[AA] - decreases the chance that you will set off a trap when opening a chest
|
||||
#define SE_TrapCircumvention 245 // *not implemented[AA] - decreases the chance that you will set off a trap when opening a chest
|
||||
#define SE_SetBreathLevel 246 // *not implemented as bonus
|
||||
#define SE_RaiseSkillCap 247 // *not implemented[AA] - adds skill over the skill cap.
|
||||
//#define SE_SecondaryForte 248 // not implemented as bonus(gives you a 2nd specialize skill that can go past 50 to 100)
|
||||
#define SE_SecondaryForte 248 // not implemented as bonus(gives you a 2nd specialize skill that can go past 50 to 100)
|
||||
#define SE_SecondaryDmgInc 249 // implemented[AA] Allows off hand weapon to recieve a damage bonus (Sinister Strikes)
|
||||
#define SE_SpellProcChance 250 // implemented - Increase chance to proc from melee proc spells (ie Spirit of Panther)
|
||||
#define SE_ConsumeProjectile 251 // implemented[AA] - chance to not consume an arrow (ConsumeProjectile = 100)
|
||||
#define SE_FrontalBackstabChance 252 // implemented[AA] - chance to perform a full damage backstab from front.
|
||||
#define SE_FrontalBackstabMinDmg 253 // implemented[AA] - allow a frontal backstab for mininum damage.
|
||||
#define SE_Blank 254 // implemented
|
||||
//#define SE_ShieldDuration 255 // not implemented as bonus - increases duration of /shield
|
||||
//#define SE_ShroudofStealth 256 // not implemented as bonus - rogue improved invs
|
||||
//#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold
|
||||
#define SE_ShieldDuration 255 // not implemented as bonus - increases duration of /shield
|
||||
#define SE_ShroudofStealth 256 // not implemented as bonus - rogue improved invs
|
||||
#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold
|
||||
#define SE_TripleBackstab 258 // implemented[AA] - chance to perform a triple backstab
|
||||
#define SE_CombatStability 259 // implemented[AA] - damage mitigation
|
||||
#define SE_AddSingingMod 260 // implemented[AA] - Instrument/Singing Mastery, base1 is the mod, base2 is the ItemType
|
||||
#define SE_SongModCap 261 // implemented[AA] - Song Mod cap increase (no longer used on live)
|
||||
#define SE_RaiseStatCap 262 // implemented
|
||||
//#define SE_TradeSkillMastery 263 // not implemented - lets you raise more than one tradeskill above master.
|
||||
//#define SE_HastenedAASkill 264 // not implemented as bonus - Use redux field in aa_actions table for this effect
|
||||
#define SE_TradeSkillMastery 263 // not implemented - lets you raise more than one tradeskill above master.
|
||||
#define SE_HastenedAASkill 264 // implemented
|
||||
#define SE_MasteryofPast 265 // implemented[AA] - Spells less than effect values level can not be fizzled
|
||||
#define SE_ExtraAttackChance 266 // implemented - increase chance to score an extra attack with a 2-Handed Weapon.
|
||||
#define SE_PetDiscipline2 267 // *not implemented - /pet focus, /pet no cast
|
||||
//#define SE_ReduceTradeskillFail 268 // *not implemented? - reduces chance to fail with given tradeskill by a percent chance
|
||||
#define SE_ReduceTradeskillFail 268 // *not implemented? - reduces chance to fail with given tradeskill by a percent chance
|
||||
#define SE_MaxBindWound 269 // implemented[AA] - Increase max HP you can bind wound.
|
||||
#define SE_BardSongRange 270 // implemented[AA] - increase range of beneficial bard songs (Sionachie's Crescendo)
|
||||
#define SE_BaseMovementSpeed 271 // implemented[AA] - mods basemove speed, doesn't stack with other move mods
|
||||
@ -434,14 +434,14 @@ typedef enum {
|
||||
#define SE_FinishingBlow 278 // implemented[AA] - chance to do massive damage under 10% HP (base1 = chance, base2 = damage)
|
||||
#define SE_Flurry 279 // implemented
|
||||
#define SE_PetFlurry 280 // implemented[AA]
|
||||
//#define SE_FeignedMinion 281 // *not implemented[AA] ability allows you to instruct your pet to feign death via the '/pet feign' command. value = succeed chance
|
||||
#define SE_FeignedMinion 281 // *not implemented[AA] ability allows you to instruct your pet to feign death via the '/pet feign' command. value = succeed chance
|
||||
#define SE_ImprovedBindWound 282 // implemented[AA] - increase bind wound amount by percent.
|
||||
#define SE_DoubleSpecialAttack 283 // implemented[AA] - Chance to perform second special attack as monk
|
||||
//#define SE_LoHSetHeal 284 // not used
|
||||
//#define SE_NimbleEvasion 285 // *not implemented - base1 = 100 for max
|
||||
#define SE_NimbleEvasion 285 // *not implemented - base1 = 100 for max
|
||||
#define SE_FcDamageAmt 286 // implemented - adds direct spell damage
|
||||
#define SE_SpellDurationIncByTic 287 // implemented
|
||||
#define SE_SpecialAttackKBProc 288 // implemented[AA] - Chance to to do a knockback from special attacks [AA Dragon Punch].
|
||||
#define SE_SkillAttackProc 288 // implemented[AA] - Chance to proc spell on skill attack usage (ex. Dragon Punch)
|
||||
#define SE_CastOnFadeEffect 289 // implemented - Triggers only if fades after natural duration.
|
||||
#define SE_IncreaseRunSpeedCap 290 // implemented[AA] - increases run speed over the hard cap
|
||||
#define SE_Purify 291 // implemented - Removes determental effects
|
||||
@ -515,8 +515,8 @@ typedef enum {
|
||||
//#define SE_PassiveSenseTrap 359 // *not implemented - Invulnerability (Brell's Blessing)
|
||||
#define SE_ProcOnKillShot 360 // implemented - a buff that has a base1 % to cast spell base2 when you kill a "challenging foe" base3 min level
|
||||
#define SE_SpellOnDeath 361 // implemented - casts spell on death of buffed
|
||||
//#define SE_PotionBeltSlots 362 // *not implemented[AA] 'Quick Draw' expands the potion belt by one additional available item slot per rank.
|
||||
//#define SE_BandolierSlots 363 // *not implemented[AA] 'Battle Ready' expands the bandolier by one additional save slot per rank.
|
||||
#define SE_PotionBeltSlots 362 // *not implemented[AA] 'Quick Draw' expands the potion belt by one additional available item slot per rank.
|
||||
#define SE_BandolierSlots 363 // *not implemented[AA] 'Battle Ready' expands the bandolier by one additional save slot per rank.
|
||||
#define SE_TripleAttackChance 364 // implemented
|
||||
#define SE_ProcOnSpellKillShot 365 // implemented - chance to trigger a spell on kill when the kill is caused by a specific spell with this effect in it (10470 Venin)
|
||||
#define SE_ShieldEquipDmgMod 366 // implemented[AA] Damage modifier to melee if shield equiped. (base1 = dmg mod , base2 = ?) ie Shield Specialist AA
|
||||
@ -525,7 +525,7 @@ typedef enum {
|
||||
#define SE_CorruptionCounter 369 // implemented
|
||||
#define SE_ResistCorruption 370 // implemented
|
||||
#define SE_AttackSpeed4 371 // implemented - stackable slow effect 'Inhibit Melee'
|
||||
//#define SE_ForageSkill 372 // *not implemented[AA] Will increase the skill cap for those that have the Forage skill and grant the skill and raise the cap to those that do not.
|
||||
#define SE_ForageSkill 372 // *not implemented[AA] Will increase the skill cap for those that have the Forage skill and grant the skill and raise the cap to those that do not.
|
||||
#define SE_CastOnFadeEffectAlways 373 // implemented - Triggers if fades after natural duration OR from rune/numhits fades.
|
||||
#define SE_ApplyEffect 374 // implemented
|
||||
#define SE_DotCritDmgIncrease 375 // implemented - Increase damage of DoT critical amount
|
||||
@ -544,7 +544,7 @@ typedef enum {
|
||||
//#define SE_SummonCorpseZone 388 // *not implemented - summons a corpse from any zone(nec AA)
|
||||
#define SE_FcTimerRefresh 389 // implemented - Refresh spell icons
|
||||
//#define SE_FcTimerLockout 390 // *not implemented - Sets recast timers to specific value, focus limited.
|
||||
#define SE_MeleeVulnerability 391 // implemented [Live SPA has this as LimitManaMax however that is clearly not the effect used]
|
||||
#define SE_LimitManaMax 391 // implemented
|
||||
#define SE_FcHealAmt 392 // implemented - Adds or removes healing from spells
|
||||
#define SE_FcHealPctIncoming 393 // implemented - HealRate with focus restrictions.
|
||||
#define SE_FcHealAmtIncoming 394 // implemented - Adds/Removes amount of healing on target by X value with foucs restrictions.
|
||||
@ -579,7 +579,7 @@ typedef enum {
|
||||
#define SE_LimitUseType 423 // implemented - limit a focus to require a certain numhits type
|
||||
#define SE_GravityEffect 424 // implemented - Pulls/pushes you toward/away the mob at a set pace
|
||||
//#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
|
||||
//#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
|
||||
#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
|
||||
#define SE_SkillProc 427 // implemented - chance to proc when using a skill(ie taunt)
|
||||
#define SE_LimitToSkill 428 // implemented - limits what skills will effect a skill proc
|
||||
#define SE_SkillProcSuccess 429 // implemented - chance to proc when tje skill in use successfully fires.
|
||||
@ -735,8 +735,8 @@ struct SPDat_Spell_Struct
|
||||
/* 198- 199 */
|
||||
/* 200 */ bool suspendable; // buff is suspended in suspended buff zones
|
||||
/* 201 */ int viral_range;
|
||||
/* 202 */
|
||||
/* 203 */ //int songcap; // individual song cap (how live currently does it, not implemented)
|
||||
/* 202 */ int songcap; // individual song cap
|
||||
/* 203 */
|
||||
/* 204 */
|
||||
/* 205 */ bool no_block;
|
||||
/* 206 */
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9085
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9086
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
#ifndef WIN32
|
||||
|
||||
@ -353,6 +353,7 @@ OP_OpenContainer=0x0000
|
||||
OP_Marquee=0x502e
|
||||
OP_ItemRecastDelay=0x15a9
|
||||
#OP_OpenInventory=0x0000 # Likely does not exist in RoF -U
|
||||
OP_ResetAA=0x1669
|
||||
|
||||
# Expeditions
|
||||
OP_DzAddPlayer=0x4701
|
||||
|
||||
@ -339,7 +339,7 @@
|
||||
9083|2015_06_07_aa_update.sql|SHOW COLUMNS FROM `character_alternate_abilities` LIKE 'charges'|empty|
|
||||
9084|2015_06_30_runspeed_adjustments.sql|SELECT `runspeed` FROM `npc_types` WHERE `runspeed` > 3|not_empty|
|
||||
9085|2015_7_1_Marquee_Rule.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Character:MarqueeHPUpdates%'|empty|
|
||||
|
||||
9086|2015_07_02_aa_rework.sql|SHOW TABLES LIKE 'aa_ranks'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
20679
utils/sql/git/required/2015_07_02_aa_rework.sql
Normal file
20679
utils/sql/git/required/2015_07_02_aa_rework.sql
Normal file
File diff suppressed because it is too large
Load Diff
@ -152,7 +152,13 @@ void Client::SendEnterWorld(std::string name)
|
||||
void Client::SendExpansionInfo() {
|
||||
auto outapp = new EQApplicationPacket(OP_ExpansionInfo, sizeof(ExpansionInfo_Struct));
|
||||
ExpansionInfo_Struct *eis = (ExpansionInfo_Struct*)outapp->pBuffer;
|
||||
eis->Expansions = (RuleI(World, ExpansionSettings));
|
||||
if(RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
eis->Expansions = ExpansionFromClientVersion(eqs->GetClientVersion());
|
||||
//eis->Expansions = ExpansionFromClientVersion(this->GetCLE.
|
||||
} else {
|
||||
eis->Expansions = (RuleI(World, ExpansionSettings));
|
||||
}
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(zone_sources
|
||||
aa.cpp
|
||||
aa_ability.cpp
|
||||
aggro.cpp
|
||||
attack.cpp
|
||||
beacon.cpp
|
||||
@ -126,6 +127,7 @@ SET(zone_sources
|
||||
|
||||
SET(zone_headers
|
||||
aa.h
|
||||
aa_ability.h
|
||||
basic_functions.h
|
||||
beacon.h
|
||||
bot.h
|
||||
|
||||
2282
zone/aa.cpp
2282
zone/aa.cpp
File diff suppressed because it is too large
Load Diff
638
zone/aa.h
638
zone/aa.h
@ -1,27 +1,8 @@
|
||||
|
||||
#ifndef AA_H
|
||||
#define AA_H
|
||||
|
||||
struct AA_Ability;
|
||||
struct SendAA_Struct;
|
||||
|
||||
|
||||
#define MANA_BURN 664
|
||||
|
||||
#include <map>
|
||||
|
||||
#define MAX_SWARM_PETS 12 //this can change as long as you make more coords (swarm_pet_x/swarm_pet_y)
|
||||
|
||||
//this might be missing some, and some might not be used...
|
||||
typedef enum { //AA Targeting Constants
|
||||
aaTargetUser = 1,
|
||||
aaTargetCurrent = 2, //use current target
|
||||
aaTargetGroup = 3, //target group of user
|
||||
aaTargetCurrentGroup = 4, //target group of current target
|
||||
aaTargetPet = 5 //target the user's pet
|
||||
} aaTargetType;
|
||||
|
||||
|
||||
typedef enum {
|
||||
aaActionNone = 0,
|
||||
aaActionAETaunt = 1,
|
||||
@ -42,21 +23,6 @@ typedef enum {
|
||||
aaActionFadingMemories = 16
|
||||
} aaNonspellAction;
|
||||
|
||||
//use these for AAs which dont cast spells, yet need effects
|
||||
//if this list grows beyond 32, more work is needed in *AAEffect
|
||||
typedef enum { //AA Effect IDs
|
||||
aaEffectMassGroupBuff = 1, //unused - Handled via spell effect.
|
||||
aaEffectRampage,
|
||||
aaEffectSharedHealth,
|
||||
aaEffectFlamingArrows,
|
||||
aaEffectFrostArrows,
|
||||
aaEffectWarcry,
|
||||
aaEffectLeechTouch,
|
||||
aaEffectProjectIllusion, // unused - Handled via spell effect
|
||||
_maxaaEffectType = 32
|
||||
} aaEffectType;
|
||||
|
||||
|
||||
enum { //leadership AA indexes
|
||||
groupAAMarkNPC = 0,
|
||||
groupAANPCHealth,
|
||||
@ -133,571 +99,6 @@ static const uint8 LeadershipAACosts[_maxLeaderAA][MAX_LEADERSHIP_TIERS] = {
|
||||
{ 0, 0, 0, 0, 0, 0 }, //raidAA15
|
||||
};
|
||||
|
||||
/*
|
||||
typedef enum { //AA IDs
|
||||
aaNone = 0,
|
||||
aaInnateStrength = 2, //works
|
||||
aaInnateStamina = 7, //works
|
||||
aaInnateAgility = 12, //works
|
||||
//aaCompleteHeal = 13,/ //not implemented, but is in dbstr_us.txt
|
||||
aaInnateDexterity = 17, //works
|
||||
aaInnateIntelligence = 22, //works
|
||||
aaInnateWisdom = 27, //works
|
||||
aaInnateCharisma = 32, //works
|
||||
aaInnateFireProtection = 37, //works
|
||||
aaInnateColdProtection = 42, //works
|
||||
aaInnateMagicProtection = 47, //works
|
||||
aaInnatePoisonProtection = 52, //works
|
||||
aaInnateDiseaseProtection = 57, //works
|
||||
aaInnateRunSpeed = 62, //works
|
||||
aaInnateRegeneration = 65, //works
|
||||
aaInnateMetabolism = 68,
|
||||
aaInnateLungCapacity = 71, //handled by client
|
||||
aaFirstAid = 74, //untested
|
||||
aaHealingAdept = 77, //untested
|
||||
aaHealingGift = 80, //untested
|
||||
aaSpellCastingMastery = 83, //untested
|
||||
aaSpellCastingReinforcement = 86, //untested
|
||||
aaMentalClarity = 89,
|
||||
aaSpellCastingFury = 92, //untested
|
||||
aaChanellingFocus = 95,
|
||||
aaSpellCastingSubtlety = 98, //untested
|
||||
aaSpellCastingExpertise = 101, //untested
|
||||
aaSpellCastingDeftness = 104, //untested
|
||||
aaNaturalDurability = 107, //works
|
||||
aaNaturalHealing = 110, //untested
|
||||
aaCombatFury = 113, //untested
|
||||
aaFearResistance = 116, //untested
|
||||
aaFinishingBlow = 119, //untested
|
||||
aaCombatStability = 122,
|
||||
aaCombatAgility = 125,
|
||||
aaMassGroupBuff = 128, //untested
|
||||
aaDivineResurrection = 129, //DB
|
||||
aaInnateInvisToUndead = 130, //DB
|
||||
aaCelestialRegeneration = 131, //untested
|
||||
aaBestowDivineAura = 132, //DB
|
||||
aaTurnUndead = 133, //DB
|
||||
aaPurifySoul = 136, //DB
|
||||
aaQuickEvacuation = 137, //untested
|
||||
aaExodus = 140, //untested
|
||||
aaQuickDamage = 141, //untested
|
||||
aaEnhancedRoot = 144,
|
||||
aaDireCharm = 145, //untested
|
||||
aaCannibalization = 146, //DB
|
||||
aaQuickBuff = 147, //untested
|
||||
aaAlchemyMastery = 150,
|
||||
aaRabidBear = 153, //DB
|
||||
aaManaBurn = 154, //DB
|
||||
aaImprovedFamiliar = 155, //untested, implemented?
|
||||
aaNexusGate = 156, //DB
|
||||
aaUnknown54 = 157,
|
||||
aaPermanentIllusion = 158,
|
||||
aaJewelCraftMastery = 159,
|
||||
aaGatherMana = 162, //DB
|
||||
aaMendCompanion = 163, //DB
|
||||
aaQuickSummoning = 164, //untested
|
||||
aaFrenziedBurnout = 167, //DB
|
||||
aaElementalFormFire = 168, //DB
|
||||
aaElementalFormWater = 171, //DB
|
||||
aaElementalFormEarth = 174, //DB
|
||||
aaElementalFormAir = 177, //DB
|
||||
aaImprovedReclaimEnergy = 180, //untested
|
||||
aaTurnSummoned = 181, //DB
|
||||
aaElementalPact = 182, //DB
|
||||
aaLifeBurn = 183, //DB
|
||||
aaDeadMesmerization = 184, //DB
|
||||
aaFearstorm = 185, //DB
|
||||
aaFleshToBone = 186, //DB
|
||||
aaCallToCorpse = 187, //DB
|
||||
aaDivineStun = 188, //DB
|
||||
aaImprovedLayOnHands = 189,
|
||||
aaSlayUndead = 190,
|
||||
aaActOfValor = 193, //DB
|
||||
aaHolySteed = 194, //DB
|
||||
aaFearless = 195,
|
||||
aa2HandBash = 196, //works. handled by client?
|
||||
aaInnateCamouflage = 197, //DB
|
||||
aaAmbidexterity = 198, //untested
|
||||
aaArcheryMastery = 199, //untested
|
||||
aaFletchingMastery = 202, //removed from db?
|
||||
aaEndlessQuiver = 205, //untested
|
||||
aaUnholySteed = 206, //DB
|
||||
aaImprovedHarmTouch = 207, //untested
|
||||
aaLeechTouch = 208, //DB
|
||||
aaDeathPeace = 209,
|
||||
aaSoulAbrasion = 210, //untested
|
||||
aaInstrumentMastery = 213, //untested
|
||||
aaUnknown91 = 216, //not used
|
||||
aaUnknown92 = 219, //not used
|
||||
aaUnknown93 = 222, //not used
|
||||
aaJamFest = 225,
|
||||
aaUnknown95 = 228,
|
||||
aaSonicCall = 229,
|
||||
aaCriticalMend = 230, //untested
|
||||
aaPurifyBody = 233, //DB
|
||||
aaChainCombo = 234,
|
||||
aaRapidFeign = 237, //works
|
||||
aaReturnKick = 240,
|
||||
aaEscape = 243, //DB
|
||||
aaPoisonMastery = 244,
|
||||
aaDoubleRiposte = 247, //untested
|
||||
aaQuickHide = 250,
|
||||
aaQuickThrow = 253, //corrected from dbstr_us.txt
|
||||
aaPurgePoison = 254, //DB
|
||||
aaFlurry = 255, //untested
|
||||
aaRampage = 258, //untested
|
||||
aaAreaTaunt = 259, //untested
|
||||
aaWarcry = 260, //DB
|
||||
aaBandageWound = 263, //untested
|
||||
aaSpellCastingReinforcementMastery = 266, //untested
|
||||
aaSpellCastingFuryMastery = 267, //untested
|
||||
aaExtendedNotes = 270, //untested
|
||||
aaDragonPunch = 273,
|
||||
aaStrongRoot = 274, //DB
|
||||
aaSingingMastery = 275, //untested
|
||||
aaBodyAndMindRejuvenation = 278, //added
|
||||
aaPhysicalEnhancement = 279, //untested
|
||||
aaAdvTrapNegotiation = 280, //untested
|
||||
aaAcrobatics = 283, //untested
|
||||
aaScribbleNotes = 286,
|
||||
aaChaoticStab = 287, //untested
|
||||
aaPetDiscipline = 288, //added
|
||||
aaHobbleofSpirits = 289, //DB
|
||||
aaFrenzyofSpirit = 290, //DB
|
||||
aaParagonofSpirit = 291, //DB
|
||||
aaAdvancedInnateStrength = 292, //works
|
||||
aaAdvancedInnateStamina = 302, //works
|
||||
aaAdvancedInnateAgility = 312, //works
|
||||
aaAdvancedInnateDexterity = 322, //works
|
||||
aaAdvancedInnateIntelligence = 332, //works
|
||||
aaAdvancedInnateWisdom = 342, //works
|
||||
aaAdvancedInnateCharisma = 352, //works
|
||||
aaWardingofSolusek = 362, //works
|
||||
aaBlessingofEci = 372, //works
|
||||
aaMarrsProtection = 382, //works
|
||||
aaShroudofTheFaceless = 392, //works
|
||||
aaBertoxxulousGift = 402, //works
|
||||
aaNewTanaanCraftingMastery = 412,
|
||||
aaPlanarPower = 418, //untested
|
||||
aaPlanarDurability = 423, //added
|
||||
aaInnateEnlightenment = 426, //added
|
||||
aaAdvancedSpellCastingMastery = 431,//untested
|
||||
aaAdvancedHealingAdept = 434, //untested
|
||||
aaAdvancedHealingGift = 437, //untested
|
||||
aaCoupdeGrace = 440, //added
|
||||
aaFuryoftheAges = 443, //added
|
||||
aaMasteryofthePast = 446, //untested
|
||||
aaLightningReflexes = 449, //added
|
||||
aaInnateDefense = 454, //added
|
||||
aaRadiantCure = 459, //DB
|
||||
aaHastenedDivinity = 462, //DB
|
||||
aaHastenedTurning = 465, //DB
|
||||
aaHastenedPurificationofSoul = 468, //DB
|
||||
aaHastenedGathering = 471, //DB
|
||||
aaHastenedRabidity = 474, //DB
|
||||
aaHastenedExodus = 477, //DB
|
||||
aaHastenedRoot = 480, //DB
|
||||
aaHastenedMending = 483, //DB
|
||||
aaHastenedBanishment = 486, //DB
|
||||
aaHastenedInstigation = 489, //DB, maybe
|
||||
aaFuriousRampage = 492, //DB
|
||||
aaHastenedPurificationoftheBody = 495,//DB
|
||||
aaHastyExit = 498, //DB
|
||||
aaHastenedPurification = 501, //DB
|
||||
aaFlashofSteel = 504,
|
||||
aaDivineArbitration = 507, //DB
|
||||
aaWrathoftheWild = 510, //DB
|
||||
aaVirulentParalysis = 513, //DB
|
||||
aaHarvestofDruzzil = 516, //DB
|
||||
aaEldritchRune = 517, //DB
|
||||
aaServantofRo = 520, //DB
|
||||
aaWaketheDead = 523, //DB
|
||||
aaSuspendedMinion = 526, //untested
|
||||
aaSpiritCall = 528, //DB
|
||||
aaCelestialRenewal = 531, //DB
|
||||
aaAllegiantFamiliar = 533,
|
||||
aaHandofPiety = 534, //DB
|
||||
aaMithanielsBinding = 537, //untested
|
||||
aaMendingoftheTranquil = 539,
|
||||
aaRagingFlurry = 542,
|
||||
aaGuardianoftheForest = 545, //DB
|
||||
aaSpiritoftheWood = 548, //DB
|
||||
aaBestialFrenzy = 551, //untested
|
||||
aaHarmoniousAttack = 556, //untested
|
||||
aaKnightsAdvantage = 561,
|
||||
aaFerocity = 564,
|
||||
aaViscidRoots = 567,
|
||||
aaSionachiesCrescendo = 568, //untested
|
||||
aaAyonaesTutelage = 571,
|
||||
aaFeignedMinion = 574,
|
||||
aaUnfailingDivinity = 577,
|
||||
aaAnimationEmpathy = 580, // Implemented
|
||||
aaRushtoJudgement = 583,
|
||||
aaLivingShield = 586,
|
||||
aaConsumptionoftheSoul = 589, //untested
|
||||
aaBoastfulBellow = 592, //DB
|
||||
aaFervrentBlessing = 593, //untested
|
||||
aaTouchoftheWicked = 596, //untested
|
||||
aaPunishingBlade = 599,
|
||||
aaSpeedoftheKnight = 602,
|
||||
aaShroudofStealth = 605,
|
||||
aaNimbleEvasion = 606,
|
||||
aaTechniqueofMasterWu = 611,
|
||||
aaHostoftheElements = 616, //DB
|
||||
aaCallofXuzl = 619, //DB
|
||||
aaHastenedStealth = 622,
|
||||
aaIngenuity = 625,
|
||||
aaFleetofFoot = 628,
|
||||
aaFadingMemories = 630,
|
||||
aaTacticalMastery = 631,
|
||||
aaTheftofLife = 634,
|
||||
aaFuryofMagic = 637,
|
||||
aaFuryofMagicMastery2 = 640, //whats the difference?
|
||||
aaProjectIllusion = 643,
|
||||
aaHeadshot = 644, //added
|
||||
aaEntrap = 645, //DB
|
||||
aaUnholyTouch = 646, //untested
|
||||
aaTotalDomination = 649, // Implemented
|
||||
aaStalwartEndurance = 652, //implemented as bonus
|
||||
aaQuickSummoning2 = 655, //whats the difference?
|
||||
aaMentalClarity2 = 658, //whats the difference?
|
||||
aaInnateRegeneration2 = 661, //whats the difference?
|
||||
aaManaBurn2 = 664, //whats the difference?
|
||||
aaExtendedNotes2 = 665, //not implemented - later expansions replaced Extended Notes with this.
|
||||
aaSionachiesCrescendo2 = 668, //not implemented - later expansions replaced Sionachies Crescendo with this.
|
||||
aaImprovedReclaimEnergy2 = 671, //whats the difference? untetsed
|
||||
aaSwiftJourney = 672, //implemented as bonus
|
||||
aaConvalescence = 674, //added 9/26/08
|
||||
aaLastingBreath = 676, //handled by client
|
||||
aaPackrat = 678, //added 9/29/08
|
||||
aaHeightenedEndurance = 683,
|
||||
aaWeaponAffinity = 686, //implemented
|
||||
aaSecondaryForte = 691,
|
||||
aaPersistantCasting = 692,
|
||||
aaTuneofPursuance = 695,
|
||||
aaImprovedInstrumentMastery = 700,
|
||||
aaImprovedSingingMastery =701,
|
||||
aaExultantBellowing = 702,
|
||||
aaEchoofTaelosia = 707,
|
||||
aaInternalMetronome = 710, //In 2006 this AA was removed.
|
||||
aaPiousSupplication = 715,
|
||||
aaBeastialAlignment = 718, //untested
|
||||
aaWrathofXuzl = 721,
|
||||
aaFeralSwipe = 723, //DB?
|
||||
aaWardersFury = 724,
|
||||
aaWardersAlacrity = 729,
|
||||
aaPetAffinity = 734, // Implemented
|
||||
aaMasteryofthePast2 = 735, //whats the difference?
|
||||
aaSpellCastingSubtlety2 = 738, //whats the difference?
|
||||
aaTouchoftheDivine = 741,
|
||||
aaDivineAvatar = 746, //DB
|
||||
aaExquisiteBenediction = 749, //DB
|
||||
aaQuickenedCuring = 754,
|
||||
aaNaturesBoon = 757, //DB
|
||||
aaAdvancedTracking = 762,
|
||||
aaCriticalAffliction = 767,
|
||||
aaFuryofMagicMastery = 770, //whats the difference?
|
||||
aaDoppelganger = 773,
|
||||
aaEnchancedForgetfulness = 776,
|
||||
aaMesmerizationMastery = 781,
|
||||
aaQuickMassGroupBuff = 782,
|
||||
aaSharedHealth = 785,
|
||||
aaElementalFury = 790,
|
||||
aaElementalAlacrity = 795,
|
||||
aaElementalAgility = 800,
|
||||
aaElementalDurability = 803,
|
||||
aaSinisterStrikes = 806,
|
||||
aaStrikethrough = 807,
|
||||
aaStonewall = 810,
|
||||
aaRapidStrikes = 815,
|
||||
aaKickMastery = 820,
|
||||
aaHightenedAwareness = 823,
|
||||
aaDestructiveForce = 828, //DB
|
||||
aaSwarmofDecay = 831, //DB
|
||||
aaDeathsFury = 834,
|
||||
aaQuickeningofDeath = 839,
|
||||
aaAdvancedTheftofLife = 844,
|
||||
aaTripleBackstab = 846,
|
||||
aaHastenedPiety = 849,
|
||||
aaImmobilizingBash = 852,
|
||||
aaViciousSmash = 855,
|
||||
aaRadiantCure2 = 860, //whats the difference?
|
||||
aaPurification = 863,
|
||||
aaPrecisionofthePathfinder = 864,
|
||||
aaCoatofThistles = 867,
|
||||
aaFlamingArrows = 872, //untested
|
||||
aaFrostArrows = 875, //untested
|
||||
aaSeizedOpportunity = 878,
|
||||
aaTrapCircumvention = 881,
|
||||
aaImprovedHastyExit = 886,
|
||||
aaVirulentVenom = 888,
|
||||
aaImprovedConsumptionofSoul = 893,
|
||||
aaIntenseHatred = 895,
|
||||
aaAdvancedSpiritCall = 900,
|
||||
aaCalloftheAncients = 902, //DB
|
||||
aaSturdiness = 907,
|
||||
aaWarlordsTenacity = 912, //DB
|
||||
aaStrengthenedStrike = 915,
|
||||
aaExtendedShielding = 918,
|
||||
aaRosFlamingFamiliar = 921, //DB
|
||||
aaEcisIcyFamiliar = 922, //DB
|
||||
aaDruzzilsMysticalFamiliar = 923, //DB
|
||||
aaAdvancedFuryofMagicMastery = 924, //added 9/29/08
|
||||
aaWardofDestruction = 926, //DB
|
||||
aaFrenziedDevastation = 931, //DB
|
||||
aaCombatFury2 = 934, //whats the difference?
|
||||
aaCombatFury3 = 937, //whats the difference?
|
||||
aaCombatFury4 = 940, //whats the difference?
|
||||
aaFuryoftheAges2 = 943, //whats the difference?
|
||||
aaFuryoftheAges3 = 946, //whats the difference?
|
||||
aaFuryoftheAges4 = 949, //whats the difference?
|
||||
aaPlanarDurability2 = 952, //whats the difference?
|
||||
aaInnateEnlightenment2 = 955, //whats the difference?
|
||||
aaDireCharm2 = 960, //whats the difference?
|
||||
aaDireCharm3 = 961, //whats the difference?
|
||||
aaTouchoftheDivine2 = 962, //whats the difference?
|
||||
aaTouchofDecay = 967,
|
||||
aaCalloftheAncients2 = 970, //whats the difference?
|
||||
aaImprovedVision = 975,
|
||||
aaEternalBreath = 978, //handled by client
|
||||
aaBlacksmithingMastery = 979, //added 9/29/08
|
||||
aaBakingMastery = 982, //added 9/29/08
|
||||
aaBrewingMastery = 985, //added 9/29/08
|
||||
aaFletchingMastery2 = 988, //added 9/29/08
|
||||
aaPotteryMastery = 991, //added 9/29/08
|
||||
aaTailoringMastery = 994, //added 9/29/08
|
||||
aaSalvage = 997,
|
||||
aaOrigin = 1000, //spell
|
||||
aaChaoticPotential = 1001, //added
|
||||
aaDiscordantDefiance = 1006, //added 9/29/08
|
||||
aaTrialsofMataMuram = 1011,
|
||||
aaMysticalAttuning = 1021,
|
||||
aaDelayDeath = 1026,
|
||||
aaHealthyAura = 1031,
|
||||
aaFitness = 1036,
|
||||
aaVeteransWrath = 1041, //added 9/29/08
|
||||
aaVeteransWrath2 = 1044, //whats the difference?
|
||||
aaVeteransWrath3 = 1047, //whats the difference?
|
||||
aaVeteransWrath4 = 1050, //whats the difference?
|
||||
aaDeathblow = 1053,
|
||||
aaReflexiveMastery = 1061,
|
||||
aaDefensiveInstincts = 1066,
|
||||
aaMnemonicRetention = 1071, //Implemented
|
||||
aaExpansiveMind = 1072, //added 9/29/08
|
||||
aaSleightofHand = 1077,
|
||||
aaSleightofHand2 = 1080, //whats the difference?
|
||||
aaHealingAdeptMastery = 1083,
|
||||
aaHealingGiftMastery = 1086,
|
||||
aaArcaneTongues = 1089,
|
||||
aaMasterofDisguise = 1092,
|
||||
aaSlipperyAttacks = 1093,
|
||||
aaImprovedCriticalAffliction = 1099,
|
||||
aaFortifiedBellowing = 1102,
|
||||
aaFuryofMagic2 = 1107, //whats the difference?
|
||||
aaDanceofBlades = 1110,
|
||||
aaShieldofNotes = 1116,
|
||||
aaRoarofThunder = 1119,
|
||||
aaPersistentMinion = 1122,
|
||||
aaPerfectionofSpirit = 1123,
|
||||
aaReplentishCompanion = 1126,
|
||||
aaAdvancedPetDiscipline = 1129,
|
||||
aaThrowingMastery = 1131,
|
||||
aaBlurofAxes = 1134,
|
||||
aaHastenedWarCry = 1137,
|
||||
aaDeadAim = 1140,
|
||||
aaFrenziedDefense = 1143,
|
||||
aaTirelessSprint = 1146,
|
||||
aaDesperation = 1149,
|
||||
aaUntamedRage = 1150,
|
||||
aaEchoingCries = 1155,
|
||||
aaViciousFrenzy = 1158,
|
||||
aaCrazedOnslaught = 1163,
|
||||
aaOverwhelmingAttack = 1172,
|
||||
aaFuriousRage = 1175,
|
||||
aaBloodPact = 1178,
|
||||
aaShieldingResistance = 1181,
|
||||
aaHealingBoon = 1186,
|
||||
aaResplendentCure = 1189,
|
||||
aaCelestialHammer = 1192,
|
||||
aaDivineRetribution = 1195,
|
||||
aaCelestialRejuvination = 1203,
|
||||
aaFerventBenediction = 1206,
|
||||
aaSanctuary = 1209,
|
||||
aaDestructiveFury = 1210, //added 9/29/08
|
||||
aaDestructiveFury2 = 1213, //whats the difference?
|
||||
aaBoonoftheForest = 1222,
|
||||
aaSpiritoftheGrove = 1225,
|
||||
aaCalloftheWild = 1228,
|
||||
aaSecondaryRecall = 1229,
|
||||
aaNaturesBounty = 1230,
|
||||
aaStasis = 1233,
|
||||
aaColorShock = 1239,
|
||||
aaMindOverMatter = 1242,
|
||||
aaSoothingWords = 1245,
|
||||
aaElementalSwarm = 1248,
|
||||
aaHeartofFlames = 1251,
|
||||
aaHeartofVapor = 1252,
|
||||
aaHeartofIce = 1253,
|
||||
aaHeartofStone = 1254,
|
||||
aaImitateDeath = 1255,
|
||||
aaCripplingStrike = 1256,
|
||||
aaStunningKick = 1259,
|
||||
aaEyeGouge = 1262,
|
||||
aaIronKicks = 1265,
|
||||
aaStyleoftheMimic = 1268,
|
||||
aaDeathPeace2 = 1272, //whats the difference?
|
||||
aaArmyoftheDead = 1274,
|
||||
aaCelestialStun = 1277,
|
||||
aaHandofDevotion = 1278,
|
||||
aaSteadfastWill = 1284,
|
||||
aaShieldBlock = 1287,
|
||||
aaScoutsEfficiency = 1290,
|
||||
aaGuardianoftheGlade = 1293,
|
||||
aaTrackingMastery = 1296,
|
||||
aaFlurryofKnives = 1301,
|
||||
aaPrecision = 1304,
|
||||
aaNervesofSteel = 1307,
|
||||
aaTouchoftheCursed = 1313,
|
||||
aaSpiritualCorrosion = 1316,
|
||||
aaSoulThief = 1319,
|
||||
aaSpiritualChanneling = 1323,
|
||||
aaBoonoftheAncients = 1324,
|
||||
aaAncestralAid = 1327,
|
||||
aaResoluteDefiance = 1330,
|
||||
aaPresstheAttack = 1333,
|
||||
aaMindCrash = 1334,
|
||||
aaProlongedDestruction = 1337,
|
||||
aaRosGreaterFamiliar = 1340,
|
||||
aaEcisGreaterFamiliar = 1341,
|
||||
aaDruzzilsGreaterFamiliar = 1342,
|
||||
aaTeleportBind = 1343,
|
||||
aaDevotedFamiliar = 1344,
|
||||
aaAuspiceoftheHunter = 1345,
|
||||
aaSavageSpirit = 1348,
|
||||
aaPresstheAttack2 = 1351, //whats the difference?
|
||||
aaCripplingStrike2 = 1352, //whats the difference?
|
||||
aaStunningKick2 = 1353, //whats the difference?
|
||||
aaEyeGouge2 = 1358, //whats the difference?
|
||||
|
||||
//Dragons of Norrath
|
||||
//good info here: http://www.eqthieves.com/exp-don-progression.htm and here: http://everquest.allakhazam.com/db/guides.html?guide=811
|
||||
aaGiftoftheDarkReign = 1361, //from dbstr_us.txt
|
||||
aaTenacityoftheDarkReign = 1362, //from dbstr_us.txt
|
||||
aaEmbraceoftheDarkReign = 1363, //from dbstr_us.txt
|
||||
aaPoweroftheDarkReign = 1364, //from dbstr_us.txt
|
||||
aaFervoroftheDarkReign = 1365, //from dbstr_us.txt
|
||||
aaGiftoftheKeepers = 1366, //from dbstr_us.txt
|
||||
aaValoroftheKeepers = 1367, //from dbstr_us.txt
|
||||
aaEmbraceoftheKeepers = 1368, //from dbstr_us.txt
|
||||
aaPoweroftheKeepers = 1369, //from dbstr_us.txt
|
||||
aaSanctityoftheKeepers = 1370, //from dbstr_us.txt
|
||||
|
||||
//Veteran AAs
|
||||
aaLessonoftheDevoted = 1371, //from dbstr_us.txt
|
||||
aaInfusionoftheFaithful = 1372, //from dbstr_us.txt
|
||||
aaChaoticJester = 1373, //from dbstr_us.txt
|
||||
aaExpedientRecovery = 1374, //from dbstr_us.txt
|
||||
aaSteadfastServant = 1375, //from dbstr_us.txt
|
||||
aaStaunchRecovery = 1376, //from dbstr_us.txt
|
||||
aaIntensityoftheResolute = 1377, //from dbstr_us.txt
|
||||
|
||||
//Depths of Darkhollow
|
||||
|
||||
//the following 5 look to be used as flags for completion of the Blood Raids for access to the Demiplane of Blood
|
||||
//quest info here: http://everquest.allakhazam.com/db/quest.html?quest=3582
|
||||
//"You must also complete the five Blood Raids in any order: The Council of Nine, Emperor Draygun, Bloodeye, Matriarch Shyra, Sendaii, the Hive Queen"
|
||||
//"The AA's you receive are: Curse of Blood (1/5), Affliction of Blood (2/5), Torment of Blood (3/5), Temptation of Blood (4/5), Invitation of Blood (5/5)."
|
||||
aaCurseofBlood = 1378, //from dbstr_us.txt
|
||||
aaAfflictionofBlood = 1379, //from dbstr_us.txt
|
||||
aaTormentofBlood = 1380, //from dbstr_us.txt
|
||||
aaTemptationofBlood = 1381, //from dbstr_us.txt
|
||||
aaInvitationofBlood = 1382, //from dbstr_us.txt
|
||||
|
||||
aaTurnUndead2 = 1383, //from dbstr_us.txt, Class AA changed in DoD
|
||||
aaWrackUndead = 1386, //from dbstr_us.txt, PoP Class AA changed in DoD
|
||||
aaEradicateUndead = 1387, //from dbstr_us.txt
|
||||
aaInnateSeeInvis = 1388, //from dbstr_us.txt
|
||||
aaProlongedMortality = 1389, //from dbstr_us.txt
|
||||
aaPrecognition = 1394, //from dbstr_us.txt
|
||||
aaThickSkin = 1399, //from dbstr_us.txt
|
||||
aaSilentCasting = 1404, //from dbstr_us.txt
|
||||
aaSilentCasting2 = 1409, //from dbstr_us.txt
|
||||
aaHastenedMindCrash = 1414, //from dbstr_us.txt
|
||||
aaFieldDressing = 1417, //from dbstr_us.txt
|
||||
aaBandageWounds = 1420, //from dbstr_us.txt
|
||||
aaCascadingRage = 1425, //from dbstr_us.txt
|
||||
aaElementalFerocity = 1430, //from dbstr_us.txt
|
||||
aaGiftofMana = 1435, //from dbstr_us.txt
|
||||
aaRuneofShadows = 1440, //from dbstr_us.txt
|
||||
aaChannelingMastery = 1445, //from dbstr_us.txt
|
||||
aaConservation = 1453, //from dbstr_us.txt
|
||||
aaCryofBattle = 1458, //from dbstr_us.txt
|
||||
aaWardofPurity = 1459, //from dbstr_us.txt
|
||||
aaTurnSummoned2 = 1462, //from dbstr_us.txt
|
||||
aaWrackSummoned = 1465, //from dbstr_us.txt
|
||||
aaEradicateSummoned = 1466, //from dbstr_us.txt
|
||||
aaWardersSavagery = 1467, //from dbstr_us.txt
|
||||
aaShackleofSpirits = 1470, //from dbstr_us.txt
|
||||
aaHastenedThunder = 1471, //from dbstr_us.txt
|
||||
aaTranslocationalAnchor = 1474, //from dbstr_us.txt
|
||||
aaStealthyGetaway = 1477, //from dbstr_us.txt
|
||||
aaPyromancy = 1478, //from dbstr_us.txt
|
||||
aaMasteryofFury = 1483, //from dbstr_us.txt
|
||||
aaAbundantHealing = 1486, //from dbstr_us.txt
|
||||
aaGreaterAvatar = 1491, //from dbstr_us.txt
|
||||
aaSharedCamouflage = 1494, //from dbstr_us.txt
|
||||
aaConvergenceofSpirits = 1495, //from dbstr_us.txt
|
||||
aaNaturesGuardian = 1498, //from dbstr_us.txt
|
||||
aaEdictofCommand = 1501, //from dbstr_us.txt
|
||||
aaExtendedBurnout = 1504, //from dbstr_us.txt
|
||||
aaGuardianofRo = 1507, //from dbstr_us.txt
|
||||
aaBloodMagic = 1510, //from dbstr_us.txt
|
||||
aaGraverobbing = 1511, //from dbstr_us.txt
|
||||
aaAfflictionMastery = 1514, //from dbstr_us.txt
|
||||
aaGreaterRabidBear = 1517, //from dbstr_us.txt
|
||||
aaAncestralGuard = 1520, //from dbstr_us.txt
|
||||
aaCloakofLight = 1523, //from dbstr_us.txt
|
||||
aaVanquishUndead = 1524, //from dbstr_us.txt
|
||||
aaCloakofShadows = 1527, //from dbstr_us.txt
|
||||
aaWillfulDeath = 1528, //from dbstr_us.txt
|
||||
aaSwiftBlade = 1533, //from dbstr_us.txt
|
||||
aaWickedBlade = 1536, //from dbstr_us.txt
|
||||
aaForcedOpening = 1539, //from dbstr_us.txt
|
||||
aaAppraisal = 1542, //from dbstr_us.txt
|
||||
aaPreciseStrikes = 1543, //from dbstr_us.txt
|
||||
aaHastenedDeath = 1546, //from dbstr_us.txt
|
||||
aaUnflinchingResolve = 1549, //from dbstr_us.txt
|
||||
aaWeightlessSteps = 1552, //from dbstr_us.txt
|
||||
aaHastenedBlades = 1555, //from dbstr_us.txt
|
||||
aaImprovedHarmoniousAttack = 1563, //from dbstr_us.txt
|
||||
aaImprovedBestialFrenzy = 1566, //from dbstr_us.txt
|
||||
aaSongofStone = 1569, //from dbstr_us.txt
|
||||
aaDeepSleep = 1572, //from dbstr_us.txt
|
||||
aaCompanionsGift = 1577, //from dbstr_us.txt
|
||||
aaHastenedDefiance = 1583, //from dbstr_us.txt
|
||||
aaDauntlessPerseverance = 1586, //from dbstr_us.txt
|
||||
aaConcentration = 1587, //from dbstr_us.txt
|
||||
aaEnhancedAggression = 1592, //from dbstr_us.txt
|
||||
aaCallofChallenge = 1597, //from dbstr_us.txt
|
||||
aaCacophony = 1598, //from dbstr_us.txt
|
||||
aaImprovedHeadshot = 1601, //from dbstr_us.txt
|
||||
aaAnatomy = 1604, //from dbstr_us.txt
|
||||
aaFetterofSpirits = 1607, //from dbstr_us.txt
|
||||
aaTrickShot = 1608, //from dbstr_us.txt
|
||||
aaLightningStrikes = 1616, //from dbstr_us.txt
|
||||
aaRelentlessAssault = 1621, //from dbstr_us.txt
|
||||
aaKnightsExpertise = 1624, //from dbstr_us.txt
|
||||
aaSelosEnduringCadence = 1627, //from dbstr_us.txt
|
||||
aaHarmTouch = 7800, //from dbstr_us.txt
|
||||
aaLayonHands = 7850, //from dbstr_us.txt
|
||||
aaLayonHandsRank16 = 7866,
|
||||
|
||||
aaHighestID //this should always be last, and should always
|
||||
//follow the highest AA ID
|
||||
} aaID;
|
||||
*/
|
||||
|
||||
|
||||
typedef enum { //AA IDs
|
||||
aaNone =0,
|
||||
aaInnateStrength =2,//implemented as bonus
|
||||
@ -2109,21 +1510,6 @@ typedef enum { //AA IDs
|
||||
//follow the highest AA ID
|
||||
} aaID;
|
||||
|
||||
|
||||
//Structure representing the database's AA actions
|
||||
struct AA_DBAction {
|
||||
uint32 reuse_time; //in seconds
|
||||
uint16 spell_id; //spell to cast, SPELL_UNKNOWN=no spell
|
||||
aaTargetType target; //from aaTargetType
|
||||
aaNonspellAction action; //non-spell action to take
|
||||
uint16 mana_cost; //mana the NON-SPELL action costs
|
||||
uint16 duration; //duration of NON-SPELL effect, 0=N/A
|
||||
aaID redux_aa; //AA which reduces reuse time
|
||||
int32 redux_rate; //%/point in redux_aa reduction in reuse time
|
||||
aaID redux_aa2; //AA which reduces reuse time
|
||||
int32 redux_rate2; //%/point in redux_aa reduction in reuse time
|
||||
};
|
||||
|
||||
//Structure representing the database's swarm pet configs
|
||||
struct AA_SwarmPet {
|
||||
uint8 count; //number to summon
|
||||
@ -2131,23 +1517,6 @@ struct AA_SwarmPet {
|
||||
uint16 duration; //how long they last, in seconds
|
||||
};
|
||||
|
||||
struct AALevelCost_Struct
|
||||
{
|
||||
uint32 Level;
|
||||
uint32 Cost;
|
||||
};
|
||||
|
||||
//assumes that no activatable aa.has more than 5 ranks
|
||||
#define MAX_AA_ACTION_RANKS 20
|
||||
extern AA_DBAction AA_Actions[aaHighestID][MAX_AA_ACTION_RANKS]; //[aaid][rank]
|
||||
extern std::map<uint16, AA_SwarmPet> AA_SwarmPets; //key=spell_id
|
||||
|
||||
#define AA_Choose3(val, v1, v2, v3) (val==1?v1:(val==2?v2:v3))
|
||||
|
||||
extern std::map<uint32,SendAA_Struct*>aas_send;
|
||||
extern std::map<uint32, std::map<uint32, AA_Ability> > aa_effects;
|
||||
extern std::map<uint32, AALevelCost_Struct> AARequiredLevelAndCost;
|
||||
|
||||
enum { //values of AA_Action.action
|
||||
aaActionActivate = 0,
|
||||
aaActionSetEXP = 1,
|
||||
@ -2167,4 +1536,11 @@ public:
|
||||
uint32 owner_id;
|
||||
};
|
||||
|
||||
enum AATimers
|
||||
{
|
||||
aaTimerRampage,
|
||||
aaTimerWarcry,
|
||||
aaTimerMax
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
70
zone/aa_ability.cpp
Normal file
70
zone/aa_ability.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/* 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 "masterentity.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(current_level == 0)
|
||||
return nullptr;
|
||||
|
||||
if(!first)
|
||||
return nullptr;
|
||||
|
||||
int i = 1;
|
||||
Rank *current = first;
|
||||
while(current->next) {
|
||||
if(i == current_level) {
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
int AA::Ability::GetMaxLevel(Mob *who) {
|
||||
int max_level = 0;
|
||||
Rank *current = first;
|
||||
while(current) {
|
||||
if(!who->CanUseAlternateAdvancementRank(current)) {
|
||||
return max_level;
|
||||
}
|
||||
|
||||
max_level++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return max_level;
|
||||
}
|
||||
61
zone/aa_ability.h
Normal file
61
zone/aa_ability.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_ZONE_AA_ABILITY_H
|
||||
#define EQEMU_ZONE_AA_ABILITY_H
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "aa_rank_effects.h"
|
||||
#include "aa_rank.h"
|
||||
|
||||
class Mob;
|
||||
|
||||
namespace AA
|
||||
{
|
||||
|
||||
class Ability
|
||||
{
|
||||
public:
|
||||
Ability() { }
|
||||
~Ability() { }
|
||||
|
||||
Rank *GetMaxRank();
|
||||
Rank *GetRankByPointsSpent(int current_level);
|
||||
int GetMaxLevel(Mob *who);
|
||||
|
||||
int id;
|
||||
std::string name;
|
||||
int category;
|
||||
int classes;
|
||||
int races;
|
||||
int deities;
|
||||
int drakkin_heritage;
|
||||
int status;
|
||||
bool grant_only;
|
||||
int type;
|
||||
int charges;
|
||||
int first_rank_id;
|
||||
Rank *first;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
56
zone/aa_rank.h
Normal file
56
zone/aa_rank.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_ZONE_AA_RANK_H
|
||||
#define EQEMU_ZONE_AA_RANK_H
|
||||
|
||||
namespace AA
|
||||
{
|
||||
|
||||
class Ability;
|
||||
class Rank
|
||||
{
|
||||
public:
|
||||
Rank() { }
|
||||
~Rank() { }
|
||||
|
||||
int id;
|
||||
int upper_hotkey_sid;
|
||||
int lower_hotkey_sid;
|
||||
int title_sid;
|
||||
int desc_sid;
|
||||
int cost;
|
||||
int level_req;
|
||||
int spell;
|
||||
int spell_type;
|
||||
int recast_time;
|
||||
int prev_id;
|
||||
Rank *prev;
|
||||
int next_id;
|
||||
Rank *next;
|
||||
int current_value;
|
||||
int expansion;
|
||||
int total_cost;
|
||||
Ability *base_ability;
|
||||
std::vector<RankEffect> effects;
|
||||
std::map<int, int> prereqs;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
38
zone/aa_rank_effects.h
Normal file
38
zone/aa_rank_effects.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_ZONE_AA_RANK_EFFECTS_H
|
||||
#define EQEMU_ZONE_AA_RANK_EFFECTS_H
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include <string>
|
||||
|
||||
namespace AA
|
||||
{
|
||||
|
||||
struct RankEffect
|
||||
{
|
||||
int slot;
|
||||
int effect_id;
|
||||
int base1;
|
||||
int base2;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
155
zone/attack.cpp
155
zone/attack.cpp
@ -1372,6 +1372,13 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
///////////////////////////////////////////////////////////
|
||||
////// Send Attack Damage
|
||||
///////////////////////////////////////////////////////////
|
||||
if (damage > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skillinuse &&
|
||||
IsValidSpell(aabonuses.SkillAttackProc[2])) {
|
||||
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
|
||||
if (zone->random.Roll(chance))
|
||||
SpellFinished(aabonuses.SkillAttackProc[2], other, 10, 0, -1,
|
||||
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
|
||||
}
|
||||
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse);
|
||||
|
||||
if (IsDead()) return false;
|
||||
@ -3512,14 +3519,6 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
if(damage > 0) {
|
||||
//if there is some damage being done and theres an attacker involved
|
||||
if(attacker) {
|
||||
if(spell_id == SPELL_HARM_TOUCH2 && attacker->IsClient() && attacker->CastToClient()->CheckAAEffect(aaEffectLeechTouch)){
|
||||
int healed = damage;
|
||||
healed = attacker->GetActSpellHealing(spell_id, healed);
|
||||
attacker->HealDamage(healed);
|
||||
entity_list.MessageClose(this, true, 300, MT_Emote, "%s beams a smile at %s", attacker->GetCleanName(), this->GetCleanName() );
|
||||
attacker->CastToClient()->DisableAAEffect(aaEffectLeechTouch);
|
||||
}
|
||||
|
||||
// if spell is lifetap add hp to the caster
|
||||
if (spell_id != SPELL_UNKNOWN && IsLifetapSpell( spell_id )) {
|
||||
int healed = damage;
|
||||
@ -4416,42 +4415,55 @@ bool Mob::TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Mob::DoRiposte(Mob* defender) {
|
||||
void Mob::DoRiposte(Mob *defender)
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a riposte");
|
||||
|
||||
if (!defender)
|
||||
return;
|
||||
|
||||
defender->Attack(this, MainPrimary, true);
|
||||
if (HasDied()) return;
|
||||
if (HasDied())
|
||||
return;
|
||||
|
||||
int32 DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[0] +
|
||||
defender->spellbonuses.GiveDoubleRiposte[0] +
|
||||
defender->itembonuses.GiveDoubleRiposte[0];
|
||||
// this effect isn't used on live? See no AAs or spells
|
||||
int32 DoubleRipChance = defender->aabonuses.DoubleRiposte + defender->spellbonuses.DoubleRiposte +
|
||||
defender->itembonuses.DoubleRiposte;
|
||||
|
||||
DoubleRipChance = defender->aabonuses.DoubleRiposte +
|
||||
defender->spellbonuses.DoubleRiposte +
|
||||
defender->itembonuses.DoubleRiposte;
|
||||
|
||||
//Live AA - Double Riposte
|
||||
if(DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a double riposed (%d percent chance)", DoubleRipChance);
|
||||
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Preforming a double riposted from SE_DoubleRiposte (%d percent chance)", DoubleRipChance);
|
||||
defender->Attack(this, MainPrimary, true);
|
||||
if (HasDied()) return;
|
||||
if (HasDied())
|
||||
return;
|
||||
}
|
||||
|
||||
//Double Riposte effect, allows for a chance to do RIPOSTE with a skill specfic special attack (ie Return Kick).
|
||||
//Coded narrowly: Limit to one per client. Limit AA only. [1 = Skill Attack Chance, 2 = Skill]
|
||||
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[0] + defender->spellbonuses.GiveDoubleRiposte[0] +
|
||||
defender->itembonuses.GiveDoubleRiposte[0];
|
||||
|
||||
// Live AA - Double Riposte
|
||||
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
Log.Out(Logs::Detail, Logs::Combat,
|
||||
"Preforming a double riposted from SE_GiveDoubleRiposte base1 == 0 (%d percent chance)",
|
||||
DoubleRipChance);
|
||||
defender->Attack(this, MainPrimary, true);
|
||||
if (HasDied())
|
||||
return;
|
||||
}
|
||||
|
||||
// Double Riposte effect, allows for a chance to do RIPOSTE with a skill specific special attack (ie Return Kick).
|
||||
// Coded narrowly: Limit to one per client. Limit AA only. [1 = Skill Attack Chance, 2 = Skill]
|
||||
|
||||
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
|
||||
|
||||
if(DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a return SPECIAL ATTACK (%d percent chance)", DoubleRipChance);
|
||||
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a return SPECIAL ATTACK (%d percent chance)",
|
||||
DoubleRipChance);
|
||||
|
||||
if (defender->GetClass() == MONK)
|
||||
defender->MonkSpecialAttack(this, defender->aabonuses.GiveDoubleRiposte[2]);
|
||||
else if (defender->IsClient())
|
||||
defender->CastToClient()->DoClassAttacks(this,defender->aabonuses.GiveDoubleRiposte[2], true);
|
||||
else if (defender->IsClient() && defender->CastToClient()->HasSkill((SkillUseTypes)defender->aabonuses.GiveDoubleRiposte[2]))
|
||||
defender->CastToClient()->DoClassAttacks(this, defender->aabonuses.GiveDoubleRiposte[2], true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4643,7 +4655,7 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
|
||||
if (IsClient() && aabonuses.LimitToSkill[skill]){
|
||||
|
||||
CanProc = true;
|
||||
uint32 effect = 0;
|
||||
uint32 effect_id = 0;
|
||||
int32 base1 = 0;
|
||||
int32 base2 = 0;
|
||||
uint32 slot = 0;
|
||||
@ -4662,36 +4674,41 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
|
||||
proc_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
|
||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aaid);
|
||||
if(find_iter == aa_effects.end())
|
||||
break;
|
||||
for(auto &rank_info : aa_ranks) {
|
||||
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_info.first, rank_info.second.first);
|
||||
auto ability = ability_rank.first;
|
||||
auto rank = ability_rank.second;
|
||||
|
||||
for (std::map<uint32, AA_Ability>::const_iterator iter = aa_effects[aaid].begin(); iter != aa_effects[aaid].end(); ++iter) {
|
||||
effect = iter->second.skill_id;
|
||||
base1 = iter->second.base1;
|
||||
base2 = iter->second.base2;
|
||||
slot = iter->second.slot;
|
||||
|
||||
if (effect == SE_SkillProc || effect == SE_SkillProcSuccess) {
|
||||
proc_spell_id = base1;
|
||||
ProcMod = static_cast<float>(base2);
|
||||
if(!ability) {
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (effect == SE_LimitToSkill && base1 <= HIGHEST_SKILL) {
|
||||
for(auto &effect : rank->effects) {
|
||||
effect_id = effect.effect_id;
|
||||
base1 = effect.base1;
|
||||
base2 = effect.base2;
|
||||
slot = effect.slot;
|
||||
|
||||
if (CanProc && base1 == skill && IsValidSpell(proc_spell_id)) {
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
if(effect_id == SE_SkillProc || effect_id == SE_SkillProcSuccess) {
|
||||
proc_spell_id = base1;
|
||||
ProcMod = static_cast<float>(base2);
|
||||
}
|
||||
else if(effect_id == SE_LimitToSkill && base1 <= HIGHEST_SKILL) {
|
||||
|
||||
if (zone->random.Roll(final_chance)) {
|
||||
ExecWeaponProc(nullptr, proc_spell_id, on);
|
||||
CanProc = false;
|
||||
break;
|
||||
if (CanProc && base1 == skill && IsValidSpell(proc_spell_id)) {
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
|
||||
if (zone->random.Roll(final_chance)) {
|
||||
ExecWeaponProc(nullptr, proc_spell_id, on);
|
||||
CanProc = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
proc_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
else {
|
||||
proc_spell_id = 0;
|
||||
ProcMod = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5042,3 +5059,39 @@ void NPC::SetAttackTimer()
|
||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
|
||||
if (CanThisClassDoubleAttack()) {
|
||||
CheckIncreaseSkill(SkillDoubleAttack, target, -10);
|
||||
if (CheckDoubleAttack())
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
if (hand == MainPrimary && GetLevel() >= 60 &&
|
||||
(GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER) &&
|
||||
CheckDoubleAttack(true))
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
if (hand == MainPrimary) {
|
||||
auto flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
||||
if (flurrychance && zone->random.Roll(flurrychance)) {
|
||||
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
|
||||
auto extraattackchance = aabonuses.ExtraAttackChance + spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance;
|
||||
if (extraattackchance) {
|
||||
auto wpn = GetInv().GetItem(MainPrimary);
|
||||
if (wpn && (wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
||||
wpn->GetItem()->ItemType == ItemType2HSlash ||
|
||||
wpn->GetItem()->ItemType == ItemType2HPiercing))
|
||||
if (zone->random.Roll(extraattackchance))
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1639
zone/bonuses.cpp
1639
zone/bonuses.cpp
File diff suppressed because it is too large
Load Diff
962
zone/bot.cpp
962
zone/bot.cpp
File diff suppressed because it is too large
Load Diff
12
zone/bot.h
12
zone/bot.h
@ -314,11 +314,12 @@ public:
|
||||
virtual float GetAOERange(uint16 spell_id);
|
||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
|
||||
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
|
||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr);
|
||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0,
|
||||
uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr, uint32 aa_id = 0);
|
||||
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar);
|
||||
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
|
||||
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction);
|
||||
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF);
|
||||
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0);
|
||||
|
||||
// Bot Action Command Methods
|
||||
bool MesmerizeTarget(Mob* target);
|
||||
@ -448,9 +449,6 @@ public:
|
||||
bool IsBotWISCaster() { return (GetClass() == CLERIC || GetClass() == DRUID || GetClass() == SHAMAN); }
|
||||
bool CanHeal();
|
||||
int GetRawACNoShield(int &shield_ac);
|
||||
void LoadAAs();
|
||||
uint32 GetAA(uint32 aa_id);
|
||||
void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon);
|
||||
bool GetHasBeenSummoned() { return _hasBeenSummoned; }
|
||||
const glm::vec3 GetPreSummonLocation() const { return m_PreSummonLocation; }
|
||||
bool GetGroupMessagesOn() { return _groupMessagesOn; }
|
||||
@ -564,7 +562,7 @@ protected:
|
||||
virtual bool CheckBotDoubleAttack(bool Triple = false);
|
||||
virtual int32 GetBotFocusEffect(BotfocusType bottype, uint16 spell_id);
|
||||
virtual int32 CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spell_id, bool best_focus=false);
|
||||
virtual int32 CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id);
|
||||
virtual int32 CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint32 points, uint16 spell_id);
|
||||
virtual void PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* client);
|
||||
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
||||
virtual float GetMaxMeleeRangeToTarget(Mob* target);
|
||||
@ -646,12 +644,12 @@ private:
|
||||
uint8 _baseGender; // Bots gender. Necessary to preserve the original value otherwise it can be changed by illusions.
|
||||
|
||||
// Class Methods
|
||||
void LoadAAs();
|
||||
int32 acmod();
|
||||
void GenerateBaseStats();
|
||||
void GenerateAppearance();
|
||||
void GenerateArmorClass();
|
||||
int32 GenerateBaseHitPoints();
|
||||
void GenerateAABonuses(StatBonuses* newbon);
|
||||
int32 GenerateBaseManaPoints();
|
||||
void GenerateSpecialAttacks();
|
||||
void SetBotID(uint32 botID);
|
||||
|
||||
122
zone/client.cpp
122
zone/client.cpp
@ -176,7 +176,6 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
admin = 0;
|
||||
lsaccountid = 0;
|
||||
shield_target = nullptr;
|
||||
SQL_log = nullptr;
|
||||
guild_id = GUILD_NONE;
|
||||
guildrank = 0;
|
||||
GuildBanker = false;
|
||||
@ -441,7 +440,7 @@ void Client::SendZoneInPackets()
|
||||
|
||||
//Send AA Exp packet:
|
||||
if (GetLevel() >= 51)
|
||||
SendAAStats();
|
||||
SendAlternateAdvancementStats();
|
||||
|
||||
// Send exp packets
|
||||
outapp = new EQApplicationPacket(OP_ExpUpdate, sizeof(ExpUpdate_Struct));
|
||||
@ -458,7 +457,7 @@ void Client::SendZoneInPackets()
|
||||
}
|
||||
safe_delete(outapp);
|
||||
|
||||
SendAATimers();
|
||||
SendAlternateAdvancementTimers();
|
||||
|
||||
outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(ZoneInSendName_Struct));
|
||||
ZoneInSendName_Struct* zonesendname = (ZoneInSendName_Struct*)outapp->pBuffer;
|
||||
@ -525,48 +524,39 @@ void Client::ReportConnectingState() {
|
||||
};
|
||||
}
|
||||
|
||||
bool Client::SaveAA(){
|
||||
int first_entry = 0;
|
||||
std::string rquery;
|
||||
/* Save Player AA */
|
||||
bool Client::SaveAA() {
|
||||
std::string iquery;
|
||||
int spentpoints = 0;
|
||||
for (int a = 0; a < MAX_PP_AA_ARRAY; a++) {
|
||||
uint32 points = aa[a]->value;
|
||||
if (points > HIGHEST_AA_VALUE) {
|
||||
aa[a]->value = HIGHEST_AA_VALUE;
|
||||
points = HIGHEST_AA_VALUE;
|
||||
}
|
||||
if (points > 0) {
|
||||
SendAA_Struct* curAA = zone->FindAA(aa[a]->AA - aa[a]->value + 1);
|
||||
if (curAA) {
|
||||
for (int rank = 0; rank<points; rank++) {
|
||||
std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(aa[a]->AA - aa[a]->value + 1 + rank);
|
||||
if (RequiredLevel != AARequiredLevelAndCost.end()) {
|
||||
spentpoints += RequiredLevel->second.Cost;
|
||||
}
|
||||
else
|
||||
spentpoints += (curAA->cost + (curAA->cost_inc * rank));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
|
||||
int highest = 0;
|
||||
for (int a = 0; a < MAX_PP_AA_ARRAY; a++) {
|
||||
if (aa[a]->AA > 0) { // those with value 0 will be cleaned up on next load
|
||||
if (first_entry != 1){
|
||||
rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value, charges)"
|
||||
" VALUES (%u, %u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value, aa[a]->charges);
|
||||
first_entry = 1;
|
||||
int i = 0;
|
||||
for(auto &rank : aa_ranks) {
|
||||
AA::Ability *ability = zone->GetAlternateAdvancementAbility(rank.first);
|
||||
if(!ability)
|
||||
continue;
|
||||
|
||||
if(rank.second.first > 0) {
|
||||
AA::Rank *r = ability->GetRankByPointsSpent(rank.second.first);
|
||||
|
||||
if(!r)
|
||||
continue;
|
||||
|
||||
spentpoints += r->total_cost;
|
||||
|
||||
if(i == 0) {
|
||||
iquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, aa_id, aa_value, charges)"
|
||||
" VALUES (%u, %u, %u, %u)", character_id, ability->first_rank_id, rank.second.first, rank.second.second);
|
||||
} else {
|
||||
rquery = rquery + StringFormat(", (%u, %u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value, aa[a]->charges);
|
||||
iquery += StringFormat(", (%u, %u, %u, %u)", character_id, ability->first_rank_id, rank.second.first, rank.second.second);
|
||||
}
|
||||
highest = a;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
|
||||
|
||||
if(iquery.length() > 0) {
|
||||
database.QueryDatabase(iquery);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -8041,56 +8031,6 @@ void Client::TryItemTimer(int slot)
|
||||
}
|
||||
}
|
||||
|
||||
void Client::RefundAA() {
|
||||
int cur = 0;
|
||||
bool refunded = false;
|
||||
|
||||
for(int x = 0; x < aaHighestID; x++) {
|
||||
cur = GetAA(x);
|
||||
if(cur > 0){
|
||||
SendAA_Struct* curaa = zone->FindAA(x);
|
||||
if(cur){
|
||||
SetAA(x, 0);
|
||||
for(int j = 0; j < cur; j++) {
|
||||
m_pp.aapoints += curaa->cost + (curaa->cost_inc * j);
|
||||
refunded = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pp.aapoints += cur;
|
||||
SetAA(x, 0);
|
||||
refunded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(refunded) {
|
||||
SaveAA();
|
||||
Save();
|
||||
// Kick();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::IncrementAA(int aa_id) {
|
||||
SendAA_Struct* aa2 = zone->FindAA(aa_id);
|
||||
|
||||
if(aa2 == nullptr)
|
||||
return;
|
||||
|
||||
if(GetAA(aa_id) == aa2->max_level)
|
||||
return;
|
||||
|
||||
SetAA(aa_id, GetAA(aa_id) + 1);
|
||||
|
||||
SaveAA();
|
||||
|
||||
SendAA(aa_id);
|
||||
SendAATable();
|
||||
SendAAStats();
|
||||
CalcBonuses();
|
||||
}
|
||||
|
||||
void Client::SendItemScale(ItemInst *inst) {
|
||||
int slot = m_inv.GetSlotByItemInst(inst);
|
||||
if(slot != -1) {
|
||||
@ -8651,4 +8591,4 @@ void Client::SendHPUpdateMarquee(){
|
||||
|
||||
std::string health_update_notification = StringFormat("Health: %u%%", health_percentage);
|
||||
this->SendMarqueeMessage(15, 510, 0, 3000, 3000, health_update_notification);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,6 @@ struct Item_Struct;
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/clientversions.h"
|
||||
|
||||
#include "aa.h"
|
||||
#include "common.h"
|
||||
#include "merc.h"
|
||||
#include "mob.h"
|
||||
@ -227,6 +226,7 @@ public:
|
||||
virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
virtual void SetAttackTimer();
|
||||
float GetQuiverHaste();
|
||||
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
||||
|
||||
void AI_Init();
|
||||
void AI_Start(uint32 iMoveDelay = 0);
|
||||
@ -541,7 +541,6 @@ public:
|
||||
|
||||
bool Flurry();
|
||||
bool Rampage();
|
||||
void DurationRampage(uint32 duration);
|
||||
|
||||
inline uint32 GetEXP() const { return m_pp.exp; }
|
||||
|
||||
@ -623,6 +622,7 @@ public:
|
||||
inline uint32 AccountID() const { return account_id; }
|
||||
|
||||
inline const char* AccountName()const { return account_name; }
|
||||
inline int GetAccountCreation() const { return account_creation; }
|
||||
inline int16 Admin() const { return admin; }
|
||||
inline uint32 CharacterID() const { return character_id; }
|
||||
void UpdateAdmin(bool iFromDB = true);
|
||||
@ -759,45 +759,35 @@ public:
|
||||
|
||||
inline PTimerList &GetPTimers() { return(p_timers); }
|
||||
|
||||
//AA Methods
|
||||
void SendAAList();
|
||||
void ResetAA();
|
||||
void SendClearAA();
|
||||
void SendAA(uint32 id, int seq=1);
|
||||
void SendPreviousAA(uint32 id, int seq=1);
|
||||
void BuyAA(AA_Action* action);
|
||||
//this function is used by some AA stuff
|
||||
void MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing);
|
||||
void SetAATitle(const char *Title);
|
||||
void SetTitleSuffix(const char *txt);
|
||||
inline uint32 GetMaxAAXP(void) const { return max_AAXP; }
|
||||
inline uint32 GetAAXP() const { return m_pp.expAA; }
|
||||
void SendAAStats();
|
||||
void SendAATable();
|
||||
void SendAATimers();
|
||||
int GetAATimerID(aaID activate);
|
||||
int CalcAAReuseTimer(const AA_DBAction *caa);
|
||||
void ActivateAA(aaID activate);
|
||||
void SendAATimer(uint32 ability, uint32 begin, uint32 end);
|
||||
void EnableAAEffect(aaEffectType type, uint32 duration = 0);
|
||||
void DisableAAEffect(aaEffectType type);
|
||||
bool CheckAAEffect(aaEffectType type);
|
||||
void HandleAAAction(aaID activate);
|
||||
uint32 GetAA(uint32 aa_id) const;
|
||||
bool SetAA(uint32 aa_id, uint32 new_value);
|
||||
inline uint32 GetAAPointsSpent() { return m_pp.aapoints_spent; }
|
||||
int16 CalcAAFocusEffect(focusType type, uint16 focus_spell, uint16 spell_id);
|
||||
int16 CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id);
|
||||
void SetAAPoints(uint32 points) { m_pp.aapoints = points; SendAAStats(); }
|
||||
void AddAAPoints(uint32 points) { m_pp.aapoints += points; SendAAStats(); }
|
||||
//New AA Methods
|
||||
void SendAlternateAdvancementRank(int aa_id, int level);
|
||||
void SendAlternateAdvancementTable();
|
||||
void SendAlternateAdvancementStats();
|
||||
void PurchaseAlternateAdvancementRank(int rank_id);
|
||||
bool GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost = false);
|
||||
void IncrementAlternateAdvancementRank(int rank_id);
|
||||
void ActivateAlternateAdvancementAbility(int rank_id, int target_id);
|
||||
void SendAlternateAdvancementPoints();
|
||||
void SendAlternateAdvancementTimer(int ability, int begin, int end);
|
||||
void SendAlternateAdvancementTimers();
|
||||
void ResetAlternateAdvancementTimer(int ability);
|
||||
void ResetAlternateAdvancementTimers();
|
||||
|
||||
void SetAAPoints(uint32 points) { m_pp.aapoints = points; SendAlternateAdvancementStats(); }
|
||||
void AddAAPoints(uint32 points) { m_pp.aapoints += points; SendAlternateAdvancementStats(); }
|
||||
int GetAAPoints() { return m_pp.aapoints; }
|
||||
int GetSpentAA() { return m_pp.aapoints_spent; }
|
||||
|
||||
//old AA methods that we still use
|
||||
void ResetAA();
|
||||
void RefundAA();
|
||||
void IncrementAA(int aa_id);
|
||||
int32 GetAAEffectDataBySlot(uint32 aa_ID, uint32 slot_id, bool GetEffect, bool GetBase1, bool GetBase2);
|
||||
int32 GetAAEffectid(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, true, false,false); }
|
||||
int32 GetAABase1(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, false, true,false); }
|
||||
int32 GetAABase2(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, false, false,true); }
|
||||
void SendClearAA();
|
||||
inline uint32 GetMaxAAXP(void) const { return max_AAXP; }
|
||||
inline uint32 GetAAXP() const { return m_pp.expAA; }
|
||||
int16 CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id);
|
||||
void SetAATitle(const char *Title);
|
||||
void SetTitleSuffix(const char *txt);
|
||||
void MemorizeSpell(uint32 slot, uint32 spellid, uint32 scribing);
|
||||
int32 acmod();
|
||||
|
||||
// Item methods
|
||||
@ -1271,8 +1261,6 @@ protected:
|
||||
void AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false);
|
||||
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
||||
void CalcEdibleBonuses(StatBonuses* newbon);
|
||||
void CalcAABonuses(StatBonuses* newbon);
|
||||
void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon);
|
||||
void ProcessItemCaps();
|
||||
void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true);
|
||||
bool client_data_loaded;
|
||||
@ -1280,6 +1268,8 @@ protected:
|
||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||
uint16 GetSympatheticFocusEffect(focusType type, uint16 spell_id);
|
||||
|
||||
void FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost);
|
||||
|
||||
Mob* bind_sight_target;
|
||||
|
||||
glm::vec4 m_AutoAttackPosition;
|
||||
@ -1497,11 +1487,7 @@ private:
|
||||
|
||||
uint32 tribute_master_id;
|
||||
|
||||
FILE *SQL_log;
|
||||
uint32 max_AAXP;
|
||||
uint32 staminacount;
|
||||
AA_Array* aa[MAX_PP_AA_ARRAY]; //this list contains pointers into our player profile
|
||||
std::map<uint32,uint8> aa_points;
|
||||
bool npcflag;
|
||||
uint8 npclevel;
|
||||
bool feigned;
|
||||
|
||||
@ -1121,7 +1121,7 @@ int32 Client::CalcMaxMana()
|
||||
switch (GetCasterClass()) {
|
||||
case 'I':
|
||||
case 'W': {
|
||||
max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
break;
|
||||
}
|
||||
case 'N': {
|
||||
@ -1978,7 +1978,18 @@ uint32 Mob::GetInstrumentMod(uint16 spell_id) const
|
||||
return 10;
|
||||
|
||||
uint32 effectmod = 10;
|
||||
int effectmodcap = RuleI(Character, BaseInstrumentSoftCap);
|
||||
int effectmodcap = 0;
|
||||
bool nocap = false;
|
||||
if (RuleB(Character, UseSpellFileSongCap)) {
|
||||
effectmodcap = spells[spell_id].songcap / 10;
|
||||
// this looks a bit weird, but easiest way I could think to keep both systems working
|
||||
if (effectmodcap == 0)
|
||||
nocap = true;
|
||||
else
|
||||
effectmodcap += 10;
|
||||
} else {
|
||||
effectmodcap = RuleI(Character, BaseInstrumentSoftCap);
|
||||
}
|
||||
// this should never use spell modifiers...
|
||||
// if a spell grants better modifers, they are copied into the item mods
|
||||
// because the spells are supposed to act just like having the intrument.
|
||||
@ -2048,10 +2059,11 @@ uint32 Mob::GetInstrumentMod(uint16 spell_id) const
|
||||
effectmod = 10;
|
||||
return effectmod;
|
||||
}
|
||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
||||
if (!RuleB(Character, UseSpellFileSongCap))
|
||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
||||
if (effectmod < 10)
|
||||
effectmod = 10;
|
||||
if (effectmod > effectmodcap)
|
||||
if (!nocap && effectmod > effectmodcap) // if the cap is calculated to be 0 using new rules, no cap.
|
||||
effectmod = effectmodcap;
|
||||
Log.Out(Logs::Detail, Logs::Spells, "%s::GetInstrumentMod() spell=%d mod=%d modcap=%d\n", GetName(), spell_id,
|
||||
effectmod, effectmodcap);
|
||||
|
||||
@ -389,6 +389,7 @@ void MapOpcodes()
|
||||
ConnectedOpcodes[OP_XTargetRequest] = &Client::Handle_OP_XTargetRequest;
|
||||
ConnectedOpcodes[OP_YellForHelp] = &Client::Handle_OP_YellForHelp;
|
||||
ConnectedOpcodes[OP_ZoneChange] = &Client::Handle_OP_ZoneChange;
|
||||
ConnectedOpcodes[OP_ResetAA] = &Client::Handle_OP_ResetAA;
|
||||
}
|
||||
|
||||
void ClearMappedOpcode(EmuOpcode op)
|
||||
@ -1082,7 +1083,7 @@ void Client::Handle_Connect_OP_ReqNewZone(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app)
|
||||
{
|
||||
SendAATimers();
|
||||
SendAlternateAdvancementTimers();
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SendAAStats, 0);
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
@ -1091,7 +1092,7 @@ void Client::Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_Connect_OP_SendAATable(const EQApplicationPacket *app)
|
||||
{
|
||||
SendAAList();
|
||||
SendAlternateAdvancementTable();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1152,7 +1153,7 @@ void Client::Handle_Connect_OP_TGB(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app)
|
||||
{
|
||||
SendAATable();
|
||||
SendAlternateAdvancementPoints();
|
||||
}
|
||||
|
||||
void Client::Handle_Connect_OP_WearChange(const EQApplicationPacket *app)
|
||||
@ -1439,58 +1440,15 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
if (m_pp.ldon_points_tak < 0 || m_pp.ldon_points_tak > 2000000000){ m_pp.ldon_points_tak = 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 */
|
||||
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++)
|
||||
aa[a] = &m_pp.aa_array[a];
|
||||
query = StringFormat(
|
||||
"SELECT "
|
||||
"slot, "
|
||||
"aa_id, "
|
||||
"aa_value, "
|
||||
"charges "
|
||||
"FROM "
|
||||
"`character_alternate_abilities` "
|
||||
"WHERE `id` = %u ORDER BY `slot`", this->CharacterID());
|
||||
results = database.QueryDatabase(query); i = 0;
|
||||
int offset = 0; // offset to fix the hole from expendables
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
i = atoi(row[0]) - offset;
|
||||
m_pp.aa_array[i].AA = atoi(row[1]);
|
||||
m_pp.aa_array[i].value = atoi(row[2]);
|
||||
m_pp.aa_array[i].charges = atoi(row[3]);
|
||||
/* A used expendable could cause there to be a "hole" in the array, this is very bad. Bad things like keeping your expendable after use.
|
||||
We could do a few things, one of them being reshuffling when the hole is created or defer the fixing until a later point, like during load!
|
||||
Or just never making a hole in the array and just have hacks every where. Fixing the hole at load really just keeps 1 hack in Client::SendAATable
|
||||
and keeping this offset that will cause the next AA to be pushed back over the hole. We also need to clean up on save so we don't have multiple
|
||||
entries for a single AA.
|
||||
*/
|
||||
if (m_pp.aa_array[i].value == 0)
|
||||
offset++;
|
||||
if(RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
m_pp.expansions = ExpansionFromClientVersion(GetClientVersion());
|
||||
}
|
||||
else {
|
||||
m_pp.expansions = RuleI(World, ExpansionSettings);
|
||||
}
|
||||
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++){
|
||||
uint32 id = aa[a]->AA;
|
||||
//watch for invalid AA IDs
|
||||
if (id == aaNone)
|
||||
continue;
|
||||
if (id >= aaHighestID) {
|
||||
aa[a]->AA = aaNone;
|
||||
aa[a]->value = 0;
|
||||
continue;
|
||||
}
|
||||
if (aa[a]->value == 0) {
|
||||
aa[a]->AA = aaNone;
|
||||
continue;
|
||||
}
|
||||
if (aa[a]->value > HIGHEST_AA_VALUE) {
|
||||
aa[a]->AA = aaNone;
|
||||
aa[a]->value = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aa[a]->value > 1) /* hack in some stuff for sony's new AA method (where each level of each aa.has a seperate ID) */
|
||||
aa_points[(id - aa[a]->value + 1)] = aa[a]->value;
|
||||
else
|
||||
aa_points[id] = aa[a]->value;
|
||||
if(!database.LoadAlternateAdvancement(this)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error loading AA points for %s", GetName());
|
||||
}
|
||||
|
||||
if (SPDAT_RECORDS > 0) {
|
||||
@ -1615,11 +1573,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
/* Update LFP in case any (or all) of our group disbanded while we were zoning. */
|
||||
if (IsLFP()) { UpdateLFP(); }
|
||||
|
||||
/* Get Expansions from variables table and ship via PP */
|
||||
char val[20] = { 0 };
|
||||
if (database.GetVariable("Expansions", val, 20)){ m_pp.expansions = atoi(val); }
|
||||
else{ m_pp.expansions = 0x3FF; }
|
||||
|
||||
p_timers.SetCharID(CharacterID());
|
||||
if (!p_timers.Load(&database)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to load ability timers from the database for %s (%i)!", GetCleanName(), CharacterID());
|
||||
@ -1794,38 +1747,39 @@ void Client::Handle_OP_AAAction(const EQApplicationPacket *app)
|
||||
Log.Out(Logs::Detail, Logs::AA, "Received OP_AAAction");
|
||||
|
||||
if (app->size != sizeof(AA_Action)){
|
||||
printf("Error! OP_AAAction size didnt match!\n");
|
||||
Log.Out(Logs::General, Logs::AA, "Error! OP_AAAction size didnt match!");
|
||||
return;
|
||||
}
|
||||
AA_Action* action = (AA_Action*)app->pBuffer;
|
||||
|
||||
if (action->action == aaActionActivate) {//AA Hotkey
|
||||
Log.Out(Logs::Detail, Logs::AA, "Activating AA %d", action->ability);
|
||||
ActivateAA((aaID)action->ability);
|
||||
ActivateAlternateAdvancementAbility(action->ability, action->target_id);
|
||||
}
|
||||
else if (action->action == aaActionBuy) {
|
||||
BuyAA(action);
|
||||
PurchaseAlternateAdvancementRank(action->ability);
|
||||
}
|
||||
else if (action->action == aaActionDisableEXP){ //Turn Off AA Exp
|
||||
if (m_epp.perAA > 0)
|
||||
Message_StringID(0, AA_OFF);
|
||||
|
||||
m_epp.perAA = 0;
|
||||
SendAAStats();
|
||||
SendAlternateAdvancementStats();
|
||||
}
|
||||
else if (action->action == aaActionSetEXP) {
|
||||
if (m_epp.perAA == 0)
|
||||
Message_StringID(0, AA_ON);
|
||||
m_epp.perAA = action->exp_value;
|
||||
if (m_epp.perAA<0 || m_epp.perAA>100) m_epp.perAA = 0; // stop exploit with sanity check
|
||||
if (m_epp.perAA < 0 || m_epp.perAA > 100)
|
||||
m_epp.perAA = 0; // stop exploit with sanity check
|
||||
|
||||
// send an update
|
||||
SendAAStats();
|
||||
SendAATable();
|
||||
SendAlternateAdvancementStats();
|
||||
SendAlternateAdvancementTable();
|
||||
}
|
||||
else {
|
||||
printf("Unknown AA action: %u %u 0x%x %d\n", action->action, action->ability, action->unknown08, action->exp_value);
|
||||
Log.Out(Logs::General, Logs::AA, "Unknown AA action : %u %u %u %d", action->action, action->ability, action->target_id, action->exp_value);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Client::Handle_OP_AcceptNewTask(const EQApplicationPacket *app)
|
||||
@ -3898,8 +3852,6 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
m_TargetRing = glm::vec3(castspell->x_pos, castspell->y_pos, castspell->z_pos);
|
||||
|
||||
CastSpell(spell_to_cast, castspell->target_id, castspell->slot);
|
||||
}
|
||||
/* Spell Slot or Potion Belt Slot */
|
||||
@ -8852,7 +8804,7 @@ void Client::Handle_OP_LFGuild(const EQApplicationPacket *app)
|
||||
pack->WriteUInt32(QSG_LFGuild_UpdatePlayerInfo);
|
||||
pack->WriteUInt32(GetBaseClass());
|
||||
pack->WriteUInt32(GetLevel());
|
||||
pack->WriteUInt32(GetAAPointsSpent());
|
||||
pack->WriteUInt32(GetSpentAA());
|
||||
pack->WriteString(pts->Comment);
|
||||
pack->WriteUInt32(pts->Toggle);
|
||||
pack->WriteUInt32(pts->TimeZone);
|
||||
@ -14228,9 +14180,12 @@ void Client::Handle_OP_YellForHelp(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app)
|
||||
void Client::Handle_OP_ResetAA(const EQApplicationPacket *app)
|
||||
{
|
||||
if(Admin() >= 50) {
|
||||
Message(0, "Resetting AA points.");
|
||||
ResetAA();
|
||||
}
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@ -295,3 +295,4 @@
|
||||
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_YellForHelp(const EQApplicationPacket *app);
|
||||
void Handle_OP_ZoneChange(const EQApplicationPacket *app);
|
||||
void Handle_OP_ResetAA(const EQApplicationPacket *app);
|
||||
|
||||
@ -391,73 +391,12 @@ bool Client::Process() {
|
||||
}
|
||||
else if (auto_attack_target->GetHP() > -10) // -10 so we can watch people bleed in PvP
|
||||
{
|
||||
if(CheckAAEffect(aaEffectRampage))
|
||||
{
|
||||
entity_list.AEAttack(this, 30);
|
||||
} else {
|
||||
Attack(auto_attack_target, MainPrimary); // Kaiyodo - added attacking hand to arguments
|
||||
}
|
||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
||||
TryWeaponProc(wpn, auto_attack_target, MainPrimary);
|
||||
|
||||
bool tripleAttackSuccess = false;
|
||||
if( auto_attack_target && CanThisClassDoubleAttack() ) {
|
||||
|
||||
CheckIncreaseSkill(SkillDoubleAttack, auto_attack_target, -10);
|
||||
if(CheckDoubleAttack()) {
|
||||
//should we allow rampage on double attack?
|
||||
if(CheckAAEffect(aaEffectRampage)) {
|
||||
entity_list.AEAttack(this, 30);
|
||||
} else {
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
|
||||
//triple attack: rangers, monks, warriors, berserkers over level 60
|
||||
if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
|
||||
&& GetLevel() >= 60) || GetSpecialAbility(SPECATK_TRIPLE))
|
||||
&& CheckDoubleAttack(true))
|
||||
{
|
||||
tripleAttackSuccess = true;
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
|
||||
//quad attack, does this belong here??
|
||||
if(GetSpecialAbility(SPECATK_QUAD) && CheckDoubleAttack(true))
|
||||
{
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
|
||||
//Live AA - Flurry, Rapid Strikes ect (Flurry does not require Triple Attack).
|
||||
int16 flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
||||
|
||||
if (auto_attack_target && flurrychance)
|
||||
{
|
||||
if(zone->random.Int(0, 99) < flurrychance)
|
||||
{
|
||||
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
|
||||
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
|
||||
|
||||
if (auto_attack_target && ExtraAttackChanceBonus) {
|
||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
||||
if(wpn){
|
||||
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
|
||||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
||||
wpn->GetItem()->ItemType == ItemType2HPiercing )
|
||||
{
|
||||
if(zone->random.Int(0, 99) < ExtraAttackChanceBonus)
|
||||
{
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DoAttackRounds(auto_attack_target, MainPrimary);
|
||||
if (CheckAATimer(aaTimerRampage))
|
||||
entity_list.AEAttack(this, 30);
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,23 +437,11 @@ bool Client::Process() {
|
||||
|
||||
float random = zone->random.Real(0, 1);
|
||||
CheckIncreaseSkill(SkillDualWield, auto_attack_target, -10);
|
||||
if (random < DualWieldProbability){ // Max 78% of DW
|
||||
if(CheckAAEffect(aaEffectRampage)) {
|
||||
entity_list.AEAttack(this, 30, MainSecondary);
|
||||
} else {
|
||||
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
|
||||
}
|
||||
if (random < DualWieldProbability) { // Max 78% of DW
|
||||
ItemInst *wpn = GetInv().GetItem(MainSecondary);
|
||||
TryWeaponProc(wpn, auto_attack_target, MainSecondary);
|
||||
|
||||
if( CanThisClassDoubleAttack() && CheckDoubleAttack()) {
|
||||
if(CheckAAEffect(aaEffectRampage)) {
|
||||
entity_list.AEAttack(this, 30, MainSecondary);
|
||||
} else {
|
||||
if(auto_attack_target && auto_attack_target->GetHP() > -10)
|
||||
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
|
||||
}
|
||||
}
|
||||
DoAttackRounds(auto_attack_target, MainSecondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
143
zone/command.cpp
143
zone/command.cpp
@ -167,7 +167,6 @@ int command_init(void) {
|
||||
command_add("aggro", "(range) [-v] - Display aggro information for all mobs 'range' distance from your target. -v is verbose faction info.", 80, command_aggro) ||
|
||||
command_add("aggrozone", "[aggro] - Aggro every mob in the zone with X aggro. Default is 0. Not recommend if you're not invulnerable.", 100, command_aggrozone) ||
|
||||
command_add("ai", "[factionid/spellslist/con/guard/roambox/stop/start] - Modify AI on NPC target", 100, command_ai) ||
|
||||
command_add("altactivate", "[argument] - activates alternate advancement abilities, use altactivate help for more information", 0, command_altactivate) ||
|
||||
command_add("appearance", "[type] [value] - Send an appearance packet for you or your target", 150, command_appearance) ||
|
||||
command_add("attack", "[targetname] - Make your NPC target attack targetname", 150, command_attack) ||
|
||||
command_add("augmentitem", "Force augments an item. Must have the augment item window open.", 250, command_augmentitem) ||
|
||||
@ -273,7 +272,6 @@ int command_init(void) {
|
||||
command_add("los", nullptr,0, command_checklos) ||
|
||||
command_add("makepet", "[level] [class] [race] [texture] - Make a pet", 50, command_makepet) ||
|
||||
command_add("mana", "- Fill your or your target's mana", 50, command_mana) ||
|
||||
command_add("manaburn", "- Use AA Wizard class skill manaburn on target", 10, command_manaburn) ||
|
||||
command_add("maxskills", "Maxes skills for you.", 200, command_max_all_skills) ||
|
||||
command_add("memspell", "[slotid] [spellid] - Memorize spellid in the specified slot", 50, command_memspell) ||
|
||||
command_add("merchant_close_shop", "Closes a merchant shop", 100, command_merchantcloseshop) ||
|
||||
@ -322,6 +320,7 @@ int command_init(void) {
|
||||
command_add("raidloot", "LEADER|GROUPLEADER|SELECTED|ALL - Sets your raid loot settings if you have permission to do so.", 0, command_raidloot) ||
|
||||
command_add("randomfeatures", "- Temporarily randomizes the Facial Features of your target", 80, command_randomfeatures) ||
|
||||
command_add("refreshgroup", "- Refreshes Group.", 0, command_refreshgroup) ||
|
||||
command_add("reloadaa", "Reloads AA data", 200, command_reloadaa) ||
|
||||
command_add("reloadallrules", "Executes a reload of all rules.", 80, command_reloadallrules) ||
|
||||
command_add("reloademote", "Reloads NPC Emotes", 80, command_reloademote) ||
|
||||
command_add("reloadlevelmods", nullptr,255, command_reloadlevelmods) ||
|
||||
@ -334,7 +333,8 @@ int command_init(void) {
|
||||
command_add("reloadzonepoints", "- Reload zone points from database", 150, command_reloadzps) ||
|
||||
command_add("reloadzps", nullptr,0, command_reloadzps) ||
|
||||
command_add("repop", "[delay] - Repop the zone with optional delay", 100, command_repop) ||
|
||||
command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, disconnects player.", 200, command_resetaa) ||
|
||||
command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", 200, command_resetaa) ||
|
||||
command_add("resetaa_timer", "Command to reset AA cooldown timers.", 200, command_resetaa_timer) ||
|
||||
command_add("revoke", "[charname] [1/0] - Makes charname unable to talk on OOC", 200, command_revoke) ||
|
||||
command_add("rules", "(subcommand) - Manage server rules", 250, command_rules) ||
|
||||
command_add("save", "- Force your player or player corpse target to be saved to the database", 50, command_save) ||
|
||||
@ -673,8 +673,8 @@ void command_incstat(Client* c, const Seperator* sep){
|
||||
}
|
||||
}
|
||||
|
||||
void command_resetaa(Client* c,const Seperator *sep){
|
||||
if(c->GetTarget()!=0 && c->GetTarget()->IsClient()){
|
||||
void command_resetaa(Client* c,const Seperator *sep) {
|
||||
if(c->GetTarget() && c->GetTarget()->IsClient()){
|
||||
c->GetTarget()->CastToClient()->ResetAA();
|
||||
c->Message(13,"Successfully reset %s's AAs", c->GetTarget()->GetName());
|
||||
}
|
||||
@ -4840,36 +4840,6 @@ void command_zonestatus(Client *c, const Seperator *sep)
|
||||
}
|
||||
}
|
||||
|
||||
void command_manaburn(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob* target=c->GetTarget();
|
||||
|
||||
if (c->GetTarget() == 0)
|
||||
c->Message(0, "#Manaburn needs a target.");
|
||||
else {
|
||||
int cur_level=c->GetAA(MANA_BURN);//ManaBurn ID
|
||||
if (DistanceSquared(c->GetPosition(), target->GetPosition()) > 200)
|
||||
c->Message(0,"You are too far away from your target.");
|
||||
else {
|
||||
if(cur_level == 1) {
|
||||
if(c->IsAttackAllowed(target))
|
||||
{
|
||||
c->SetMana(0);
|
||||
int nukedmg=(c->GetMana())*2;
|
||||
if (nukedmg>0)
|
||||
{
|
||||
target->Damage(c, nukedmg, 2751, SkillAbjuration/*hackish*/);
|
||||
c->Message(4,"You unleash an enormous blast of magical energies.");
|
||||
}
|
||||
Log.Out(Logs::General, Logs::Normal, "Manaburn request from %s, damage: %d", c->GetName(), nukedmg);
|
||||
}
|
||||
}
|
||||
else
|
||||
c->Message(0, "You have not learned this skill.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void command_doanim(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!sep->IsNumber(1))
|
||||
@ -5584,16 +5554,23 @@ void command_setaapts(Client *c, const Seperator *sep)
|
||||
|
||||
if(sep->arg[1][0] == '\0' || sep->arg[2][0] == '\0')
|
||||
c->Message(0, "Usage: #setaapts <AA|group|raid> <new AA points value>");
|
||||
else if(atoi(sep->arg[2]) <= 0 || atoi(sep->arg[2]) > 200)
|
||||
c->Message(0, "You must have a number greater than 0 for points and no more than 200.");
|
||||
else if(atoi(sep->arg[2]) <= 0 || atoi(sep->arg[2]) > 5000)
|
||||
c->Message(0, "You must have a number greater than 0 for points and no more than 5000.");
|
||||
else if(!strcasecmp(sep->arg[1], "group")) {
|
||||
t->SetLeadershipEXP(atoi(sep->arg[2])*GROUP_EXP_PER_POINT, t->GetRaidEXP());
|
||||
t->GetPP().group_leadership_points = atoi(sep->arg[2]);
|
||||
t->GetPP().group_leadership_exp = 0;
|
||||
t->Message(MT_Experience, "Setting Group AA points to %u", t->GetPP().group_leadership_points);
|
||||
t->SendLeadershipEXPUpdate();
|
||||
} else if(!strcasecmp(sep->arg[1], "raid")) {
|
||||
t->SetLeadershipEXP(t->GetGroupEXP(), atoi(sep->arg[2])*RAID_EXP_PER_POINT);
|
||||
t->GetPP().raid_leadership_points = atoi(sep->arg[2]);
|
||||
t->GetPP().raid_leadership_exp = 0;
|
||||
t->Message(MT_Experience, "Setting Raid AA points to %u", t->GetPP().raid_leadership_points);
|
||||
t->SendLeadershipEXPUpdate();
|
||||
} else {
|
||||
t->SetEXP(t->GetEXP(),t->GetMaxAAXP()*atoi(sep->arg[2]),false);
|
||||
t->SendAAStats();
|
||||
t->SendAATable();
|
||||
t->GetPP().aapoints = atoi(sep->arg[2]);
|
||||
t->GetPP().expAA = 0;
|
||||
t->Message(MT_Experience, "Setting personal AA points to %u", t->GetPP().aapoints);
|
||||
t->SendAlternateAdvancementStats();
|
||||
}
|
||||
}
|
||||
|
||||
@ -7676,56 +7653,6 @@ void command_reloadtitles(Client *c, const Seperator *sep)
|
||||
|
||||
}
|
||||
|
||||
void command_altactivate(Client *c, const Seperator *sep){
|
||||
if(sep->arg[1][0] == '\0'){
|
||||
c->Message(10, "Invalid argument, usage:");
|
||||
c->Message(10, "#altactivate list - lists the AA ID numbers that are available to you");
|
||||
c->Message(10, "#altactivate time [argument] - returns the time left until you can use the AA with the ID that matches the argument.");
|
||||
c->Message(10, "#altactivate [argument] - activates the AA with the ID that matches the argument.");
|
||||
return;
|
||||
}
|
||||
if(!strcasecmp(sep->arg[1], "help")){
|
||||
c->Message(10, "Usage:");
|
||||
c->Message(10, "#altactivate list - lists the AA ID numbers that are available to you");
|
||||
c->Message(10, "#altactivate time [argument] - returns the time left until you can use the AA with the ID that matches the argument.");
|
||||
c->Message(10, "#altactivate [argument] - activates the AA with the ID that matches the argument.");
|
||||
return;
|
||||
}
|
||||
if(!strcasecmp(sep->arg[1], "list")){
|
||||
c->Message(10, "You have access to the following AA Abilities:");
|
||||
int x, val;
|
||||
SendAA_Struct* saa = nullptr;
|
||||
for(x = 0; x < aaHighestID; x++){
|
||||
if(AA_Actions[x][0].spell_id || AA_Actions[x][0].action){ //if there's an action or spell associated we assume it's a valid
|
||||
val = 0; //and assume if they don't have a value for the first rank then it isn't valid for any rank
|
||||
saa = nullptr;
|
||||
val = c->GetAA(x);
|
||||
if(val){
|
||||
saa = zone->FindAA(x);
|
||||
c->Message(10, "%d: %s %d", x, saa->name, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!strcasecmp(sep->arg[1], "time")){
|
||||
int ability = atoi(sep->arg[2]);
|
||||
if(c->GetAA(ability)){
|
||||
int remain = c->GetPTimers().GetRemainingTime(pTimerAAStart + ability);
|
||||
if(remain)
|
||||
c->Message(10, "You may use that ability in %d minutes and %d seconds.", (remain/60), (remain%60));
|
||||
else
|
||||
c->Message(10, "You may use that ability now.");
|
||||
}
|
||||
else{
|
||||
c->Message(10, "You do not have access to that ability.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c->ActivateAA((aaID) atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
void command_traindisc(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint8 max_level, min_level;
|
||||
@ -10655,3 +10582,35 @@ void command_mysqltest(Client *c, const Seperator *sep)
|
||||
}
|
||||
Log.Out(Logs::General, Logs::Debug, "MySQL Test... Took %f seconds", ((float)(std::clock() - t)) / CLOCKS_PER_SEC);
|
||||
}
|
||||
|
||||
void command_resetaa_timer(Client *c, const Seperator *sep) {
|
||||
Client *target = nullptr;
|
||||
if(!c->GetTarget() || !c->GetTarget()->IsClient()) {
|
||||
target = c;
|
||||
} else {
|
||||
target = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
if(sep->IsNumber(1))
|
||||
{
|
||||
int timer_id = atoi(sep->arg[1]);
|
||||
c->Message(0, "Reset of timer %i for %s", timer_id, c->GetName());
|
||||
c->ResetAlternateAdvancementTimer(timer_id);
|
||||
}
|
||||
else if(!strcasecmp(sep->arg[1], "all"))
|
||||
{
|
||||
c->Message(0, "Reset all timers for %s", c->GetName());
|
||||
c->ResetAlternateAdvancementTimers();
|
||||
}
|
||||
else
|
||||
{
|
||||
c->Message(0, "usage: #resetaa_timer [all | timer_id]");
|
||||
}
|
||||
}
|
||||
|
||||
void command_reloadaa(Client *c, const Seperator *sep) {
|
||||
c->Message(0, "Reloading Alternate Advancement Data...");
|
||||
zone->LoadAlternateAdvancement();
|
||||
c->Message(0, "Alternate Advancement Data Reloaded");
|
||||
entity_list.SendAlternateAdvancementStats();
|
||||
}
|
||||
|
||||
@ -216,7 +216,6 @@ void command_time(Client *c, const Seperator *sep);
|
||||
void command_guild(Client *c, const Seperator *sep);
|
||||
bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const char* what, const char* value);
|
||||
void command_zonestatus(Client *c, const Seperator *sep);
|
||||
void command_manaburn(Client *c, const Seperator *sep);
|
||||
void command_doanim(Client *c, const Seperator *sep);
|
||||
void command_randomfeatures(Client *c, const Seperator *sep);
|
||||
void command_face(Client *c, const Seperator *sep);
|
||||
@ -276,7 +275,6 @@ void command_guildlist(Client *c, const Seperator *sep);
|
||||
void command_rules(Client *c, const Seperator *sep);
|
||||
void command_task(Client *c, const Seperator *sep);
|
||||
void command_reloadtitles(Client *c, const Seperator *sep);
|
||||
void command_altactivate(Client *c, const Seperator *sep);
|
||||
void command_refundaa(Client *c, const Seperator *sep);
|
||||
void command_traindisc(Client *c, const Seperator *sep);
|
||||
void command_deletegraveyard(Client *c, const Seperator *sep);
|
||||
@ -325,7 +323,9 @@ void command_tune(Client *c, const Seperator *sep);
|
||||
void command_logtest(Client *c, const Seperator *sep);
|
||||
void command_mysqltest(Client *c, const Seperator *sep);
|
||||
void command_logs(Client *c, const Seperator *sep);
|
||||
|
||||
void command_resetaa_timer(Client *c, const Seperator *sep);
|
||||
void command_reloadaa(Client *c, const Seperator *sep);
|
||||
|
||||
#ifdef EQPROFILE
|
||||
void command_profiledump(Client *c, const Seperator *sep);
|
||||
void command_profilereset(Client *c, const Seperator *sep);
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#define TARGET_RING_SPELL_SLOT 12
|
||||
#define DISCIPLINE_SPELL_SLOT 10
|
||||
#define ABILITY_SPELL_SLOT 9
|
||||
#define ALTERNATE_ABILITY_SPELL_SLOT 0xFF
|
||||
|
||||
//LOS Parameters:
|
||||
#define HEAD_POSITION 0.9f //ratio of GetSize() where NPCs see from
|
||||
@ -400,7 +401,6 @@ struct StatBonuses {
|
||||
int32 Metabolism; // Food/drink consumption rates.
|
||||
bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others.
|
||||
int32 FactionModPct; // Modifies amount of faction gained.
|
||||
int32 MeleeVulnerability; // Weakness/mitigation to melee damage
|
||||
bool LimitToSkill[HIGHEST_SKILL+2]; // Determines if we need to search for a skill proc.
|
||||
uint32 SkillProc[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs.
|
||||
uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
||||
@ -412,7 +412,7 @@ struct StatBonuses {
|
||||
int8 BaseMovementSpeed; // Adjust base run speed, does not stack with other movement bonuses.
|
||||
uint8 IncreaseRunSpeedCap; // Increase max run speed above cap.
|
||||
int32 DoubleSpecialAttack; // Chance to to perform a double special attack (ie flying kick 2x)
|
||||
int32 SpecialAttackKBProc[2]; // Chance to to do a knockback from special attacks. (0 = chance 1 = Skill)
|
||||
int32 SkillAttackProc[3]; // [0] chance to proc [2] spell on [1] skill usage
|
||||
uint8 FrontalStunResist; // Chance to resist a frontal stun
|
||||
int32 BindWound; // Increase amount of HP by percent.
|
||||
int32 MaxBindWound; // Increase max amount of HP you can bind wound.
|
||||
@ -461,6 +461,7 @@ struct StatBonuses {
|
||||
uint8 AssassinateLevel; // Max Level Assassinate will be effective at.
|
||||
int32 PetMeleeMitigation; // Add AC to owner's pet.
|
||||
bool IllusionPersistence; // Causes illusions not to fade.
|
||||
uint16 extra_xtargets; // extra xtarget entries
|
||||
};
|
||||
|
||||
typedef struct
|
||||
|
||||
@ -421,12 +421,6 @@ int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
||||
int tic_inc = 0;
|
||||
tic_inc = GetFocusEffect(focusSpellDurByTic, spell_id);
|
||||
|
||||
// unsure on the exact details, but bard songs that don't cost mana at some point get an extra tick, 60 for now
|
||||
// a level 53 bard reported getting 2 tics
|
||||
// bard DOTs do get this extra tick, but beneficial long bard songs don't? (invul, crescendo)
|
||||
if ((IsShortDurationBuff(spell_id) || IsDetrimentalSpell(spell_id)) && IsBardSong(spell_id) &&
|
||||
spells[spell_id].mana == 0 && GetClass() == BARD && GetLevel() > 60)
|
||||
tic_inc++;
|
||||
float focused = ((duration * increase) / 100.0f) + tic_inc;
|
||||
int ifocused = static_cast<int>(focused);
|
||||
|
||||
@ -878,7 +872,7 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
|
||||
caster->CastToClient()->CheckSongSkillIncrease(spell_id);
|
||||
}
|
||||
|
||||
//Dook- Rampage and stuff for clients.
|
||||
// Rampage and stuff for clients. Normal and Duration rampages
|
||||
//NPCs handle it differently in Mob::Rampage
|
||||
void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool IsFromSpell) {
|
||||
//Dook- Will need tweaking, currently no pets or players or horses
|
||||
@ -896,7 +890,10 @@ void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool I
|
||||
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
|
||||
&& (DistanceSquared(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
|
||||
) {
|
||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||
if (!attacker->IsClient() || attacker->GetClass() == MONK || attacker->GetClass() == RANGER)
|
||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||
else
|
||||
attacker->CastToClient()->DoAttackRounds(curmob, Hand, IsFromSpell);
|
||||
hit++;
|
||||
if (count != 0 && hit >= count)
|
||||
return;
|
||||
|
||||
@ -58,7 +58,6 @@ extern uint32 numclients;
|
||||
extern PetitionList petition_list;
|
||||
|
||||
extern char errorname[32];
|
||||
extern uint16 adverrornum;
|
||||
|
||||
Entity::Entity()
|
||||
{
|
||||
@ -4705,3 +4704,11 @@ void EntityList::StopMobAI()
|
||||
mob.second->AI_ShutDown();
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::SendAlternateAdvancementStats() {
|
||||
for(auto &c : client_list) {
|
||||
c.second->SendAlternateAdvancementTable();
|
||||
c.second->SendAlternateAdvancementStats();
|
||||
c.second->SendAlternateAdvancementPoints();
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,7 +398,6 @@ public:
|
||||
|
||||
void SaveAllClientsTaskState();
|
||||
void ReloadAllClientsTaskState(int TaskID=0);
|
||||
|
||||
uint16 CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time = 300000);
|
||||
uint16 CreateGroundObjectFromModel(const char *model, const glm::vec4& position, uint8 type = 0x00, uint32 decay_time = 0);
|
||||
uint16 CreateDoor(const char *model, const glm::vec4& position, uint8 type = 0, uint16 size = 100);
|
||||
@ -429,6 +428,7 @@ public:
|
||||
uint16 GetFreeID();
|
||||
void RefreshAutoXTargets(Client *c);
|
||||
void RefreshClientXTargets(Client *c);
|
||||
void SendAlternateAdvancementStats();
|
||||
|
||||
protected:
|
||||
friend class Zone;
|
||||
|
||||
@ -515,7 +515,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
if (GetLevel() < 51) {
|
||||
m_epp.perAA = 0; // turn off aa exp if they drop below 51
|
||||
} else
|
||||
SendAAStats(); //otherwise, send them an AA update
|
||||
SendAlternateAdvancementStats(); //otherwise, send them an AA update
|
||||
|
||||
//send the expdata in any case so the xp bar isnt stuck after leveling
|
||||
uint32 tmpxp1 = GetEXPForLevel(GetLevel()+1);
|
||||
|
||||
@ -350,6 +350,11 @@ const char *Lua_Client::AccountName() {
|
||||
return self->AccountName();
|
||||
}
|
||||
|
||||
int Lua_Client::GetAccountAge() {
|
||||
Lua_Safe_Call_Int();
|
||||
return time(nullptr) - self->GetAccountCreation();
|
||||
}
|
||||
|
||||
int Lua_Client::Admin() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->Admin();
|
||||
@ -1024,7 +1029,17 @@ void Lua_Client::AddLevelBasedExp(int exp_pct, int max_level) {
|
||||
|
||||
void Lua_Client::IncrementAA(int aa) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->IncrementAA(aa);
|
||||
self->IncrementAlternateAdvancementRank(aa);
|
||||
}
|
||||
|
||||
bool Lua_Client::GrantAlternateAdvancementAbility(int aa_id, int points) {
|
||||
Lua_Safe_Call_Bool();
|
||||
self->GrantAlternateAdvancementAbility(aa_id, points);
|
||||
}
|
||||
|
||||
bool Lua_Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost) {
|
||||
Lua_Safe_Call_Bool();
|
||||
self->GrantAlternateAdvancementAbility(aa_id, points, ignore_cost);
|
||||
}
|
||||
|
||||
void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z) {
|
||||
@ -1365,6 +1380,7 @@ luabind::scope lua_register_client() {
|
||||
.def("GetRawItemAC", (int(Lua_Client::*)(void))&Lua_Client::GetRawItemAC)
|
||||
.def("AccountID", (uint32(Lua_Client::*)(void))&Lua_Client::AccountID)
|
||||
.def("AccountName", (const char *(Lua_Client::*)(void))&Lua_Client::AccountName)
|
||||
.def("GetAccountAge", (int(Lua_Client::*)(void))&Lua_Client::GetAccountAge)
|
||||
.def("Admin", (int(Lua_Client::*)(void))&Lua_Client::Admin)
|
||||
.def("CharacterID", (uint32(Lua_Client::*)(void))&Lua_Client::CharacterID)
|
||||
.def("GuildRank", (int(Lua_Client::*)(void))&Lua_Client::GuildRank)
|
||||
@ -1500,6 +1516,8 @@ luabind::scope lua_register_client() {
|
||||
.def("AddLevelBasedExp", (void(Lua_Client::*)(int))&Lua_Client::AddLevelBasedExp)
|
||||
.def("AddLevelBasedExp", (void(Lua_Client::*)(int,int))&Lua_Client::AddLevelBasedExp)
|
||||
.def("IncrementAA", (void(Lua_Client::*)(int))&Lua_Client::IncrementAA)
|
||||
.def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int))&Lua_Client::GrantAlternateAdvancementAbility)
|
||||
.def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int, bool))&Lua_Client::GrantAlternateAdvancementAbility)
|
||||
.def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float))&Lua_Client::MarkSingleCompassLoc)
|
||||
.def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float,int))&Lua_Client::MarkSingleCompassLoc)
|
||||
.def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(void))&Lua_Client::GetNextAvailableSpellBookSlot)
|
||||
|
||||
@ -166,9 +166,9 @@ public:
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
bool attuned);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
bool attuned, int to_slot);
|
||||
void SetStats(int type, int value);
|
||||
void IncStats(int type, int value);
|
||||
@ -233,6 +233,8 @@ public:
|
||||
void AddLevelBasedExp(int exp_pct);
|
||||
void AddLevelBasedExp(int exp_pct, int max_level);
|
||||
void IncrementAA(int aa);
|
||||
bool GrantAlternateAdvancementAbility(int aa_id, int points);
|
||||
bool GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost);
|
||||
void MarkSingleCompassLoc(float in_x, float in_y, float in_z);
|
||||
void MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count);
|
||||
int GetNextAvailableSpellBookSlot();
|
||||
@ -260,6 +262,7 @@ public:
|
||||
bool HasSpellScribed(int spell_id);
|
||||
void SetAccountFlag(std::string flag, std::string val);
|
||||
std::string GetAccountFlag(std::string flag);
|
||||
int GetAccountAge();
|
||||
Lua_Group GetGroup();
|
||||
Lua_Raid GetRaid();
|
||||
bool PutItemInInventory(int slot_id, Lua_ItemInst inst);
|
||||
|
||||
@ -790,7 +790,7 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, in
|
||||
int16 res = resist_adjust;
|
||||
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
static_cast<uint32>(timer), static_cast<uint32>(timer_duration), 0, &res);
|
||||
static_cast<uint32>(timer), static_cast<uint32>(timer_duration), &res);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target) {
|
||||
@ -1195,6 +1195,21 @@ int Lua_Mob::GetAA(int id) {
|
||||
return self->GetAA(id);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetAAByAAID(int id) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetAAByAAID(id);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SetAA(int rank_id, int new_value) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SetAA(rank_id, new_value);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SetAA(int rank_id, int new_value, int charges) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SetAA(rank_id, new_value, charges);
|
||||
}
|
||||
|
||||
bool Lua_Mob::DivineAura() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->DivineAura();
|
||||
@ -2074,6 +2089,9 @@ luabind::scope lua_register_mob() {
|
||||
.def("CheckHealAggroAmount", (int(Lua_Mob::*)(int))&Lua_Mob::CheckHealAggroAmount)
|
||||
.def("CheckHealAggroAmount", (int(Lua_Mob::*)(int,uint32))&Lua_Mob::CheckHealAggroAmount)
|
||||
.def("GetAA", (int(Lua_Mob::*)(int))&Lua_Mob::GetAA)
|
||||
.def("GetAAByAAID", (int(Lua_Mob::*)(int))&Lua_Mob::GetAAByAAID)
|
||||
.def("SetAA", (bool(Lua_Mob::*)(int,int))&Lua_Mob::SetAA)
|
||||
.def("SetAA", (bool(Lua_Mob::*)(int,int,int))&Lua_Mob::SetAA)
|
||||
.def("DivineAura", (bool(Lua_Mob::*)(void))&Lua_Mob::DivineAura)
|
||||
.def("SetOOCRegen", (void(Lua_Mob::*)(int))&Lua_Mob::SetOOCRegen)
|
||||
.def("GetEntityVariable", (const char*(Lua_Mob::*)(const char*))&Lua_Mob::GetEntityVariable)
|
||||
|
||||
@ -249,6 +249,9 @@ public:
|
||||
int CheckHealAggroAmount(int spell_id);
|
||||
int CheckHealAggroAmount(int spell_id, uint32 heal_possible);
|
||||
int GetAA(int id);
|
||||
int GetAAByAAID(int id);
|
||||
bool SetAA(int rank_id, int new_value);
|
||||
bool SetAA(int rank_id, int new_value, int charges);
|
||||
bool DivineAura();
|
||||
void SetOOCRegen(int regen);
|
||||
const char* GetEntityVariable(const char *name);
|
||||
|
||||
17
zone/mob.cpp
17
zone/mob.cpp
@ -307,8 +307,8 @@ Mob::Mob(const char* in_name,
|
||||
casting_spell_id = 0;
|
||||
casting_spell_timer = 0;
|
||||
casting_spell_timer_duration = 0;
|
||||
casting_spell_type = 0;
|
||||
casting_spell_inventory_slot = 0;
|
||||
casting_spell_aa_id = 0;
|
||||
target = 0;
|
||||
|
||||
ActiveProjectileATK = false;
|
||||
@ -1142,6 +1142,10 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
else
|
||||
ns->spawn.flymode = flymode;
|
||||
|
||||
if(IsBoat()) {
|
||||
ns->spawn.flymode = 1;
|
||||
}
|
||||
|
||||
ns->spawn.lastName[0] = '\0';
|
||||
|
||||
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
|
||||
@ -3510,9 +3514,11 @@ void Mob::TriggerOnCast(uint32 focus_spell, uint32 spell_id, bool aa_trigger)
|
||||
|
||||
uint32 trigger_spell_id = 0;
|
||||
|
||||
if (aa_trigger && IsClient()){
|
||||
//focus_spell = aaid
|
||||
trigger_spell_id = CastToClient()->CalcAAFocus(focusTriggerOnCast, focus_spell, spell_id);
|
||||
if (aa_trigger && IsClient()) {
|
||||
// focus_spell = aaid
|
||||
auto rank = zone->GetAlternateAdvancementRank(focus_spell);
|
||||
if (rank)
|
||||
trigger_spell_id = CastToClient()->CalcAAFocus(focusTriggerOnCast, *rank, spell_id);
|
||||
|
||||
if(IsValidSpell(trigger_spell_id) && GetTarget())
|
||||
SpellFinished(trigger_spell_id, GetTarget(), 10, 0, -1, spells[trigger_spell_id].ResistDiff);
|
||||
@ -3768,11 +3774,8 @@ int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used)
|
||||
skilldmg_mod += itembonuses.SkillDmgTaken[HIGHEST_SKILL+1] + spellbonuses.SkillDmgTaken[HIGHEST_SKILL+1] +
|
||||
itembonuses.SkillDmgTaken[skill_used] + spellbonuses.SkillDmgTaken[skill_used];
|
||||
|
||||
|
||||
skilldmg_mod += SkillDmgTaken_Mod[skill_used] + SkillDmgTaken_Mod[HIGHEST_SKILL+1];
|
||||
|
||||
skilldmg_mod += spellbonuses.MeleeVulnerability + itembonuses.MeleeVulnerability + aabonuses.MeleeVulnerability;
|
||||
|
||||
if(skilldmg_mod < -100)
|
||||
skilldmg_mod = -100;
|
||||
|
||||
|
||||
27
zone/mob.h
27
zone/mob.h
@ -23,6 +23,8 @@
|
||||
#include "hate_list.h"
|
||||
#include "pathing.h"
|
||||
#include "position.h"
|
||||
#include "aa_ability.h"
|
||||
#include "aa.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
@ -221,10 +223,12 @@ public:
|
||||
virtual void SpellProcess();
|
||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1,
|
||||
int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF,
|
||||
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, uint32 type = 0, int16 *resist_adjust = nullptr);
|
||||
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, int16 *resist_adjust = nullptr,
|
||||
uint32 aa_id = 0);
|
||||
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = 10, int32 casttime = -1,
|
||||
int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF,
|
||||
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, uint32 type = 0, int16 resist_adjust = 0);
|
||||
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, int16 resist_adjust = 0,
|
||||
uint32 aa_id = 0);
|
||||
void CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, uint16 mana_used,
|
||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
|
||||
bool SpellFinished(uint16 spell_id, Mob *target, uint16 slot = 10, uint16 mana_used = 0,
|
||||
@ -860,7 +864,6 @@ public:
|
||||
uint32 GetZoneID() const; //for perl
|
||||
virtual int32 CheckAggroAmount(uint16 spell_id, bool isproc = false);
|
||||
virtual int32 CheckHealAggroAmount(uint16 spell_id, uint32 heal_possible = 0);
|
||||
virtual uint32 GetAA(uint32 aa_id) const { return(0); }
|
||||
|
||||
uint32 GetInstrumentMod(uint16 spell_id) const;
|
||||
int CalcSpellEffectValue(uint16 spell_id, int effect_id, int caster_level = 1, uint32 instrument_mod = 10, Mob *caster = nullptr, int ticsremaining = 0);
|
||||
@ -956,6 +959,19 @@ public:
|
||||
void Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int avoid_override, int Msg = 0);
|
||||
void Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg = 0);
|
||||
|
||||
//aa new
|
||||
uint32 GetAA(uint32 rank_id, uint32 *charges = nullptr) const;
|
||||
uint32 GetAAByAAID(uint32 aa_id, uint32 *charges = nullptr) const;
|
||||
bool SetAA(uint32 rank_id, uint32 new_value, uint32 charges = 0);
|
||||
void ClearAAs() { aa_ranks.clear(); }
|
||||
bool CanUseAlternateAdvancementRank(AA::Rank *rank);
|
||||
bool CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price, bool check_grant);
|
||||
int GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in);
|
||||
void ExpendAlternateAdvancementCharge(uint32 aa_id);
|
||||
void CalcAABonuses(StatBonuses* newbon);
|
||||
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
||||
bool CheckAATimer(int timer);
|
||||
|
||||
protected:
|
||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||
@ -969,7 +985,6 @@ protected:
|
||||
virtual bool AI_PursueCastCheck() { return(false); }
|
||||
virtual bool AI_IdleCastCheck() { return(false); }
|
||||
|
||||
|
||||
bool IsFullHP;
|
||||
bool moved;
|
||||
|
||||
@ -1145,6 +1160,7 @@ protected:
|
||||
uint32 casting_spell_timer_duration;
|
||||
uint32 casting_spell_type;
|
||||
int16 casting_spell_resist_adjust;
|
||||
uint32 casting_spell_aa_id;
|
||||
bool casting_spell_checks;
|
||||
uint16 bardsong;
|
||||
uint8 bardsong_slot;
|
||||
@ -1311,6 +1327,9 @@ protected:
|
||||
bool bEnraged;
|
||||
bool destructibleobject;
|
||||
|
||||
std::unordered_map<uint32, std::pair<uint32, uint32>> aa_ranks;
|
||||
Timer aa_timers[aaTimerMax];
|
||||
|
||||
private:
|
||||
void _StopSong(); //this is not what you think it is
|
||||
Mob* target;
|
||||
|
||||
@ -342,7 +342,7 @@ bool NPC::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
|
||||
SetCurrentSpeed(0);
|
||||
}
|
||||
|
||||
return CastSpell(AIspells[i].spellid, tar->GetID(), 1, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, 0, &(AIspells[i].resist_adjust));
|
||||
return CastSpell(AIspells[i].spellid, tar->GetID(), 1, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, &(AIspells[i].resist_adjust));
|
||||
}
|
||||
|
||||
bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint16 iSpellTypes) {
|
||||
|
||||
@ -96,7 +96,6 @@ EntityList entity_list;
|
||||
WorldServer worldserver;
|
||||
uint32 numclients = 0;
|
||||
char errorname[32];
|
||||
uint16 adverrornum = 0;
|
||||
extern Zone* zone;
|
||||
EQStreamFactory eqsf(ZoneStream);
|
||||
npcDecayTimes_Struct npcCorpseDecayTimes[100];
|
||||
@ -249,9 +248,6 @@ int main(int argc, char** argv) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading titles");
|
||||
title_manager.LoadTitles();
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading AA effects");
|
||||
database.LoadAAEffects();
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading tributes");
|
||||
database.LoadTributes();
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/servertalk.h"
|
||||
|
||||
#include "aa.h"
|
||||
#include "client.h"
|
||||
#include "entity.h"
|
||||
#include "npc.h"
|
||||
|
||||
@ -4077,33 +4077,7 @@ XS(XS_Client_RefundAA) {
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
int curpt = 0;
|
||||
bool refunded = false;
|
||||
|
||||
for(int x1=0;x1<aaHighestID;x1++){
|
||||
curpt = THIS->GetAA(x1);
|
||||
if(curpt > 0){
|
||||
SendAA_Struct* curaa = zone->FindAA(x1);
|
||||
if(curaa){
|
||||
THIS->SetAA(x1, 0);
|
||||
for(int x2=0;x2<curpt;x2++){ //add up all the AA points pt by pt to get the correct cost
|
||||
THIS->GetPP().aapoints += curaa->cost + (curaa->cost_inc * x2);
|
||||
refunded = true;
|
||||
}
|
||||
}
|
||||
else //aa doesn't exist.. but if they bought it then it had at least a cost of 1 point each
|
||||
{ //so give back what we can
|
||||
THIS->GetPP().aapoints += curpt;
|
||||
THIS->SetAA(x1, 0);
|
||||
refunded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(refunded){
|
||||
THIS->Save(); //save of course
|
||||
THIS->Kick(); //client gets all buggy if we don't immediatly relog so just force it on them
|
||||
}
|
||||
THIS->RefundAA();
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@ -4915,11 +4889,44 @@ XS(XS_Client_IncrementAA)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->IncrementAA(aaskillid);
|
||||
THIS->IncrementAlternateAdvancementRank(aaskillid);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_GrantAlternateAdvancementAbility); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_GrantAlternateAdvancementAbility)
|
||||
{
|
||||
dXSARGS;
|
||||
if(items < 3 || items > 4)
|
||||
Perl_croak(aTHX_ "Usage: Client::GrantAlternateAdvancementAbility(THIS, aa_id, points, [ignore_cost])");
|
||||
{
|
||||
Client * THIS;
|
||||
bool RETVAL;
|
||||
int aa_id = (int)SvIV(ST(1));
|
||||
int points = (int)SvIV(ST(2));
|
||||
bool ignore_cost = false;
|
||||
|
||||
if(sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *, tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
if(items > 3) {
|
||||
ignore_cost = (bool)SvTRUE(ST(3));
|
||||
}
|
||||
|
||||
RETVAL = THIS->GrantAlternateAdvancementAbility(aa_id, points, ignore_cost);
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_GetAALevel);
|
||||
XS(XS_Client_GetAALevel)
|
||||
{
|
||||
@ -6463,6 +6470,7 @@ XS(boot_Client)
|
||||
newXSproto(strcpy(buf, "GetIP"), XS_Client_GetIP, file, "$");
|
||||
newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "IncrementAA"), XS_Client_IncrementAA, file, "$$");
|
||||
newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Client_GrantAlternateAdvancementAbility, file, "$$$;$");
|
||||
newXSproto(strcpy(buf, "GetAALevel"), XS_Client_GetAALevel, file, "$$");
|
||||
newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$");
|
||||
newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$");
|
||||
|
||||
@ -3998,9 +3998,9 @@ XS(XS_Mob_CastSpell)
|
||||
}
|
||||
|
||||
if (resist_adjust == 0)//If you do not pass resist adjust as nullptr it will ignore the spells default resist adjust
|
||||
THIS->CastSpell(spell_id, target_id, slot, casttime, mana_cost, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0);
|
||||
THIS->CastSpell(spell_id, target_id, slot, casttime, mana_cost, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0);
|
||||
else
|
||||
THIS->CastSpell(spell_id, target_id, slot, casttime, mana_cost, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0, &resist_adjust);
|
||||
THIS->CastSpell(spell_id, target_id, slot, casttime, mana_cost, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, &resist_adjust);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@ -6360,12 +6360,12 @@ XS(XS_Mob_GetAA)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetAA(THIS, aa_id)");
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetAA(THIS, rank_id)");
|
||||
{
|
||||
Mob * THIS;
|
||||
uint32 RETVAL;
|
||||
dXSTARG;
|
||||
uint32 aa_id = (uint32)SvUV(ST(1));
|
||||
uint32 rank_id = (uint32)SvUV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Mob")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@ -6376,12 +6376,68 @@ XS(XS_Mob_GetAA)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetAA(aa_id);
|
||||
RETVAL = THIS->GetAA(rank_id);
|
||||
XSprePUSH; PUSHu((UV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_GetAAByAAID); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetAAByAAID)
|
||||
{
|
||||
dXSARGS;
|
||||
if(items != 2)
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetAAByAAID(THIS, aa_id)");
|
||||
{
|
||||
Mob * THIS;
|
||||
uint32 RETVAL;
|
||||
dXSTARG;
|
||||
uint32 aa_id = (uint32)SvUV(ST(1));
|
||||
|
||||
if(sv_derived_from(ST(0), "Mob")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Mob *, tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetAAByAAID(aa_id);
|
||||
XSprePUSH; PUSHu((UV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_SetAA); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_SetAA)
|
||||
{
|
||||
dXSARGS;
|
||||
if(items < 3 || items > 4)
|
||||
Perl_croak(aTHX_ "Usage: Mob::SetAA(THIS, aa_id, points, [charges])");
|
||||
{
|
||||
Mob * THIS;
|
||||
bool RETVAL;
|
||||
int aa_id = (int)SvIV(ST(1));
|
||||
int points = (int)SvIV(ST(2));
|
||||
int charges = (items == 4) ? (int)SvIV(ST(3)) : 0;
|
||||
|
||||
if(sv_derived_from(ST(0), "Mob")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Mob *, tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->SetAA(aa_id, points, charges);
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_DivineAura); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_DivineAura)
|
||||
{
|
||||
@ -8625,6 +8681,8 @@ XS(boot_Mob)
|
||||
newXSproto(strcpy(buf, "CheckAggroAmount"), XS_Mob_CheckAggroAmount, file, "$$");
|
||||
newXSproto(strcpy(buf, "CheckHealAggroAmount"), XS_Mob_CheckHealAggroAmount, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetAA"), XS_Mob_GetAA, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetAAByAAID"), XS_Mob_GetAAByAAID, file, "$$");
|
||||
newXSproto(strcpy(buf, "SetAA"), XS_Mob_SetAA, file, "$$$;$");
|
||||
newXSproto(strcpy(buf, "DivineAura"), XS_Mob_DivineAura, file, "$");
|
||||
newXSproto(strcpy(buf, "AddFeignMemory"), XS_Mob_AddFeignMemory, file, "$$");
|
||||
newXSproto(strcpy(buf, "RemoveFromFeignMemory"), XS_Mob_RemoveFromFeignMemory, file, "$$");
|
||||
|
||||
@ -149,22 +149,19 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
||||
}
|
||||
|
||||
who->AddToHateList(this, hate, 0, false);
|
||||
if (max_damage > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skill &&
|
||||
IsValidSpell(aabonuses.SkillAttackProc[2])) {
|
||||
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
|
||||
if (zone->random.Roll(chance))
|
||||
SpellFinished(aabonuses.SkillAttackProc[2], who, 10, 0, -1,
|
||||
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
|
||||
}
|
||||
who->Damage(this, max_damage, SPELL_UNKNOWN, skill, false);
|
||||
|
||||
//Make sure 'this' has not killed the target and 'this' is not dead (Damage shield ect).
|
||||
if(!GetTarget())return;
|
||||
if (HasDied()) return;
|
||||
|
||||
//[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill
|
||||
if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skill){
|
||||
int kb_chance = 25;
|
||||
kb_chance += kb_chance*(100-aabonuses.SpecialAttackKBProc[0])/100;
|
||||
|
||||
if (zone->random.Roll(kb_chance))
|
||||
SpellFinished(904, who, 10, 0, -1, spells[904].ResistDiff);
|
||||
//who->Stun(100); Kayen: This effect does not stun on live, it only moves the NPC.
|
||||
}
|
||||
|
||||
if (HasSkillProcs())
|
||||
TrySkillProc(who, skill, ReuseTime*1000);
|
||||
|
||||
@ -2442,19 +2439,18 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
||||
}
|
||||
|
||||
other->AddToHateList(this, hate, 0, false);
|
||||
if (damage > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skillinuse &&
|
||||
IsValidSpell(aabonuses.SkillAttackProc[2])) {
|
||||
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
|
||||
if (zone->random.Roll(chance))
|
||||
SpellFinished(aabonuses.SkillAttackProc[2], other, 10, 0, -1,
|
||||
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
|
||||
}
|
||||
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse);
|
||||
|
||||
if (HasDied())
|
||||
return;
|
||||
|
||||
if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skillinuse){
|
||||
int kb_chance = 25;
|
||||
kb_chance += kb_chance*(100-aabonuses.SpecialAttackKBProc[0])/100;
|
||||
|
||||
if (zone->random.Roll(kb_chance))
|
||||
SpellFinished(904, other, 10, 0, -1, spells[904].ResistDiff);
|
||||
}
|
||||
|
||||
if (CanSkillProc && HasSkillProcs())
|
||||
TrySkillProc(other, skillinuse, ReuseTime);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -146,7 +146,8 @@ void NPC::SpellProcess()
|
||||
// to allow procs to work
|
||||
bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot,
|
||||
uint32 timer, uint32 timer_duration, uint32 type, int16 *resist_adjust)
|
||||
uint32 timer, uint32 timer_duration, int16 *resist_adjust,
|
||||
uint32 aa_id)
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Spells, "CastSpell called for spell %s (%d) on entity %d, slot %d, time %d, mana %d, from item slot %d",
|
||||
(IsValidSpell(spell_id))?spells[spell_id].name:"UNKNOWN SPELL", spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot);
|
||||
@ -318,11 +319,11 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
|
||||
if(resist_adjust)
|
||||
{
|
||||
return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, type, *resist_adjust));
|
||||
return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, *resist_adjust, aa_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, type, spells[spell_id].ResistDiff));
|
||||
return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, spells[spell_id].ResistDiff, aa_id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,8 +337,8 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
//
|
||||
bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish,
|
||||
uint32 item_slot, uint32 timer, uint32 timer_duration, uint32 type,
|
||||
int16 resist_adjust)
|
||||
uint32 item_slot, uint32 timer, uint32 timer_duration,
|
||||
int16 resist_adjust, uint32 aa_id)
|
||||
{
|
||||
Mob* pMob = nullptr;
|
||||
int32 orgcasttime;
|
||||
@ -361,7 +362,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
casting_spell_timer = timer;
|
||||
casting_spell_timer_duration = timer_duration;
|
||||
}
|
||||
casting_spell_type = type;
|
||||
casting_spell_aa_id = aa_id;
|
||||
|
||||
SaveSpellLoc();
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Casting %d Started at (%.3f,%.3f,%.3f)", spell_id, m_SpellLocation.x, m_SpellLocation.y, m_SpellLocation.z);
|
||||
@ -408,24 +409,19 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
// ok now we know the target
|
||||
casting_spell_targetid = target_id;
|
||||
|
||||
if (mana_cost == -1) {
|
||||
// We don't get actual mana cost here, that's done when we consume the mana
|
||||
if (mana_cost == -1)
|
||||
mana_cost = spell.mana;
|
||||
mana_cost = GetActSpellCost(spell_id, mana_cost);
|
||||
}
|
||||
|
||||
if(HasMGB() && spells[spell_id].can_mgb)
|
||||
mana_cost *= 2;
|
||||
|
||||
// mana is checked for clients on the frontend. we need to recheck it for NPCs though
|
||||
// fix: items dont need mana :-/
|
||||
// If you're at full mana, let it cast even if you dont have enough mana
|
||||
|
||||
// we calculated this above, now enforce it
|
||||
if(mana_cost > 0 && slot != 10)
|
||||
if(mana_cost > 0 && slot != USE_ITEM_SPELL_SLOT)
|
||||
{
|
||||
int my_curmana = GetMana();
|
||||
int my_maxmana = GetMaxMana();
|
||||
if(my_curmana < spell.mana) // not enough mana
|
||||
if(my_curmana < mana_cost) // not enough mana
|
||||
{
|
||||
//this is a special case for NPCs with no mana...
|
||||
if(IsNPC() && my_curmana == my_maxmana)
|
||||
@ -783,9 +779,9 @@ void Mob::ZeroCastingVars()
|
||||
casting_spell_inventory_slot = 0;
|
||||
casting_spell_timer = 0;
|
||||
casting_spell_timer_duration = 0;
|
||||
casting_spell_type = 0;
|
||||
casting_spell_resist_adjust = 0;
|
||||
casting_spell_checks = false;
|
||||
casting_spell_aa_id = 0;
|
||||
delaytimer = false;
|
||||
}
|
||||
|
||||
@ -816,10 +812,9 @@ void Mob::InterruptSpell(uint16 message, uint16 color, uint16 spellid)
|
||||
CastToNPC()->AI_Event_SpellCastFinished(false, casting_spell_slot);
|
||||
}
|
||||
|
||||
if(casting_spell_type == 1 && IsClient()) { //Rest AA Timer on failed cast
|
||||
CastToClient()->SendAATimer(casting_spell_timer - pTimerAAStart, 0, 0xFFFFFF);
|
||||
CastToClient()->Message_StringID(15,ABILITY_FAILED);
|
||||
CastToClient()->GetPTimers().Clear(&database, casting_spell_timer);
|
||||
if(casting_spell_aa_id && IsClient()) { //Rest AA Timer on failed cast
|
||||
CastToClient()->Message_StringID(MT_SpellFailure, ABILITY_FAILED);
|
||||
CastToClient()->ResetAlternateAdvancementTimer(casting_spell_aa_id);
|
||||
}
|
||||
|
||||
ZeroCastingVars(); // resets all the state keeping stuff
|
||||
@ -2078,7 +2073,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
else if(!SpellOnTarget(spell_id, spell_target, false, true, resist_adjust, false, level_override)) {
|
||||
if(IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) {
|
||||
// Prevent mana usage/timers being set for beneficial buffs
|
||||
if(casting_spell_type == 1)
|
||||
if(casting_spell_aa_id)
|
||||
InterruptSpell();
|
||||
return false;
|
||||
}
|
||||
@ -2157,11 +2152,11 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
}
|
||||
#endif //BOTS
|
||||
|
||||
// We hold off turning MBG off so we can still use it to calc the mana cost
|
||||
if(spells[spell_id].can_mgb && HasMGB())
|
||||
{
|
||||
SpellOnTarget(spell_id, this);
|
||||
entity_list.MassGroupBuff(this, this, spell_id, true);
|
||||
SetMGB(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2262,20 +2257,36 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
}
|
||||
|
||||
// if this was a spell slot or an ability use up the mana for it
|
||||
// CastSpell already reduced the cost for it if we're a client with focus
|
||||
if(slot != USE_ITEM_SPELL_SLOT && slot != POTION_BELT_SPELL_SLOT && slot != TARGET_RING_SPELL_SLOT && mana_used > 0)
|
||||
{
|
||||
mana_used = GetActSpellCost(spell_id, mana_used);
|
||||
if (HasMGB() && spells[spell_id].can_mgb) {
|
||||
mana_used *= 2;
|
||||
SetMGB(false);
|
||||
}
|
||||
// clamp if we some how got focused above our current mana
|
||||
if (GetMana() < mana_used)
|
||||
mana_used = GetMana();
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Spell %d: consuming %d mana", spell_id, mana_used);
|
||||
if (!DoHPToManaCovert(mana_used))
|
||||
if (!DoHPToManaCovert(mana_used)) {
|
||||
SetMana(GetMana() - mana_used);
|
||||
TryTriggerOnValueAmount(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
//set our reuse timer on long ass reuse_time spells...
|
||||
if(IsClient() && !isproc)
|
||||
{
|
||||
if(spell_id == casting_spell_id && casting_spell_timer != 0xFFFFFFFF)
|
||||
if(casting_spell_aa_id) {
|
||||
AA::Rank *rank = zone->GetAlternateAdvancementRank(casting_spell_aa_id);
|
||||
|
||||
if(rank && rank->base_ability) {
|
||||
ExpendAlternateAdvancementCharge(rank->base_ability->id);
|
||||
}
|
||||
}
|
||||
else if(spell_id == casting_spell_id && casting_spell_timer != 0xFFFFFFFF)
|
||||
{
|
||||
//aa new todo: aa expendable charges here
|
||||
CastToClient()->GetPTimers().Start(casting_spell_timer, casting_spell_timer_duration);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Spell %d: Setting custom reuse timer %d to %d", spell_id, casting_spell_timer, casting_spell_timer_duration);
|
||||
}
|
||||
@ -3753,7 +3764,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
// if SpellEffect returned false there's a problem applying the
|
||||
// spell. It's most likely a buff that can't stack.
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Spell %d could not apply its effects %s -> %s\n", spell_id, GetName(), spelltar->GetName());
|
||||
if(casting_spell_type != 1) // AA is handled differently
|
||||
if(casting_spell_aa_id)
|
||||
Message_StringID(MT_SpellFailure, SPELL_NO_HOLD);
|
||||
safe_delete(action_packet);
|
||||
return false;
|
||||
@ -4116,8 +4127,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
else if (IsClient() && CastToClient()->CheckAAEffect(aaEffectWarcry))
|
||||
else if (CheckAATimer(aaTimerWarcry))
|
||||
{
|
||||
Message(13, "Your are immune to fear.");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!");
|
||||
|
||||
@ -179,10 +179,10 @@ bool TitleManager::IsClientEligibleForTitle(Client *c, std::vector<TitleEntry>::
|
||||
if((Title->Class >= 0) && (c->GetBaseClass() != Title->Class))
|
||||
return false;
|
||||
|
||||
if((Title->MinAAPoints >= 0) && (c->GetAAPointsSpent() < static_cast<uint32>(Title->MinAAPoints)))
|
||||
if((Title->MinAAPoints >= 0) && (c->GetSpentAA() < static_cast<uint32>(Title->MinAAPoints)))
|
||||
return false;
|
||||
|
||||
if((Title->MaxAAPoints >= 0) && (c->GetAAPointsSpent() > static_cast<uint32>(Title->MaxAAPoints)))
|
||||
if((Title->MaxAAPoints >= 0) && (c->GetSpentAA() > static_cast<uint32>(Title->MaxAAPoints)))
|
||||
return false;
|
||||
|
||||
if(Title->SkillID >= 0)
|
||||
|
||||
@ -212,7 +212,7 @@ void NPC::UpdateWaypoint(int wp_index)
|
||||
Log.Out(Logs::Detail, Logs::AI, "Next waypoint %d: (%.3f, %.3f, %.3f, %.3f)", wp_index, m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, m_CurrentWayPoint.w);
|
||||
|
||||
//fix up pathing Z
|
||||
if(zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints))
|
||||
if(zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints) && !IsBoat())
|
||||
{
|
||||
|
||||
if(!RuleB(Watermap, CheckForWaterAtWaypoints) || !zone->HasWaterMap() ||
|
||||
@ -521,7 +521,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
||||
}
|
||||
|
||||
bool send_update = false;
|
||||
int compare_steps = IsBoat() ? 1 : 20;
|
||||
int compare_steps = 20;
|
||||
if(tar_ndx < compare_steps && m_TargetLocation.x==x && m_TargetLocation.y==y) {
|
||||
|
||||
float new_x = m_Position.x + m_TargetV.x*tar_vector;
|
||||
|
||||
@ -68,7 +68,6 @@ extern bool staticzone;
|
||||
extern NetConnection net;
|
||||
extern PetitionList petition_list;
|
||||
extern QuestParserCollection* parse;
|
||||
extern uint16 adverrornum;
|
||||
extern uint32 numclients;
|
||||
extern WorldServer worldserver;
|
||||
extern Zone* zone;
|
||||
@ -805,8 +804,6 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
||||
weather_intensity = 0;
|
||||
blocked_spells = nullptr;
|
||||
totalBS = 0;
|
||||
aas = nullptr;
|
||||
totalAAs = 0;
|
||||
zone_has_current_time = false;
|
||||
|
||||
Instance_Shutdown_Timer = nullptr;
|
||||
@ -865,16 +862,6 @@ Zone::~Zone() {
|
||||
safe_delete(qGlobals);
|
||||
safe_delete_array(adv_data);
|
||||
safe_delete_array(map_name);
|
||||
|
||||
if(aas != nullptr) {
|
||||
int r;
|
||||
for(r = 0; r < totalAAs; r++) {
|
||||
uchar *data = (uchar *) aas[r];
|
||||
safe_delete_array(data);
|
||||
}
|
||||
safe_delete_array(aas);
|
||||
}
|
||||
|
||||
safe_delete(GuildBanks);
|
||||
}
|
||||
|
||||
@ -953,16 +940,12 @@ bool Zone::Init(bool iStaticZone) {
|
||||
zone->LoadAlternateCurrencies();
|
||||
zone->LoadNPCEmotes(&NPCEmoteList);
|
||||
|
||||
//Load AA information
|
||||
adverrornum = 500;
|
||||
LoadAAs();
|
||||
LoadAlternateAdvancement();
|
||||
|
||||
//Load merchant data
|
||||
adverrornum = 501;
|
||||
zone->GetMerchantDataForZoneLoad();
|
||||
|
||||
//Load temporary merchant data
|
||||
adverrornum = 502;
|
||||
zone->LoadTempMerchantData();
|
||||
|
||||
// Merc data
|
||||
@ -974,7 +957,6 @@ bool Zone::Init(bool iStaticZone) {
|
||||
if (RuleB(Zone, LevelBasedEXPMods))
|
||||
zone->LoadLevelEXPMods();
|
||||
|
||||
adverrornum = 503;
|
||||
petition_list.ClearPetitions();
|
||||
petition_list.ReadDatabase();
|
||||
|
||||
|
||||
20
zone/zone.h
20
zone/zone.h
@ -27,6 +27,7 @@
|
||||
#include "qglobals.h"
|
||||
#include "spawn2.h"
|
||||
#include "spawngroup.h"
|
||||
#include "aa_ability.h"
|
||||
|
||||
struct ZonePoint
|
||||
{
|
||||
@ -113,11 +114,13 @@ public:
|
||||
|
||||
inline const uint32& GetMaxClients() { return pMaxClients; }
|
||||
|
||||
void LoadAAs();
|
||||
int GetTotalAAs() { return totalAAs; }
|
||||
SendAA_Struct* GetAABySequence(uint32 seq) { return aas[seq]; }
|
||||
SendAA_Struct* FindAA(uint32 id);
|
||||
uint8 GetTotalAALevels(uint32 skill_id);
|
||||
//new AA
|
||||
void LoadAlternateAdvancement();
|
||||
AA::Ability *GetAlternateAdvancementAbility(int id);
|
||||
AA::Ability *GetAlternateAdvancementAbilityByRank(int rank_id);
|
||||
AA::Rank *GetAlternateAdvancementRank(int rank_id);
|
||||
std::pair<AA::Ability*, AA::Rank*> GetAlternateAdvancementAbilityAndRank(int id, int points_spent);
|
||||
|
||||
void LoadZoneDoors(const char* zone, int16 version);
|
||||
bool LoadZoneObjects();
|
||||
bool LoadGroundSpawns();
|
||||
@ -193,6 +196,10 @@ public:
|
||||
char *adv_data;
|
||||
bool did_adventure_actions;
|
||||
|
||||
//new AA
|
||||
std::unordered_map<int, std::unique_ptr<AA::Ability>> aa_abilities;
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> aa_ranks;
|
||||
|
||||
void DoAdventureCountIncrease();
|
||||
void DoAdventureAssassinationCountIncrease();
|
||||
void DoAdventureActions();
|
||||
@ -313,9 +320,6 @@ private:
|
||||
int totalBS;
|
||||
ZoneSpellsBlocked *blocked_spells;
|
||||
|
||||
int totalAAs;
|
||||
SendAA_Struct **aas; //array of AA structs
|
||||
|
||||
/*
|
||||
Spawn related things
|
||||
*/
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "position.h"
|
||||
#include "../common/faction.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "aa_ability.h"
|
||||
|
||||
class Client;
|
||||
class Corpse;
|
||||
@ -339,17 +340,10 @@ public:
|
||||
bool SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list); // needed for factions Dec, 16 2001
|
||||
bool LoadFactionData();
|
||||
|
||||
/* AAs */
|
||||
bool LoadAAEffects();
|
||||
bool LoadAAEffects2();
|
||||
bool LoadSwarmSpells();
|
||||
SendAA_Struct*GetAASkillVars(uint32 skill_id);
|
||||
uint8 GetTotalAALevels(uint32 skill_id);
|
||||
uint32 GetSizeAA();
|
||||
uint32 CountAAs();
|
||||
void LoadAAs(SendAA_Struct **load);
|
||||
uint32 CountAAEffects();
|
||||
void FillAAEffects(SendAA_Struct* aa_struct);
|
||||
/* AAs New */
|
||||
bool LoadAlternateAdvancementAbilities(std::unordered_map<int, std::unique_ptr<AA::Ability>> &abilities,
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> &ranks);
|
||||
bool LoadAlternateAdvancement(Client *c);
|
||||
|
||||
/* Zone related */
|
||||
bool GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user