mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 11:31:30 +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 */
|
#endif /* CLIENTVERSIONS_H */
|
||||||
|
|||||||
@ -548,4 +548,5 @@ N(OP_ZoneServerInfo),
|
|||||||
N(OP_ZoneServerReady),
|
N(OP_ZoneServerReady),
|
||||||
N(OP_ZoneSpawns),
|
N(OP_ZoneSpawns),
|
||||||
N(OP_ZoneUnavail),
|
N(OP_ZoneUnavail),
|
||||||
|
N(OP_ResetAA),
|
||||||
// mail and chat opcodes located in ../mail_oplist.h
|
// mail and chat opcodes located in ../mail_oplist.h
|
||||||
|
|||||||
@ -4219,6 +4219,52 @@ struct UseAA_Struct {
|
|||||||
uint32 end;
|
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 {
|
struct AA_Ability {
|
||||||
/*00*/ uint32 skill_id;
|
/*00*/ uint32 skill_id;
|
||||||
/*04*/ uint32 base1;
|
/*04*/ uint32 base1;
|
||||||
@ -4273,7 +4319,7 @@ struct SendAA_Struct {
|
|||||||
struct AA_Action {
|
struct AA_Action {
|
||||||
/*00*/ uint32 action;
|
/*00*/ uint32 action;
|
||||||
/*04*/ uint32 ability;
|
/*04*/ uint32 ability;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 target_id;
|
||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2810,7 +2810,7 @@ namespace RoF
|
|||||||
|
|
||||||
eq->aa_spent = emu->aa_spent;
|
eq->aa_spent = emu->aa_spent;
|
||||||
// These fields may need to be correctly populated at some point
|
// 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_general = 0;
|
||||||
eq->aa_spent_archetype = 0;
|
eq->aa_spent_archetype = 0;
|
||||||
eq->aa_spent_class = 0;
|
eq->aa_spent_class = 0;
|
||||||
@ -2846,58 +2846,81 @@ namespace RoF
|
|||||||
|
|
||||||
ENCODE(OP_SendAATable)
|
ENCODE(OP_SendAATable)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
|
EQApplicationPacket *inapp = *p;
|
||||||
SETUP_VAR_ENCODE(SendAA_Struct);
|
*p = nullptr;
|
||||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
|
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||||
|
|
||||||
// Check clientver field to verify this AA should be sent for SoF
|
// the structs::SendAA_Struct includes enough space for 1 prereq which is the min even if it has no prereqs
|
||||||
// clientver 1 is for all clients and 5 is for Live
|
auto prereq_size = emu->total_prereqs > 1 ? (emu->total_prereqs - 1) * 8 : 0;
|
||||||
if (emu->clientver <= 7)
|
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));
|
||||||
OUT(id);
|
|
||||||
eq->unknown004 = 1;
|
|
||||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
std::vector<int32> skill;
|
||||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
std::vector<int32> points;
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
for(auto i = 0; i < emu->total_prereqs; ++i) {
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
skill.push_back(inapp->ReadUInt32());
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? -1 : (emu->sof_next_skill);
|
points.push_back(inapp->ReadUInt32());
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
ENCODE(OP_SendCharInfo)
|
||||||
|
|||||||
@ -2466,7 +2466,8 @@ namespace RoF2
|
|||||||
outapp->WriteUInt32(emu->lastlogin);
|
outapp->WriteUInt32(emu->lastlogin);
|
||||||
outapp->WriteUInt32(emu->timePlayedMin);
|
outapp->WriteUInt32(emu->timePlayedMin);
|
||||||
outapp->WriteUInt32(emu->timeentitledonaccount);
|
outapp->WriteUInt32(emu->timeentitledonaccount);
|
||||||
outapp->WriteUInt32(0x0007ffff); // Expansion bitmask
|
outapp->WriteUInt32(emu->expansions);
|
||||||
|
//outapp->WriteUInt32(0x0007ffff); // Expansion bitmask
|
||||||
|
|
||||||
outapp->WriteUInt32(structs::MAX_PP_LANGUAGE);
|
outapp->WriteUInt32(structs::MAX_PP_LANGUAGE);
|
||||||
|
|
||||||
@ -2899,7 +2900,7 @@ namespace RoF2
|
|||||||
|
|
||||||
eq->aa_spent = emu->aa_spent;
|
eq->aa_spent = emu->aa_spent;
|
||||||
// These fields may need to be correctly populated at some point
|
// 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_general = 0;
|
||||||
eq->aa_spent_archetype = 0;
|
eq->aa_spent_archetype = 0;
|
||||||
eq->aa_spent_class = 0;
|
eq->aa_spent_class = 0;
|
||||||
@ -2935,58 +2936,80 @@ namespace RoF2
|
|||||||
|
|
||||||
ENCODE(OP_SendAATable)
|
ENCODE(OP_SendAATable)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
|
EQApplicationPacket *inapp = *p;
|
||||||
SETUP_VAR_ENCODE(SendAA_Struct);
|
*p = nullptr;
|
||||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
|
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||||
|
|
||||||
// Check clientver field to verify this AA should be sent for SoF
|
// the structs::SendAA_Struct includes enough space for 1 prereq which is the min even if it has no prereqs
|
||||||
// clientver 1 is for all clients and 5 is for Live
|
auto prereq_size = emu->total_prereqs > 1 ? (emu->total_prereqs - 1) * 8 : 0;
|
||||||
if (emu->clientver <= 8)
|
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));
|
||||||
OUT(id);
|
|
||||||
eq->unknown004 = 1;
|
|
||||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
std::vector<int32> skill;
|
||||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
std::vector<int32> points;
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
for(auto i = 0; i < emu->total_prereqs; ++i) {
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
skill.push_back(inapp->ReadUInt32());
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? -1 : (emu->sof_next_skill);
|
points.push_back(inapp->ReadUInt32());
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
ENCODE(OP_SendCharInfo)
|
||||||
|
|||||||
@ -4289,7 +4289,7 @@ struct AA_List {
|
|||||||
struct AA_Action {
|
struct AA_Action {
|
||||||
/*00*/ uint32 action;
|
/*00*/ uint32 action;
|
||||||
/*04*/ uint32 ability;
|
/*04*/ uint32 ability;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 target_id;
|
||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
/*16*/
|
/*16*/
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4288,7 +4288,7 @@ struct AA_List {
|
|||||||
struct AA_Action {
|
struct AA_Action {
|
||||||
/*00*/ uint32 action;
|
/*00*/ uint32 action;
|
||||||
/*04*/ uint32 ability;
|
/*04*/ uint32 ability;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 target_id;
|
||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
/*16*/
|
/*16*/
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1677,8 +1677,8 @@ namespace SoD
|
|||||||
OUT(copper_bank);
|
OUT(copper_bank);
|
||||||
OUT(platinum_shared);
|
OUT(platinum_shared);
|
||||||
// OUT(unknown13156[84]);
|
// OUT(unknown13156[84]);
|
||||||
//OUT(expansions);
|
OUT(expansions);
|
||||||
eq->expansions = 16383;
|
//eq->expansions = 16383;
|
||||||
// OUT(unknown13244[12]);
|
// OUT(unknown13244[12]);
|
||||||
OUT(autosplit);
|
OUT(autosplit);
|
||||||
// OUT(unknown13260[16]);
|
// OUT(unknown13260[16]);
|
||||||
@ -1862,55 +1862,56 @@ namespace SoD
|
|||||||
|
|
||||||
ENCODE(OP_SendAATable)
|
ENCODE(OP_SendAATable)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
|
EQApplicationPacket *inapp = *p;
|
||||||
SETUP_VAR_ENCODE(SendAA_Struct);
|
*p = nullptr;
|
||||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
|
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||||
|
|
||||||
// Check clientver field to verify this AA should be sent for SoF
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
|
||||||
// clientver 1 is for all clients and 5 is for SoD
|
structs::SendAA_Struct *eq = (structs::SendAA_Struct*)outapp->pBuffer;
|
||||||
if (emu->clientver <= 5)
|
|
||||||
{
|
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
|
||||||
OUT(id);
|
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
|
||||||
|
|
||||||
|
eq->id = emu->id;
|
||||||
eq->unknown004 = 1;
|
eq->unknown004 = 1;
|
||||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
eq->id = emu->id;
|
||||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
eq->desc_sid = emu->desc_sid;
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->title_sid = emu->title_sid;
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->class_type = emu->level_req;
|
||||||
eq->title_sid = emu->sof_next_skill;
|
eq->cost = emu->cost;
|
||||||
eq->desc_sid = emu->sof_next_skill;
|
eq->seq = emu->seq;
|
||||||
OUT(class_type);
|
eq->current_level = emu->current_level;
|
||||||
OUT(cost);
|
eq->type = emu->type;
|
||||||
OUT(seq);
|
eq->spellid = emu->spell;
|
||||||
OUT(current_level);
|
eq->spell_type = emu->spell_type;
|
||||||
OUT(prereq_skill);
|
eq->spell_refresh = emu->spell_refresh;
|
||||||
OUT(prereq_minpoints);
|
eq->classes = emu->classes;
|
||||||
eq->type = emu->sof_type;
|
eq->max_level = emu->max_level;
|
||||||
OUT(spellid);
|
eq->last_id = emu->prev_id;
|
||||||
OUT(spell_type);
|
eq->next_id = emu->next_id;
|
||||||
OUT(spell_refresh);
|
eq->cost2 = emu->total_cost;
|
||||||
OUT(classes);
|
eq->grant_only = emu->grant_only;
|
||||||
OUT(berserker);
|
eq->expendable_charges = emu->charges;
|
||||||
//eq->max_level = emu->sof_max_level;
|
eq->aa_expansion = emu->expansion;
|
||||||
OUT(max_level);
|
eq->special_category = emu->category;
|
||||||
OUT(last_id);
|
eq->total_abilities = emu->total_effects;
|
||||||
OUT(next_id);
|
|
||||||
OUT(cost2);
|
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->abilities[i].skill_id = inapp->ReadUInt32();
|
||||||
eq->special_category = emu->special_category;
|
eq->abilities[i].base1 = inapp->ReadUInt32();
|
||||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
eq->abilities[i].base2 = inapp->ReadUInt32();
|
||||||
OUT(total_abilities);
|
eq->abilities[i].slot = inapp->ReadUInt32();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
ENCODE(OP_SendCharInfo)
|
||||||
|
|||||||
@ -3813,8 +3813,7 @@ struct SendAA_Struct {
|
|||||||
/*0049*/ uint32 spellid;
|
/*0049*/ uint32 spellid;
|
||||||
/*0053*/ uint32 spell_type;
|
/*0053*/ uint32 spell_type;
|
||||||
/*0057*/ uint32 spell_refresh;
|
/*0057*/ uint32 spell_refresh;
|
||||||
/*0061*/ uint16 classes;
|
/*0061*/ uint32 classes;
|
||||||
/*0063*/ uint16 berserker; //seems to be 1 if its a berserker ability
|
|
||||||
/*0065*/ uint32 max_level;
|
/*0065*/ uint32 max_level;
|
||||||
/*0069*/ uint32 last_id;
|
/*0069*/ uint32 last_id;
|
||||||
/*0073*/ uint32 next_id;
|
/*0073*/ uint32 next_id;
|
||||||
@ -3840,7 +3839,7 @@ struct AA_List {
|
|||||||
struct AA_Action {
|
struct AA_Action {
|
||||||
/*00*/ uint32 action;
|
/*00*/ uint32 action;
|
||||||
/*04*/ uint32 ability;
|
/*04*/ uint32 ability;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 target_id;
|
||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1335,8 +1335,8 @@ namespace SoF
|
|||||||
OUT(copper_bank);
|
OUT(copper_bank);
|
||||||
OUT(platinum_shared);
|
OUT(platinum_shared);
|
||||||
// OUT(unknown13156[84]);
|
// OUT(unknown13156[84]);
|
||||||
//OUT(expansions);
|
OUT(expansions);
|
||||||
eq->expansions = 16383;
|
//eq->expansions = 16383;
|
||||||
// OUT(unknown13244[12]);
|
// OUT(unknown13244[12]);
|
||||||
OUT(autosplit);
|
OUT(autosplit);
|
||||||
// OUT(unknown13260[16]);
|
// OUT(unknown13260[16]);
|
||||||
@ -1520,56 +1520,56 @@ namespace SoF
|
|||||||
|
|
||||||
ENCODE(OP_SendAATable)
|
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);
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
|
||||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*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
|
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
|
||||||
// clientver 1 is for all clients and 4 is for SoF
|
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
|
||||||
if (emu->clientver <= 4)
|
|
||||||
{
|
eq->id = emu->id;
|
||||||
OUT(id);
|
|
||||||
eq->unknown004 = 1;
|
eq->unknown004 = 1;
|
||||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
eq->id = emu->id;
|
||||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
eq->desc_sid = emu->desc_sid;
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->title_sid = emu->title_sid;
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->class_type = emu->level_req;
|
||||||
eq->title_sid = emu->sof_next_skill;
|
eq->cost = emu->cost;
|
||||||
eq->desc_sid = emu->sof_next_skill;
|
eq->seq = emu->seq;
|
||||||
OUT(class_type);
|
eq->current_level = emu->current_level;
|
||||||
OUT(cost);
|
eq->type = emu->type;
|
||||||
OUT(seq);
|
eq->spellid = emu->spell;
|
||||||
OUT(current_level);
|
eq->spell_type = emu->spell_type;
|
||||||
OUT(prereq_skill);
|
eq->spell_refresh = emu->spell_refresh;
|
||||||
OUT(prereq_minpoints);
|
eq->classes = emu->classes;
|
||||||
eq->type = emu->sof_type;
|
eq->max_level = emu->max_level;
|
||||||
OUT(spellid);
|
eq->last_id = emu->prev_id;
|
||||||
OUT(spell_type);
|
eq->next_id = emu->next_id;
|
||||||
OUT(spell_refresh);
|
eq->cost2 = emu->total_cost;
|
||||||
OUT(classes);
|
eq->grant_only = emu->grant_only;
|
||||||
OUT(berserker);
|
eq->expendable_charges = emu->charges;
|
||||||
//eq->max_level = emu->sof_max_level;
|
eq->aa_expansion = emu->expansion;
|
||||||
OUT(max_level);
|
eq->special_category = emu->category;
|
||||||
OUT(last_id);
|
eq->total_abilities = emu->total_effects;
|
||||||
OUT(next_id);
|
|
||||||
OUT(cost2);
|
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->abilities[i].skill_id = inapp->ReadUInt32();
|
||||||
eq->special_category = emu->special_category;
|
eq->abilities[i].base1 = inapp->ReadUInt32();
|
||||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
eq->abilities[i].base2 = inapp->ReadUInt32();
|
||||||
OUT(total_abilities);
|
eq->abilities[i].slot = inapp->ReadUInt32();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
ENCODE(OP_SendCharInfo)
|
||||||
@ -1665,8 +1665,6 @@ namespace SoF
|
|||||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||||
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
|
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||||
}
|
}
|
||||||
|
|
||||||
FINISH_ENCODE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//hack hack hack
|
//hack hack hack
|
||||||
|
|||||||
@ -3677,8 +3677,7 @@ struct SendAA_Struct {
|
|||||||
/*0049*/ uint32 spellid;
|
/*0049*/ uint32 spellid;
|
||||||
/*0053*/ uint32 spell_type;
|
/*0053*/ uint32 spell_type;
|
||||||
/*0057*/ uint32 spell_refresh;
|
/*0057*/ uint32 spell_refresh;
|
||||||
/*0061*/ uint16 classes;
|
/*0061*/ uint32 classes;
|
||||||
/*0063*/ uint16 berserker; //seems to be 1 if its a berserker ability
|
|
||||||
/*0065*/ uint32 max_level;
|
/*0065*/ uint32 max_level;
|
||||||
/*0069*/ uint32 last_id;
|
/*0069*/ uint32 last_id;
|
||||||
/*0073*/ uint32 next_id;
|
/*0073*/ uint32 next_id;
|
||||||
@ -3702,7 +3701,7 @@ struct AA_List {
|
|||||||
struct AA_Action {
|
struct AA_Action {
|
||||||
/*00*/ uint32 action;
|
/*00*/ uint32 action;
|
||||||
/*04*/ uint32 ability;
|
/*04*/ uint32 ability;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 target_id;
|
||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1107,50 +1107,52 @@ namespace Titanium
|
|||||||
|
|
||||||
ENCODE(OP_SendAATable)
|
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);
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
|
||||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*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
|
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
|
||||||
// clientver 1 is for all clients and 3 is for Titanium
|
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
|
||||||
if (emu->clientver <= 3)
|
|
||||||
{
|
eq->id = emu->id;
|
||||||
OUT(id);
|
|
||||||
eq->unknown004 = 1;
|
eq->unknown004 = 1;
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->id - emu->current_level + 1);
|
eq->id = emu->id;
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->id - emu->current_level + 1);
|
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||||
eq->title_sid = emu->id - emu->current_level + 1;
|
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||||
eq->desc_sid = emu->id - emu->current_level + 1;
|
eq->desc_sid = emu->desc_sid;
|
||||||
OUT(class_type);
|
eq->title_sid = emu->title_sid;
|
||||||
OUT(cost);
|
eq->class_type = emu->level_req;
|
||||||
OUT(seq);
|
eq->cost = emu->cost;
|
||||||
OUT(current_level);
|
eq->seq = emu->seq;
|
||||||
OUT(prereq_skill);
|
eq->current_level = emu->current_level;
|
||||||
OUT(prereq_minpoints);
|
eq->type = emu->type;
|
||||||
OUT(type);
|
eq->spellid = emu->spell;
|
||||||
OUT(spellid);
|
eq->spell_type = emu->spell_type;
|
||||||
OUT(spell_type);
|
eq->spell_refresh = emu->spell_refresh;
|
||||||
OUT(spell_refresh);
|
eq->classes = emu->classes;
|
||||||
OUT(classes);
|
eq->max_level = emu->max_level;
|
||||||
OUT(berserker);
|
eq->last_id = emu->prev_id;
|
||||||
OUT(max_level);
|
eq->next_id = emu->next_id;
|
||||||
OUT(last_id);
|
eq->cost2 = emu->total_cost;
|
||||||
OUT(next_id);
|
eq->total_abilities = emu->total_effects;
|
||||||
OUT(cost2);
|
|
||||||
OUT(unknown80[0]);
|
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||||
OUT(unknown80[1]);
|
eq->abilities[i].skill_id = inapp->ReadUInt32();
|
||||||
OUT(total_abilities);
|
eq->abilities[i].base1 = inapp->ReadUInt32();
|
||||||
unsigned int r;
|
eq->abilities[i].base2 = inapp->ReadUInt32();
|
||||||
for (r = 0; r < emu->total_abilities; r++) {
|
eq->abilities[i].slot = inapp->ReadUInt32();
|
||||||
OUT(abilities[r].skill_id);
|
|
||||||
OUT(abilities[r].base1);
|
|
||||||
OUT(abilities[r].base2);
|
|
||||||
OUT(abilities[r].slot);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
ENCODE(OP_SendCharInfo)
|
||||||
|
|||||||
@ -3157,8 +3157,7 @@ struct SendAA_Struct {
|
|||||||
/*0052*/ uint32 spellid;
|
/*0052*/ uint32 spellid;
|
||||||
/*0056*/ uint32 spell_type;
|
/*0056*/ uint32 spell_type;
|
||||||
/*0060*/ uint32 spell_refresh;
|
/*0060*/ uint32 spell_refresh;
|
||||||
/*0064*/ uint16 classes;
|
/*0064*/ uint32 classes;
|
||||||
/*0066*/ uint16 berserker; //seems to be 1 if its a berserker ability
|
|
||||||
/*0068*/ uint32 max_level;
|
/*0068*/ uint32 max_level;
|
||||||
/*0072*/ uint32 last_id;
|
/*0072*/ uint32 last_id;
|
||||||
/*0076*/ uint32 next_id;
|
/*0076*/ uint32 next_id;
|
||||||
@ -3175,7 +3174,7 @@ struct AA_List {
|
|||||||
struct AA_Action {
|
struct AA_Action {
|
||||||
/*00*/ uint32 action;
|
/*00*/ uint32 action;
|
||||||
/*04*/ uint32 ability;
|
/*04*/ uint32 ability;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 target_id;
|
||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1805,11 +1805,13 @@ namespace UF
|
|||||||
//NOTE: new client supports 300 AAs, our internal rep/PP
|
//NOTE: new client supports 300 AAs, our internal rep/PP
|
||||||
//only supports 240..
|
//only supports 240..
|
||||||
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
||||||
OUT(aa_array[r].AA);
|
eq->aa_array[r].AA = emu->aa_array[r].AA;
|
||||||
OUT(aa_array[r].value);
|
eq->aa_array[r].value = emu->aa_array[r].value;
|
||||||
OUT(aa_array[r].charges);
|
eq->aa_array[r].charges = emu->aa_array[r].charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OUT(unknown02220[4]);
|
// OUT(unknown02220[4]);
|
||||||
|
|
||||||
OUT(mana);
|
OUT(mana);
|
||||||
OUT(cur_hp);
|
OUT(cur_hp);
|
||||||
OUT(STR);
|
OUT(STR);
|
||||||
@ -1939,8 +1941,8 @@ namespace UF
|
|||||||
OUT(copper_bank);
|
OUT(copper_bank);
|
||||||
OUT(platinum_shared);
|
OUT(platinum_shared);
|
||||||
// OUT(unknown13156[84]);
|
// OUT(unknown13156[84]);
|
||||||
//OUT(expansions);
|
OUT(expansions);
|
||||||
eq->expansions = 0xffff;
|
//eq->expansions = 0x1ffff;
|
||||||
// OUT(unknown13244[12]);
|
// OUT(unknown13244[12]);
|
||||||
OUT(autosplit);
|
OUT(autosplit);
|
||||||
// OUT(unknown13260[16]);
|
// OUT(unknown13260[16]);
|
||||||
@ -2128,7 +2130,7 @@ namespace UF
|
|||||||
|
|
||||||
eq->aa_spent = emu->aa_spent;
|
eq->aa_spent = emu->aa_spent;
|
||||||
eq->aa_assigned = emu->aa_spent;
|
eq->aa_assigned = emu->aa_spent;
|
||||||
eq->aa_spent3 = emu->aa_spent;
|
eq->aa_spent3 = 0;
|
||||||
eq->unknown012 = 0;
|
eq->unknown012 = 0;
|
||||||
eq->unknown016 = 0;
|
eq->unknown016 = 0;
|
||||||
eq->unknown020 = 0;
|
eq->unknown020 = 0;
|
||||||
@ -2145,55 +2147,56 @@ namespace UF
|
|||||||
|
|
||||||
ENCODE(OP_SendAATable)
|
ENCODE(OP_SendAATable)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_ATLEAST(SendAA_Struct);
|
EQApplicationPacket *inapp = *p;
|
||||||
SETUP_VAR_ENCODE(SendAA_Struct);
|
*p = nullptr;
|
||||||
ALLOC_VAR_ENCODE(structs::SendAA_Struct, sizeof(structs::SendAA_Struct) + emu->total_abilities*sizeof(structs::AA_Ability));
|
AARankInfo_Struct *emu = (AARankInfo_Struct*)inapp->pBuffer;
|
||||||
|
|
||||||
// Check clientver field to verify this AA should be sent for SoF
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability));
|
||||||
// clientver 1 is for all clients and 6 is for Underfoot
|
structs::SendAA_Struct *eq = (structs::SendAA_Struct*)outapp->pBuffer;
|
||||||
if (emu->clientver <= 6)
|
|
||||||
{
|
inapp->SetReadPosition(sizeof(AARankInfo_Struct));
|
||||||
OUT(id);
|
outapp->SetWritePosition(sizeof(structs::SendAA_Struct));
|
||||||
|
|
||||||
|
eq->id = emu->id;
|
||||||
eq->unknown004 = 1;
|
eq->unknown004 = 1;
|
||||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
eq->id = emu->id;
|
||||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
eq->desc_sid = emu->desc_sid;
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->title_sid = emu->title_sid;
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->class_type = emu->level_req;
|
||||||
eq->title_sid = emu->sof_next_skill;
|
eq->cost = emu->cost;
|
||||||
eq->desc_sid = emu->sof_next_skill;
|
eq->seq = emu->seq;
|
||||||
OUT(class_type);
|
eq->current_level = emu->current_level;
|
||||||
OUT(cost);
|
eq->type = emu->type;
|
||||||
OUT(seq);
|
eq->spellid = emu->spell;
|
||||||
OUT(current_level);
|
eq->spell_type = emu->spell_type;
|
||||||
OUT(prereq_skill);
|
eq->spell_refresh = emu->spell_refresh;
|
||||||
OUT(prereq_minpoints);
|
eq->classes = emu->classes;
|
||||||
eq->type = emu->sof_type;
|
eq->max_level = emu->max_level;
|
||||||
OUT(spellid);
|
eq->last_id = emu->prev_id;
|
||||||
OUT(spell_type);
|
eq->next_id = emu->next_id;
|
||||||
OUT(spell_refresh);
|
eq->cost2 = emu->total_cost;
|
||||||
OUT(classes);
|
eq->grant_only = emu->grant_only;
|
||||||
OUT(berserker);
|
eq->expendable_charges = emu->charges;
|
||||||
//eq->max_level = emu->sof_max_level;
|
eq->aa_expansion = emu->expansion;
|
||||||
OUT(max_level);
|
eq->special_category = emu->category;
|
||||||
OUT(last_id);
|
eq->total_abilities = emu->total_effects;
|
||||||
OUT(next_id);
|
|
||||||
OUT(cost2);
|
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->abilities[i].skill_id = inapp->ReadUInt32();
|
||||||
eq->special_category = emu->special_category;
|
eq->abilities[i].base1 = inapp->ReadUInt32();
|
||||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
eq->abilities[i].base2 = inapp->ReadUInt32();
|
||||||
OUT(total_abilities);
|
eq->abilities[i].slot = inapp->ReadUInt32();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
ENCODE(OP_SendCharInfo)
|
||||||
|
|||||||
@ -3886,8 +3886,7 @@ struct SendAA_Struct {
|
|||||||
/*0049*/ uint32 spellid;
|
/*0049*/ uint32 spellid;
|
||||||
/*0053*/ uint32 spell_type;
|
/*0053*/ uint32 spell_type;
|
||||||
/*0057*/ uint32 spell_refresh;
|
/*0057*/ uint32 spell_refresh;
|
||||||
/*0061*/ uint16 classes;
|
/*0061*/ uint32 classes;
|
||||||
/*0063*/ uint16 berserker; //seems to be 1 if its a berserker ability
|
|
||||||
/*0065*/ uint32 max_level;
|
/*0065*/ uint32 max_level;
|
||||||
/*0069*/ uint32 last_id;
|
/*0069*/ uint32 last_id;
|
||||||
/*0073*/ uint32 next_id;
|
/*0073*/ uint32 next_id;
|
||||||
@ -3913,7 +3912,7 @@ struct AA_List {
|
|||||||
struct AA_Action {
|
struct AA_Action {
|
||||||
/*00*/ uint32 action;
|
/*00*/ uint32 action;
|
||||||
/*04*/ uint32 ability;
|
/*04*/ uint32 ability;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 target_id;
|
||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -139,8 +139,4 @@ protected:
|
|||||||
std::map<pTimerType, PersistentTimer *> _list;
|
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
|
#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_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, 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_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, 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_INT(Character, OrnamentationAugmentType, 20) //Ornamentation Augment Type
|
||||||
RULE_REAL(Character, EnvironmentDamageMulipliter, 1)
|
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, 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, 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_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_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_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.
|
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].not_extendable = atoi(row[197]) != 0;
|
||||||
sp[tempid].suspendable = atoi(row[200]) != 0;
|
sp[tempid].suspendable = atoi(row[200]) != 0;
|
||||||
sp[tempid].viral_range = atoi(row[201]);
|
sp[tempid].viral_range = atoi(row[201]);
|
||||||
|
sp[tempid].songcap = atoi(row[202]);
|
||||||
sp[tempid].no_block = atoi(row[205]);
|
sp[tempid].no_block = atoi(row[205]);
|
||||||
sp[tempid].spellgroup=atoi(row[207]);
|
sp[tempid].spellgroup=atoi(row[207]);
|
||||||
sp[tempid].rank = atoi(row[208]);
|
sp[tempid].rank = atoi(row[208]);
|
||||||
|
|||||||
@ -381,47 +381,47 @@ typedef enum {
|
|||||||
#define SE_GiveDoubleAttack 225 // implemented[AA] - Allow any class to double attack with set chance.
|
#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_TwoHandBash 226 // *not implemented as bonus
|
||||||
#define SE_ReduceSkillTimer 227 // implemented
|
#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_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_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_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_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_ChannelChanceSpells 235 // implemented[AA] - chance to channel from SPELLS *No longer used on live.
|
||||||
//#define SE_FreePet 236 // not used
|
//#define SE_FreePet 236 // not used
|
||||||
#define SE_GivePetGroupTarget 237 // implemented[AA] - (Pet Affinity)
|
#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_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_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_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_IncreaseChanceMemwipe 242 // implemented - increases the chance to wipe hate with memory blurr
|
||||||
#define SE_CharmBreakChance 243 // implemented - Total Domination
|
#define SE_CharmBreakChance 243 // implemented - Total Domination
|
||||||
#define SE_RootBreakChance 244 // implemented[AA] reduce the chance that your root will break.
|
#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_SetBreathLevel 246 // *not implemented as bonus
|
||||||
#define SE_RaiseSkillCap 247 // *not implemented[AA] - adds skill over the skill cap.
|
#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_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_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_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_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_FrontalBackstabMinDmg 253 // implemented[AA] - allow a frontal backstab for mininum damage.
|
||||||
#define SE_Blank 254 // implemented
|
#define SE_Blank 254 // implemented
|
||||||
//#define SE_ShieldDuration 255 // not implemented as bonus - increases duration of /shield
|
#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_ShroudofStealth 256 // not implemented as bonus - rogue improved invs
|
||||||
//#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold
|
#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold
|
||||||
#define SE_TripleBackstab 258 // implemented[AA] - chance to perform a triple backstab
|
#define SE_TripleBackstab 258 // implemented[AA] - chance to perform a triple backstab
|
||||||
#define SE_CombatStability 259 // implemented[AA] - damage mitigation
|
#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_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_SongModCap 261 // implemented[AA] - Song Mod cap increase (no longer used on live)
|
||||||
#define SE_RaiseStatCap 262 // implemented
|
#define SE_RaiseStatCap 262 // implemented
|
||||||
//#define SE_TradeSkillMastery 263 // not implemented - lets you raise more than one tradeskill above master.
|
#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_HastenedAASkill 264 // implemented
|
||||||
#define SE_MasteryofPast 265 // implemented[AA] - Spells less than effect values level can not be fizzled
|
#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_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_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_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_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
|
#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_FinishingBlow 278 // implemented[AA] - chance to do massive damage under 10% HP (base1 = chance, base2 = damage)
|
||||||
#define SE_Flurry 279 // implemented
|
#define SE_Flurry 279 // implemented
|
||||||
#define SE_PetFlurry 280 // implemented[AA]
|
#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_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_DoubleSpecialAttack 283 // implemented[AA] - Chance to perform second special attack as monk
|
||||||
//#define SE_LoHSetHeal 284 // not used
|
//#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_FcDamageAmt 286 // implemented - adds direct spell damage
|
||||||
#define SE_SpellDurationIncByTic 287 // implemented
|
#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_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_IncreaseRunSpeedCap 290 // implemented[AA] - increases run speed over the hard cap
|
||||||
#define SE_Purify 291 // implemented - Removes determental effects
|
#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_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_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_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_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_BandolierSlots 363 // *not implemented[AA] 'Battle Ready' expands the bandolier by one additional save slot per rank.
|
||||||
#define SE_TripleAttackChance 364 // implemented
|
#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_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
|
#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_CorruptionCounter 369 // implemented
|
||||||
#define SE_ResistCorruption 370 // implemented
|
#define SE_ResistCorruption 370 // implemented
|
||||||
#define SE_AttackSpeed4 371 // implemented - stackable slow effect 'Inhibit Melee'
|
#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_CastOnFadeEffectAlways 373 // implemented - Triggers if fades after natural duration OR from rune/numhits fades.
|
||||||
#define SE_ApplyEffect 374 // implemented
|
#define SE_ApplyEffect 374 // implemented
|
||||||
#define SE_DotCritDmgIncrease 375 // implemented - Increase damage of DoT critical amount
|
#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_SummonCorpseZone 388 // *not implemented - summons a corpse from any zone(nec AA)
|
||||||
#define SE_FcTimerRefresh 389 // implemented - Refresh spell icons
|
#define SE_FcTimerRefresh 389 // implemented - Refresh spell icons
|
||||||
//#define SE_FcTimerLockout 390 // *not implemented - Sets recast timers to specific value, focus limited.
|
//#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_FcHealAmt 392 // implemented - Adds or removes healing from spells
|
||||||
#define SE_FcHealPctIncoming 393 // implemented - HealRate with focus restrictions.
|
#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.
|
#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_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_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_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_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_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.
|
#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 */
|
/* 198- 199 */
|
||||||
/* 200 */ bool suspendable; // buff is suspended in suspended buff zones
|
/* 200 */ bool suspendable; // buff is suspended in suspended buff zones
|
||||||
/* 201 */ int viral_range;
|
/* 201 */ int viral_range;
|
||||||
/* 202 */
|
/* 202 */ int songcap; // individual song cap
|
||||||
/* 203 */ //int songcap; // individual song cap (how live currently does it, not implemented)
|
/* 203 */
|
||||||
/* 204 */
|
/* 204 */
|
||||||
/* 205 */ bool no_block;
|
/* 205 */ bool no_block;
|
||||||
/* 206 */
|
/* 206 */
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9085
|
#define CURRENT_BINARY_DATABASE_VERSION 9086
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
|||||||
@ -353,6 +353,7 @@ OP_OpenContainer=0x0000
|
|||||||
OP_Marquee=0x502e
|
OP_Marquee=0x502e
|
||||||
OP_ItemRecastDelay=0x15a9
|
OP_ItemRecastDelay=0x15a9
|
||||||
#OP_OpenInventory=0x0000 # Likely does not exist in RoF -U
|
#OP_OpenInventory=0x0000 # Likely does not exist in RoF -U
|
||||||
|
OP_ResetAA=0x1669
|
||||||
|
|
||||||
# Expeditions
|
# Expeditions
|
||||||
OP_DzAddPlayer=0x4701
|
OP_DzAddPlayer=0x4701
|
||||||
|
|||||||
@ -339,7 +339,7 @@
|
|||||||
9083|2015_06_07_aa_update.sql|SHOW COLUMNS FROM `character_alternate_abilities` LIKE 'charges'|empty|
|
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|
|
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|
|
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:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
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() {
|
void Client::SendExpansionInfo() {
|
||||||
auto outapp = new EQApplicationPacket(OP_ExpansionInfo, sizeof(ExpansionInfo_Struct));
|
auto outapp = new EQApplicationPacket(OP_ExpansionInfo, sizeof(ExpansionInfo_Struct));
|
||||||
ExpansionInfo_Struct *eis = (ExpansionInfo_Struct*)outapp->pBuffer;
|
ExpansionInfo_Struct *eis = (ExpansionInfo_Struct*)outapp->pBuffer;
|
||||||
|
if(RuleB(World, UseClientBasedExpansionSettings)) {
|
||||||
|
eis->Expansions = ExpansionFromClientVersion(eqs->GetClientVersion());
|
||||||
|
//eis->Expansions = ExpansionFromClientVersion(this->GetCLE.
|
||||||
|
} else {
|
||||||
eis->Expansions = (RuleI(World, ExpansionSettings));
|
eis->Expansions = (RuleI(World, ExpansionSettings));
|
||||||
|
}
|
||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
|||||||
|
|
||||||
SET(zone_sources
|
SET(zone_sources
|
||||||
aa.cpp
|
aa.cpp
|
||||||
|
aa_ability.cpp
|
||||||
aggro.cpp
|
aggro.cpp
|
||||||
attack.cpp
|
attack.cpp
|
||||||
beacon.cpp
|
beacon.cpp
|
||||||
@ -126,6 +127,7 @@ SET(zone_sources
|
|||||||
|
|
||||||
SET(zone_headers
|
SET(zone_headers
|
||||||
aa.h
|
aa.h
|
||||||
|
aa_ability.h
|
||||||
basic_functions.h
|
basic_functions.h
|
||||||
beacon.h
|
beacon.h
|
||||||
bot.h
|
bot.h
|
||||||
|
|||||||
2272
zone/aa.cpp
2272
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
|
#ifndef AA_H
|
||||||
#define 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)
|
#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 {
|
typedef enum {
|
||||||
aaActionNone = 0,
|
aaActionNone = 0,
|
||||||
aaActionAETaunt = 1,
|
aaActionAETaunt = 1,
|
||||||
@ -42,21 +23,6 @@ typedef enum {
|
|||||||
aaActionFadingMemories = 16
|
aaActionFadingMemories = 16
|
||||||
} aaNonspellAction;
|
} 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
|
enum { //leadership AA indexes
|
||||||
groupAAMarkNPC = 0,
|
groupAAMarkNPC = 0,
|
||||||
groupAANPCHealth,
|
groupAANPCHealth,
|
||||||
@ -133,571 +99,6 @@ static const uint8 LeadershipAACosts[_maxLeaderAA][MAX_LEADERSHIP_TIERS] = {
|
|||||||
{ 0, 0, 0, 0, 0, 0 }, //raidAA15
|
{ 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
|
typedef enum { //AA IDs
|
||||||
aaNone =0,
|
aaNone =0,
|
||||||
aaInnateStrength =2,//implemented as bonus
|
aaInnateStrength =2,//implemented as bonus
|
||||||
@ -2109,21 +1510,6 @@ typedef enum { //AA IDs
|
|||||||
//follow the highest AA ID
|
//follow the highest AA ID
|
||||||
} aaID;
|
} 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
|
//Structure representing the database's swarm pet configs
|
||||||
struct AA_SwarmPet {
|
struct AA_SwarmPet {
|
||||||
uint8 count; //number to summon
|
uint8 count; //number to summon
|
||||||
@ -2131,23 +1517,6 @@ struct AA_SwarmPet {
|
|||||||
uint16 duration; //how long they last, in seconds
|
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
|
enum { //values of AA_Action.action
|
||||||
aaActionActivate = 0,
|
aaActionActivate = 0,
|
||||||
aaActionSetEXP = 1,
|
aaActionSetEXP = 1,
|
||||||
@ -2167,4 +1536,11 @@ public:
|
|||||||
uint32 owner_id;
|
uint32 owner_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum AATimers
|
||||||
|
{
|
||||||
|
aaTimerRampage,
|
||||||
|
aaTimerWarcry,
|
||||||
|
aaTimerMax
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#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
|
||||||
119
zone/attack.cpp
119
zone/attack.cpp
@ -1372,6 +1372,13 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
////// Send Attack Damage
|
////// 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);
|
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse);
|
||||||
|
|
||||||
if (IsDead()) return false;
|
if (IsDead()) return false;
|
||||||
@ -3512,14 +3519,6 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
|||||||
if(damage > 0) {
|
if(damage > 0) {
|
||||||
//if there is some damage being done and theres an attacker involved
|
//if there is some damage being done and theres an attacker involved
|
||||||
if(attacker) {
|
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 is lifetap add hp to the caster
|
||||||
if (spell_id != SPELL_UNKNOWN && IsLifetapSpell( spell_id )) {
|
if (spell_id != SPELL_UNKNOWN && IsLifetapSpell( spell_id )) {
|
||||||
int healed = damage;
|
int healed = damage;
|
||||||
@ -4416,41 +4415,54 @@ bool Mob::TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::DoRiposte(Mob* defender) {
|
void Mob::DoRiposte(Mob *defender)
|
||||||
|
{
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a riposte");
|
Log.Out(Logs::Detail, Logs::Combat, "Preforming a riposte");
|
||||||
|
|
||||||
if (!defender)
|
if (!defender)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
defender->Attack(this, MainPrimary, true);
|
defender->Attack(this, MainPrimary, true);
|
||||||
if (HasDied()) return;
|
if (HasDied())
|
||||||
|
return;
|
||||||
|
|
||||||
int32 DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[0] +
|
// this effect isn't used on live? See no AAs or spells
|
||||||
defender->spellbonuses.GiveDoubleRiposte[0] +
|
int32 DoubleRipChance = defender->aabonuses.DoubleRiposte + defender->spellbonuses.DoubleRiposte +
|
||||||
defender->itembonuses.GiveDoubleRiposte[0];
|
|
||||||
|
|
||||||
DoubleRipChance = defender->aabonuses.DoubleRiposte +
|
|
||||||
defender->spellbonuses.DoubleRiposte +
|
|
||||||
defender->itembonuses.DoubleRiposte;
|
defender->itembonuses.DoubleRiposte;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[0] + defender->spellbonuses.GiveDoubleRiposte[0] +
|
||||||
|
defender->itembonuses.GiveDoubleRiposte[0];
|
||||||
|
|
||||||
// Live AA - Double Riposte
|
// Live AA - Double Riposte
|
||||||
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a double riposed (%d percent chance)", 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);
|
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).
|
// 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]
|
// Coded narrowly: Limit to one per client. Limit AA only. [1 = Skill Attack Chance, 2 = Skill]
|
||||||
|
|
||||||
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
|
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
|
||||||
|
|
||||||
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a return SPECIAL ATTACK (%d percent chance)", DoubleRipChance);
|
Log.Out(Logs::Detail, Logs::Combat, "Preforming a return SPECIAL ATTACK (%d percent chance)",
|
||||||
|
DoubleRipChance);
|
||||||
|
|
||||||
if (defender->GetClass() == MONK)
|
if (defender->GetClass() == MONK)
|
||||||
defender->MonkSpecialAttack(this, defender->aabonuses.GiveDoubleRiposte[2]);
|
defender->MonkSpecialAttack(this, defender->aabonuses.GiveDoubleRiposte[2]);
|
||||||
else if (defender->IsClient())
|
else if (defender->IsClient() && defender->CastToClient()->HasSkill((SkillUseTypes)defender->aabonuses.GiveDoubleRiposte[2]))
|
||||||
defender->CastToClient()->DoClassAttacks(this, defender->aabonuses.GiveDoubleRiposte[2], true);
|
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]){
|
if (IsClient() && aabonuses.LimitToSkill[skill]){
|
||||||
|
|
||||||
CanProc = true;
|
CanProc = true;
|
||||||
uint32 effect = 0;
|
uint32 effect_id = 0;
|
||||||
int32 base1 = 0;
|
int32 base1 = 0;
|
||||||
int32 base2 = 0;
|
int32 base2 = 0;
|
||||||
uint32 slot = 0;
|
uint32 slot = 0;
|
||||||
@ -4662,22 +4674,26 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
|
|||||||
proc_spell_id = 0;
|
proc_spell_id = 0;
|
||||||
ProcMod = 0;
|
ProcMod = 0;
|
||||||
|
|
||||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aaid);
|
for(auto &rank_info : aa_ranks) {
|
||||||
if(find_iter == aa_effects.end())
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_info.first, rank_info.second.first);
|
||||||
break;
|
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) {
|
if(!ability) {
|
||||||
effect = iter->second.skill_id;
|
continue;
|
||||||
base1 = iter->second.base1;
|
}
|
||||||
base2 = iter->second.base2;
|
|
||||||
slot = iter->second.slot;
|
|
||||||
|
|
||||||
if (effect == SE_SkillProc || effect == SE_SkillProcSuccess) {
|
for(auto &effect : rank->effects) {
|
||||||
|
effect_id = effect.effect_id;
|
||||||
|
base1 = effect.base1;
|
||||||
|
base2 = effect.base2;
|
||||||
|
slot = effect.slot;
|
||||||
|
|
||||||
|
if(effect_id == SE_SkillProc || effect_id == SE_SkillProcSuccess) {
|
||||||
proc_spell_id = base1;
|
proc_spell_id = base1;
|
||||||
ProcMod = static_cast<float>(base2);
|
ProcMod = static_cast<float>(base2);
|
||||||
}
|
}
|
||||||
|
else if(effect_id == SE_LimitToSkill && base1 <= HIGHEST_SKILL) {
|
||||||
else if (effect == SE_LimitToSkill && base1 <= HIGHEST_SKILL) {
|
|
||||||
|
|
||||||
if (CanProc && base1 == skill && IsValidSpell(proc_spell_id)) {
|
if (CanProc && base1 == skill && IsValidSpell(proc_spell_id)) {
|
||||||
float final_chance = chance * (ProcMod / 100.0f);
|
float final_chance = chance * (ProcMod / 100.0f);
|
||||||
@ -4698,6 +4714,7 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float Mob::GetSkillProcChances(uint16 ReuseTime, uint16 hand) {
|
float Mob::GetSkillProcChances(uint16 ReuseTime, uint16 hand) {
|
||||||
|
|
||||||
@ -5042,3 +5059,39 @@ void NPC::SetAttackTimer()
|
|||||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
387
zone/bonuses.cpp
387
zone/bonuses.cpp
@ -42,6 +42,7 @@
|
|||||||
void Mob::CalcBonuses()
|
void Mob::CalcBonuses()
|
||||||
{
|
{
|
||||||
CalcSpellBonuses(&spellbonuses);
|
CalcSpellBonuses(&spellbonuses);
|
||||||
|
CalcAABonuses(&aabonuses);
|
||||||
CalcMaxHP();
|
CalcMaxHP();
|
||||||
CalcMaxMana();
|
CalcMaxMana();
|
||||||
SetAttackTimer();
|
SetAttackTimer();
|
||||||
@ -51,9 +52,7 @@ void Mob::CalcBonuses()
|
|||||||
|
|
||||||
void NPC::CalcBonuses()
|
void NPC::CalcBonuses()
|
||||||
{
|
{
|
||||||
Mob::CalcBonuses();
|
memset(&itembonuses, 0, sizeof(StatBonuses));
|
||||||
memset(&aabonuses, 0, sizeof(StatBonuses));
|
|
||||||
|
|
||||||
if(RuleB(NPC, UseItemBonusesForNonPets)){
|
if(RuleB(NPC, UseItemBonusesForNonPets)){
|
||||||
memset(&itembonuses, 0, sizeof(StatBonuses));
|
memset(&itembonuses, 0, sizeof(StatBonuses));
|
||||||
CalcItemBonuses(&itembonuses);
|
CalcItemBonuses(&itembonuses);
|
||||||
@ -74,12 +73,8 @@ void Client::CalcBonuses()
|
|||||||
memset(&itembonuses, 0, sizeof(StatBonuses));
|
memset(&itembonuses, 0, sizeof(StatBonuses));
|
||||||
CalcItemBonuses(&itembonuses);
|
CalcItemBonuses(&itembonuses);
|
||||||
CalcEdibleBonuses(&itembonuses);
|
CalcEdibleBonuses(&itembonuses);
|
||||||
|
|
||||||
CalcSpellBonuses(&spellbonuses);
|
CalcSpellBonuses(&spellbonuses);
|
||||||
|
CalcAABonuses(&aabonuses);
|
||||||
Log.Out(Logs::Detail, Logs::AA, "Calculating AA Bonuses for %s.", this->GetCleanName());
|
|
||||||
CalcAABonuses(&aabonuses); //we're not quite ready for this
|
|
||||||
Log.Out(Logs::Detail, Logs::AA, "Finished calculating AA Bonuses for %s.", this->GetCleanName());
|
|
||||||
|
|
||||||
ProcessItemCaps(); // caps that depend on spell/aa bonuses
|
ProcessItemCaps(); // caps that depend on spell/aa bonuses
|
||||||
|
|
||||||
@ -113,6 +108,9 @@ void Client::CalcBonuses()
|
|||||||
rooted = FindType(SE_Root);
|
rooted = FindType(SE_Root);
|
||||||
|
|
||||||
XPRate = 100 + spellbonuses.XPRateMod;
|
XPRate = 100 + spellbonuses.XPRateMod;
|
||||||
|
|
||||||
|
if (GetMaxXTargets() != 5 + aabonuses.extra_xtargets)
|
||||||
|
SetMaxXTargets(5 + aabonuses.extra_xtargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Client::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat)
|
int Client::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat)
|
||||||
@ -632,77 +630,70 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::CalcAABonuses(StatBonuses* newbon) {
|
void Mob::CalcAABonuses(StatBonuses *newbon)
|
||||||
|
{
|
||||||
memset(newbon, 0, sizeof(StatBonuses)); // start fresh
|
memset(newbon, 0, sizeof(StatBonuses)); // start fresh
|
||||||
|
|
||||||
int i;
|
for (const auto &aa : aa_ranks) {
|
||||||
uint32 slots = 0;
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa.first, aa.second.first);
|
||||||
uint32 aa_AA = 0;
|
auto ability = ability_rank.first;
|
||||||
uint32 aa_value = 0;
|
auto rank = ability_rank.second;
|
||||||
if(this->aa) {
|
|
||||||
for (i = 0; i < MAX_PP_AA_ARRAY; i++) { //iterate through all of the client's AAs
|
if(!ability) {
|
||||||
if (this->aa[i]) { // make sure aa exists or we'll crash zone
|
continue;
|
||||||
aa_AA = this->aa[i]->AA; //same as aaid from the aa_effects table
|
|
||||||
aa_value = this->aa[i]->value; //how many points in it
|
|
||||||
if (aa_AA > 0 || aa_value > 0) { //do we have the AA? if 1 of the 2 is set, we can assume we do
|
|
||||||
//slots = database.GetTotalAALevels(aa_AA); //find out how many effects from aa_effects table
|
|
||||||
slots = zone->GetTotalAALevels(aa_AA); //find out how many effects from aa_effects, which is loaded into memory
|
|
||||||
if (slots > 0) //and does it have any effects? may be able to put this above, not sure if it runs on each iteration
|
|
||||||
ApplyAABonuses(aa_AA, slots, newbon); //add the bonuses
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bad data or no effects
|
||||||
|
if (rank->effects.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ApplyAABonuses(*rank, newbon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//A lot of the normal spell functions (IsBlankSpellEffect, etc) are set for just spells (in common/spdat.h).
|
//A lot of the normal spell functions (IsBlankSpellEffect, etc) are set for just spells (in common/spdat.h).
|
||||||
//For now, we'll just put them directly into the code and comment with the corresponding normal function
|
//For now, we'll just put them directly into the code and comment with the corresponding normal function
|
||||||
//Maybe we'll fix it later? :-D
|
//Maybe we'll fix it later? :-D
|
||||||
void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||||
{
|
{
|
||||||
if(slots == 0) //sanity check. why bother if no slots to fill?
|
if (rank.effects.empty()) // sanity check. why bother if no slots to fill?
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//from AA_Ability struct
|
|
||||||
uint32 effect = 0;
|
uint32 effect = 0;
|
||||||
int32 base1 = 0;
|
int32 base1 = 0;
|
||||||
int32 base2 = 0; // only really used for SE_RaiseStatCap & SE_ReduceSkillTimer in aa_effects table
|
int32 base2 = 0; // only really used for SE_RaiseStatCap & SE_ReduceSkillTimer in aa_effects table
|
||||||
uint32 slot = 0;
|
uint32 slot = 0;
|
||||||
|
|
||||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aaid);
|
for (const auto &e : rank.effects) {
|
||||||
if(find_iter == aa_effects.end())
|
effect = e.effect_id;
|
||||||
{
|
base1 = e.base1;
|
||||||
return;
|
base2 = e.base2;
|
||||||
}
|
slot = e.slot;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// we default to 0 (SE_CurrentHP) for the effect, so if there aren't any base1/2 values, we'll just skip it
|
// we default to 0 (SE_CurrentHP) for the effect, so if there aren't any base1/2 values, we'll just skip it
|
||||||
if (effect == 0 && base1 == 0 && base2 == 0)
|
if (effect == 0 && base1 == 0 && base2 == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// IsBlankSpellEffect()
|
// IsBlankSpellEffect()
|
||||||
if (effect == SE_Blank || (effect == SE_CHA && base1 == 0) || effect == SE_StackingCommand_Block || effect == SE_StackingCommand_Overwrite)
|
if (effect == SE_Blank || (effect == SE_CHA && base1 == 0) || effect == SE_StackingCommand_Block ||
|
||||||
|
effect == SE_StackingCommand_Overwrite)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::AA, "Applying Effect %d from AA %u in slot %d (base1: %d, base2: %d) on %s", effect, aaid, slot, base1, base2, this->GetCleanName());
|
Log.Out(Logs::Detail, Logs::AA, "Applying Effect %d from AA %u in slot %d (base1: %d, base2: %d) on %s",
|
||||||
|
effect, rank.id, slot, base1, base2, GetCleanName());
|
||||||
|
|
||||||
uint8 focus = IsFocusEffect(0, 0, true, effect);
|
uint8 focus = IsFocusEffect(0, 0, true, effect);
|
||||||
if (focus)
|
if (focus) {
|
||||||
{
|
|
||||||
newbon->FocusEffects[focus] = static_cast<uint8>(effect);
|
newbon->FocusEffects[focus] = static_cast<uint8>(effect);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (effect)
|
switch (effect) {
|
||||||
{
|
|
||||||
// Note: AA effects that use accuracy are skill limited, while spell effect is not.
|
// Note: AA effects that use accuracy are skill limited, while spell effect is not.
|
||||||
case SE_Accuracy:
|
case SE_Accuracy:
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if ((base2 == ALL_SKILLS) && (newbon->Accuracy[HIGHEST_SKILL + 1] < base1))
|
if ((base2 == ALL_SKILLS) && (newbon->Accuracy[HIGHEST_SKILL + 1] < base1))
|
||||||
newbon->Accuracy[HIGHEST_SKILL + 1] = base1;
|
newbon->Accuracy[HIGHEST_SKILL + 1] = base1;
|
||||||
else if (newbon->Accuracy[base2] < base1)
|
else if (newbon->Accuracy[base2] < base1)
|
||||||
@ -746,6 +737,9 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
case SE_CurrentMana:
|
case SE_CurrentMana:
|
||||||
newbon->ManaRegen += base1;
|
newbon->ManaRegen += base1;
|
||||||
break;
|
break;
|
||||||
|
case SE_ManaPool:
|
||||||
|
newbon->Mana += base1;
|
||||||
|
break;
|
||||||
case SE_ItemManaRegenCapIncrease:
|
case SE_ItemManaRegenCapIncrease:
|
||||||
newbon->ItemManaRegenCap += base1;
|
newbon->ItemManaRegenCap += base1;
|
||||||
break;
|
break;
|
||||||
@ -782,8 +776,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
case SE_SetBreathLevel:
|
case SE_SetBreathLevel:
|
||||||
break;
|
break;
|
||||||
case SE_RaiseStatCap:
|
case SE_RaiseStatCap:
|
||||||
switch(base2)
|
switch (base2) {
|
||||||
{
|
|
||||||
// are these #define'd somewhere?
|
// are these #define'd somewhere?
|
||||||
case 0: // str
|
case 0: // str
|
||||||
newbon->STRCapMod += base1;
|
newbon->STRCapMod += base1;
|
||||||
@ -826,8 +819,6 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SE_PetDiscipline2:
|
|
||||||
break;
|
|
||||||
case SE_SpellSlotIncrease:
|
case SE_SpellSlotIncrease:
|
||||||
break;
|
break;
|
||||||
case SE_MysticalAttune:
|
case SE_MysticalAttune:
|
||||||
@ -939,8 +930,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
newbon->CombatStability += base1;
|
newbon->CombatStability += base1;
|
||||||
break;
|
break;
|
||||||
case SE_AddSingingMod:
|
case SE_AddSingingMod:
|
||||||
switch (base2)
|
switch (base2) {
|
||||||
{
|
|
||||||
case ItemTypeWindInstrument:
|
case ItemTypeWindInstrument:
|
||||||
newbon->windMod += base1;
|
newbon->windMod += base1;
|
||||||
break;
|
break;
|
||||||
@ -1043,8 +1033,10 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
newbon->CrippBlowChance += base1;
|
newbon->CrippBlowChance += base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_HitChance:
|
case SE_HitChance: {
|
||||||
{
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if (base2 == ALL_SKILLS)
|
if (base2 == ALL_SKILLS)
|
||||||
newbon->HitChanceEffect[HIGHEST_SKILL + 1] += base1;
|
newbon->HitChanceEffect[HIGHEST_SKILL + 1] += base1;
|
||||||
else
|
else
|
||||||
@ -1052,16 +1044,16 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SE_ProcOnKillShot:
|
case SE_ProcOnKillShot:
|
||||||
for(int i = 0; i < MAX_SPELL_TRIGGER*3; i+=3)
|
for (int i = 0; i < MAX_SPELL_TRIGGER * 3; i += 3) {
|
||||||
{
|
if (!newbon->SpellOnKill[i] ||
|
||||||
if(!newbon->SpellOnKill[i] || ((newbon->SpellOnKill[i] == base2) && (newbon->SpellOnKill[i+1] < base1)))
|
((newbon->SpellOnKill[i] == base2) && (newbon->SpellOnKill[i + 1] < base1))) {
|
||||||
{
|
|
||||||
// base1 = chance, base2 = SpellID to be triggered, base3 = min npc level
|
// base1 = chance, base2 = SpellID to be triggered, base3 = min npc level
|
||||||
newbon->SpellOnKill[i] = base2;
|
newbon->SpellOnKill[i] = base2;
|
||||||
newbon->SpellOnKill[i + 1] = base1;
|
newbon->SpellOnKill[i + 1] = base1;
|
||||||
|
|
||||||
if (GetLevel() > 15)
|
if (GetLevel() > 15)
|
||||||
newbon->SpellOnKill[i+2] = GetLevel() - 15; //AA specifiy "non-trivial"
|
newbon->SpellOnKill[i + 2] =
|
||||||
|
GetLevel() - 15; // AA specifiy "non-trivial"
|
||||||
else
|
else
|
||||||
newbon->SpellOnKill[i + 2] = 0;
|
newbon->SpellOnKill[i + 2] = 0;
|
||||||
|
|
||||||
@ -1071,10 +1063,8 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_SpellOnDeath:
|
case SE_SpellOnDeath:
|
||||||
for(int i = 0; i < MAX_SPELL_TRIGGER*2; i+=2)
|
for (int i = 0; i < MAX_SPELL_TRIGGER * 2; i += 2) {
|
||||||
{
|
if (!newbon->SpellOnDeath[i]) {
|
||||||
if(!newbon->SpellOnDeath[i])
|
|
||||||
{
|
|
||||||
// base1 = SpellID to be triggered, base2 = chance to fire
|
// base1 = SpellID to be triggered, base2 = chance to fire
|
||||||
newbon->SpellOnDeath[i] = base1;
|
newbon->SpellOnDeath[i] = base1;
|
||||||
newbon->SpellOnDeath[i + 1] = base2;
|
newbon->SpellOnDeath[i + 1] = base2;
|
||||||
@ -1085,31 +1075,32 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
|
|
||||||
case SE_TriggerOnCast:
|
case SE_TriggerOnCast:
|
||||||
|
|
||||||
for(int i = 0; i < MAX_SPELL_TRIGGER; i++)
|
for (int i = 0; i < MAX_SPELL_TRIGGER; i++) {
|
||||||
{
|
if (newbon->SpellTriggers[i] == rank.id)
|
||||||
if (newbon->SpellTriggers[i] == aaid)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(!newbon->SpellTriggers[i])
|
if (!newbon->SpellTriggers[i]) {
|
||||||
{
|
// Save the 'rank.id' of each triggerable effect to an array
|
||||||
//Save the 'aaid' of each triggerable effect to an array
|
newbon->SpellTriggers[i] = rank.id;
|
||||||
newbon->SpellTriggers[i] = aaid;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_CriticalHitChance:
|
case SE_CriticalHitChance: {
|
||||||
{
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if (base2 == ALL_SKILLS)
|
if (base2 == ALL_SKILLS)
|
||||||
newbon->CriticalHitChance[HIGHEST_SKILL + 1] += base1;
|
newbon->CriticalHitChance[HIGHEST_SKILL + 1] += base1;
|
||||||
else
|
else
|
||||||
newbon->CriticalHitChance[base2] += base1;
|
newbon->CriticalHitChance[base2] += base1;
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case SE_CriticalDamageMob:
|
case SE_CriticalDamageMob: {
|
||||||
{
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
// base1 = effect value, base2 = skill restrictions(-1 for all)
|
// base1 = effect value, base2 = skill restrictions(-1 for all)
|
||||||
if (base2 == ALL_SKILLS)
|
if (base2 == ALL_SKILLS)
|
||||||
newbon->CritDmgMob[HIGHEST_SKILL + 1] += base1;
|
newbon->CritDmgMob[HIGHEST_SKILL + 1] += base1;
|
||||||
@ -1118,8 +1109,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_CriticalSpellChance:
|
case SE_CriticalSpellChance: {
|
||||||
{
|
|
||||||
newbon->CriticalSpellChance += base1;
|
newbon->CriticalSpellChance += base1;
|
||||||
|
|
||||||
if (base2 > newbon->SpellCritDmgIncNoStack)
|
if (base2 > newbon->SpellCritDmgIncNoStack)
|
||||||
@ -1128,17 +1118,19 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_ResistFearChance:
|
case SE_ResistFearChance: {
|
||||||
{
|
if (base1 == 100) // If we reach 100% in a single spell/item then we should be immune to
|
||||||
if(base1 == 100) // If we reach 100% in a single spell/item then we should be immune to negative fear resist effects until our immunity is over
|
// negative fear resist effects until our immunity is over
|
||||||
newbon->Fearless = true;
|
newbon->Fearless = true;
|
||||||
|
|
||||||
newbon->ResistFearChance += base1; // these should stack
|
newbon->ResistFearChance += base1; // these should stack
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_SkillDamageAmount:
|
case SE_SkillDamageAmount: {
|
||||||
{
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if (base2 == ALL_SKILLS)
|
if (base2 == ALL_SKILLS)
|
||||||
newbon->SkillDamageAmount[HIGHEST_SKILL + 1] += base1;
|
newbon->SkillDamageAmount[HIGHEST_SKILL + 1] += base1;
|
||||||
else
|
else
|
||||||
@ -1146,16 +1138,18 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_SpecialAttackKBProc:
|
case SE_SkillAttackProc: {
|
||||||
{
|
|
||||||
// You can only have one of these per client. [AA Dragon Punch]
|
// You can only have one of these per client. [AA Dragon Punch]
|
||||||
newbon->SpecialAttackKBProc[0] = base1; //Chance base 100 = 25% proc rate
|
newbon->SkillAttackProc[0] = base1; // Chance base 1000 = 100% proc rate
|
||||||
newbon->SpecialAttackKBProc[1] = base2; //Skill to KB Proc Off
|
newbon->SkillAttackProc[1] = base2; // Skill to Proc Off
|
||||||
|
newbon->SkillAttackProc[2] = rank.spell; // spell to proc
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_DamageModifier:
|
case SE_DamageModifier: {
|
||||||
{
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if (base2 == ALL_SKILLS)
|
if (base2 == ALL_SKILLS)
|
||||||
newbon->DamageModifier[HIGHEST_SKILL + 1] += base1;
|
newbon->DamageModifier[HIGHEST_SKILL + 1] += base1;
|
||||||
else
|
else
|
||||||
@ -1163,8 +1157,10 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_DamageModifier2:
|
case SE_DamageModifier2: {
|
||||||
{
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if (base2 == ALL_SKILLS)
|
if (base2 == ALL_SKILLS)
|
||||||
newbon->DamageModifier2[HIGHEST_SKILL + 1] += base1;
|
newbon->DamageModifier2[HIGHEST_SKILL + 1] += base1;
|
||||||
else
|
else
|
||||||
@ -1172,21 +1168,19 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_SlayUndead:
|
case SE_SlayUndead: {
|
||||||
{
|
|
||||||
if (newbon->SlayUndead[1] < base1)
|
if (newbon->SlayUndead[1] < base1)
|
||||||
newbon->SlayUndead[0] = base1; // Rate
|
newbon->SlayUndead[0] = base1; // Rate
|
||||||
newbon->SlayUndead[1] = base2; // Damage Modifier
|
newbon->SlayUndead[1] = base2; // Damage Modifier
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_DoubleRiposte:
|
case SE_DoubleRiposte: {
|
||||||
{
|
|
||||||
newbon->DoubleRiposte += base1;
|
newbon->DoubleRiposte += base1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_GiveDoubleRiposte:
|
case SE_GiveDoubleRiposte: {
|
||||||
{
|
|
||||||
// 0=Regular Riposte 1=Skill Attack Riposte 2=Skill
|
// 0=Regular Riposte 1=Skill Attack Riposte 2=Skill
|
||||||
if (base2 == 0) {
|
if (base2 == 0) {
|
||||||
if (newbon->GiveDoubleRiposte[0] < base1)
|
if (newbon->GiveDoubleRiposte[0] < base1)
|
||||||
@ -1203,8 +1197,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
|
|
||||||
// Kayen: Not sure best way to implement this yet.
|
// Kayen: Not sure best way to implement this yet.
|
||||||
// Physically raises skill cap ie if 55/55 it will raise to 55/60
|
// Physically raises skill cap ie if 55/55 it will raise to 55/60
|
||||||
case SE_RaiseSkillCap:
|
case SE_RaiseSkillCap: {
|
||||||
{
|
|
||||||
if (newbon->RaiseSkillCap[0] < base1) {
|
if (newbon->RaiseSkillCap[0] < base1) {
|
||||||
newbon->RaiseSkillCap[0] = base1; // value
|
newbon->RaiseSkillCap[0] = base1; // value
|
||||||
newbon->RaiseSkillCap[1] = base2; // skill
|
newbon->RaiseSkillCap[1] = base2; // skill
|
||||||
@ -1212,41 +1205,34 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_MasteryofPast:
|
case SE_MasteryofPast: {
|
||||||
{
|
|
||||||
if (newbon->MasteryofPast < base1)
|
if (newbon->MasteryofPast < base1)
|
||||||
newbon->MasteryofPast = base1;
|
newbon->MasteryofPast = base1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_CastingLevel2:
|
case SE_CastingLevel2:
|
||||||
case SE_CastingLevel:
|
case SE_CastingLevel: {
|
||||||
{
|
|
||||||
newbon->effective_casting_level += base1;
|
newbon->effective_casting_level += base1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_DivineSave:
|
case SE_DivineSave: {
|
||||||
{
|
if (newbon->DivineSaveChance[0] < base1) {
|
||||||
if(newbon->DivineSaveChance[0] < base1)
|
|
||||||
{
|
|
||||||
newbon->DivineSaveChance[0] = base1;
|
newbon->DivineSaveChance[0] = base1;
|
||||||
newbon->DivineSaveChance[1] = base2;
|
newbon->DivineSaveChance[1] = base2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SE_SpellEffectResistChance: {
|
||||||
case SE_SpellEffectResistChance:
|
for (int e = 0; e < MAX_RESISTABLE_EFFECTS * 2; e += 2) {
|
||||||
{
|
if (newbon->SEResist[e + 1] && (newbon->SEResist[e] == base2) &&
|
||||||
for(int e = 0; e < MAX_RESISTABLE_EFFECTS*2; e+=2)
|
(newbon->SEResist[e + 1] < base1)) {
|
||||||
{
|
|
||||||
if(newbon->SEResist[e+1] && (newbon->SEResist[e] == base2) && (newbon->SEResist[e+1] < base1)){
|
|
||||||
newbon->SEResist[e] = base2; // Spell Effect ID
|
newbon->SEResist[e] = base2; // Spell Effect ID
|
||||||
newbon->SEResist[e + 1] = base1; // Resist Chance
|
newbon->SEResist[e + 1] = base1; // Resist Chance
|
||||||
break;
|
break;
|
||||||
}
|
} else if (!newbon->SEResist[e + 1]) {
|
||||||
else if (!newbon->SEResist[e+1]){
|
|
||||||
newbon->SEResist[e] = base2; // Spell Effect ID
|
newbon->SEResist[e] = base2; // Spell Effect ID
|
||||||
newbon->SEResist[e + 1] = base1; // Resist Chance
|
newbon->SEResist[e + 1] = base1; // Resist Chance
|
||||||
break;
|
break;
|
||||||
@ -1255,8 +1241,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_MitigateDamageShield:
|
case SE_MitigateDamageShield: {
|
||||||
{
|
|
||||||
if (base1 < 0)
|
if (base1 < 0)
|
||||||
base1 = base1 * (-1);
|
base1 = base1 * (-1);
|
||||||
|
|
||||||
@ -1264,8 +1249,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_FinishingBlow:
|
case SE_FinishingBlow: {
|
||||||
{
|
|
||||||
// base1 = chance, base2 = damage
|
// base1 = chance, base2 = damage
|
||||||
if (newbon->FinishingBlow[1] < base2) {
|
if (newbon->FinishingBlow[1] < base2) {
|
||||||
newbon->FinishingBlow[0] = base1;
|
newbon->FinishingBlow[0] = base1;
|
||||||
@ -1274,8 +1258,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_FinishingBlowLvl:
|
case SE_FinishingBlowLvl: {
|
||||||
{
|
|
||||||
// base1 = level, base2 = ??? (Set to 200 in AA data, possible proc rate mod?)
|
// base1 = level, base2 = ??? (Set to 200 in AA data, possible proc rate mod?)
|
||||||
if (newbon->FinishingBlowLvl[0] < base1) {
|
if (newbon->FinishingBlowLvl[0] < base1) {
|
||||||
newbon->FinishingBlowLvl[0] = base1;
|
newbon->FinishingBlowLvl[0] = base1;
|
||||||
@ -1300,8 +1283,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
newbon->HealRate += base1;
|
newbon->HealRate += base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_MeleeLifetap:
|
case SE_MeleeLifetap: {
|
||||||
{
|
|
||||||
|
|
||||||
if ((base1 < 0) && (newbon->MeleeLifetap > base1))
|
if ((base1 < 0) && (newbon->MeleeLifetap > base1))
|
||||||
newbon->MeleeLifetap = base1;
|
newbon->MeleeLifetap = base1;
|
||||||
@ -1331,8 +1313,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
newbon->Metabolism += base1;
|
newbon->Metabolism += base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_ImprovedReclaimEnergy:
|
case SE_ImprovedReclaimEnergy: {
|
||||||
{
|
|
||||||
if ((base1 < 0) && (newbon->ImprovedReclaimEnergy > base1))
|
if ((base1 < 0) && (newbon->ImprovedReclaimEnergy > base1))
|
||||||
newbon->ImprovedReclaimEnergy = base1;
|
newbon->ImprovedReclaimEnergy = base1;
|
||||||
|
|
||||||
@ -1341,8 +1322,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_HeadShot:
|
case SE_HeadShot: {
|
||||||
{
|
|
||||||
if (newbon->HeadShot[1] < base2) {
|
if (newbon->HeadShot[1] < base2) {
|
||||||
newbon->HeadShot[0] = base1;
|
newbon->HeadShot[0] = base1;
|
||||||
newbon->HeadShot[1] = base2;
|
newbon->HeadShot[1] = base2;
|
||||||
@ -1350,15 +1330,13 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_HeadShotLevel:
|
case SE_HeadShotLevel: {
|
||||||
{
|
|
||||||
if (newbon->HSLevel < base1)
|
if (newbon->HSLevel < base1)
|
||||||
newbon->HSLevel = base1;
|
newbon->HSLevel = base1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_Assassinate:
|
case SE_Assassinate: {
|
||||||
{
|
|
||||||
if (newbon->Assassinate[1] < base2) {
|
if (newbon->Assassinate[1] < base2) {
|
||||||
newbon->Assassinate[0] = base1;
|
newbon->Assassinate[0] = base1;
|
||||||
newbon->Assassinate[1] = base2;
|
newbon->Assassinate[1] = base2;
|
||||||
@ -1366,8 +1344,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_AssassinateLevel:
|
case SE_AssassinateLevel: {
|
||||||
{
|
|
||||||
if (newbon->AssassinateLevel < base1)
|
if (newbon->AssassinateLevel < base1)
|
||||||
newbon->AssassinateLevel = base1;
|
newbon->AssassinateLevel = base1;
|
||||||
break;
|
break;
|
||||||
@ -1377,12 +1354,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
newbon->PetMeleeMitigation += base1;
|
newbon->PetMeleeMitigation += base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_MeleeVulnerability:
|
case SE_FactionModPct: {
|
||||||
newbon->MeleeVulnerability += base1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SE_FactionModPct:
|
|
||||||
{
|
|
||||||
if ((base1 < 0) && (newbon->FactionModPct > base1))
|
if ((base1 < 0) && (newbon->FactionModPct > base1))
|
||||||
newbon->FactionModPct = base1;
|
newbon->FactionModPct = base1;
|
||||||
|
|
||||||
@ -1396,19 +1368,21 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitToSkill: {
|
case SE_LimitToSkill: {
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if (base1 <= HIGHEST_SKILL)
|
if (base1 <= HIGHEST_SKILL)
|
||||||
newbon->LimitToSkill[base1] = true;
|
newbon->LimitToSkill[base1] = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_SkillProc: {
|
case SE_SkillProc: {
|
||||||
for(int e = 0; e < MAX_SKILL_PROCS; e++)
|
for (int e = 0; e < MAX_SKILL_PROCS; e++) {
|
||||||
{
|
if (newbon->SkillProc[e] && newbon->SkillProc[e] == rank.id)
|
||||||
if(newbon->SkillProc[e] && newbon->SkillProc[e] == aaid)
|
|
||||||
break; // Do not use the same aa id more than once.
|
break; // Do not use the same aa id more than once.
|
||||||
|
|
||||||
else if (!newbon->SkillProc[e]) {
|
else if (!newbon->SkillProc[e]) {
|
||||||
newbon->SkillProc[e] = aaid;
|
newbon->SkillProc[e] = rank.id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1417,13 +1391,12 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
|
|
||||||
case SE_SkillProcSuccess: {
|
case SE_SkillProcSuccess: {
|
||||||
|
|
||||||
for(int e = 0; e < MAX_SKILL_PROCS; e++)
|
for (int e = 0; e < MAX_SKILL_PROCS; e++) {
|
||||||
{
|
if (newbon->SkillProcSuccess[e] && newbon->SkillProcSuccess[e] == rank.id)
|
||||||
if(newbon->SkillProcSuccess[e] && newbon->SkillProcSuccess[e] == aaid)
|
|
||||||
break; // Do not use the same spell id more than once.
|
break; // Do not use the same spell id more than once.
|
||||||
|
|
||||||
else if (!newbon->SkillProcSuccess[e]) {
|
else if (!newbon->SkillProcSuccess[e]) {
|
||||||
newbon->SkillProcSuccess[e] = aaid;
|
newbon->SkillProcSuccess[e] = rank.id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1434,7 +1407,82 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
newbon->MeleeMitigationEffect -= base1;
|
newbon->MeleeMitigationEffect -= base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_ATK:
|
||||||
|
newbon->ATK += base1;
|
||||||
|
break;
|
||||||
|
case SE_IncreaseExtTargetWindow:
|
||||||
|
newbon->extra_xtargets += base1;
|
||||||
|
break;
|
||||||
|
// to do
|
||||||
|
case SE_PetDiscipline:
|
||||||
|
break;
|
||||||
|
case SE_PetDiscipline2:
|
||||||
|
break;
|
||||||
|
case SE_ReduceTradeskillFail:
|
||||||
|
break;
|
||||||
|
case SE_PotionBeltSlots:
|
||||||
|
break;
|
||||||
|
case SE_BandolierSlots:
|
||||||
|
break;
|
||||||
|
case SE_ForageSkill:
|
||||||
|
break;
|
||||||
|
case SE_TradeSkillMastery:
|
||||||
|
break;
|
||||||
|
case SE_SecondaryForte:
|
||||||
|
break;
|
||||||
|
case SE_FeignedCastOnChance:
|
||||||
|
break;
|
||||||
|
case SE_ExtendedShielding:
|
||||||
|
break;
|
||||||
|
case SE_ShieldDuration:
|
||||||
|
break;
|
||||||
|
case SE_ReduceApplyPoisonTime:
|
||||||
|
break;
|
||||||
|
case SE_NimbleEvasion:
|
||||||
|
break;
|
||||||
|
case SE_TrapCircumvention:
|
||||||
|
break;
|
||||||
|
case SE_ShroudofStealth:
|
||||||
|
break;
|
||||||
|
case SE_FeignedMinion:
|
||||||
|
break;
|
||||||
|
|
||||||
|
// handled client side
|
||||||
|
case SE_ReduceFallDamage:
|
||||||
|
// not handled here
|
||||||
|
case SE_HastenedAASkill:
|
||||||
|
// not handled here but don't want to clutter debug log -- these may need to be verified to ignore
|
||||||
|
case SE_LimitMaxLevel:
|
||||||
|
case SE_LimitResist:
|
||||||
|
case SE_LimitTarget:
|
||||||
|
case SE_LimitEffect:
|
||||||
|
case SE_LimitSpellType:
|
||||||
|
case SE_LimitMinDur:
|
||||||
|
case SE_LimitInstant:
|
||||||
|
case SE_LimitMinLevel:
|
||||||
|
case SE_LimitCastTimeMin:
|
||||||
|
case SE_LimitCastTimeMax:
|
||||||
|
case SE_LimitSpell:
|
||||||
|
case SE_LimitCombatSkills:
|
||||||
|
case SE_LimitManaMin:
|
||||||
|
case SE_LimitSpellGroup:
|
||||||
|
case SE_LimitSpellClass:
|
||||||
|
case SE_LimitSpellSubclass:
|
||||||
|
case SE_LimitHPPercent:
|
||||||
|
case SE_LimitManaPercent:
|
||||||
|
case SE_LimitEndPercent:
|
||||||
|
case SE_LimitClass:
|
||||||
|
case SE_LimitRace:
|
||||||
|
case SE_LimitCastingSkill:
|
||||||
|
case SE_LimitUseMin:
|
||||||
|
case SE_LimitUseType:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log.Out(Logs::Detail, Logs::AA, "SPA %d not accounted for in AA %s (%d)", effect, rank.base_ability->name.c_str(), rank.id);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1875,6 +1923,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_CriticalHitChance:
|
case SE_CriticalHitChance:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if (AdditiveWornBonus) {
|
if (AdditiveWornBonus) {
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
new_bonus->CriticalHitChance[HIGHEST_SKILL+1] += effect_value;
|
new_bonus->CriticalHitChance[HIGHEST_SKILL+1] += effect_value;
|
||||||
@ -2078,6 +2129,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_HitChance:
|
case SE_HitChance:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
|
|
||||||
if (AdditiveWornBonus){
|
if (AdditiveWornBonus){
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
@ -2112,6 +2166,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_DamageModifier:
|
case SE_DamageModifier:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
new_bonus->DamageModifier[HIGHEST_SKILL+1] += effect_value;
|
new_bonus->DamageModifier[HIGHEST_SKILL+1] += effect_value;
|
||||||
else
|
else
|
||||||
@ -2121,6 +2178,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_DamageModifier2:
|
case SE_DamageModifier2:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
new_bonus->DamageModifier2[HIGHEST_SKILL+1] += effect_value;
|
new_bonus->DamageModifier2[HIGHEST_SKILL+1] += effect_value;
|
||||||
else
|
else
|
||||||
@ -2130,6 +2190,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_MinDamageModifier:
|
case SE_MinDamageModifier:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
new_bonus->MinDamageModifier[HIGHEST_SKILL+1] += effect_value;
|
new_bonus->MinDamageModifier[HIGHEST_SKILL+1] += effect_value;
|
||||||
else
|
else
|
||||||
@ -2203,6 +2266,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_Accuracy:
|
case SE_Accuracy:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if ((effect_value < 0) && (new_bonus->Accuracy[HIGHEST_SKILL+1] > effect_value))
|
if ((effect_value < 0) && (new_bonus->Accuracy[HIGHEST_SKILL+1] > effect_value))
|
||||||
new_bonus->Accuracy[HIGHEST_SKILL+1] = effect_value;
|
new_bonus->Accuracy[HIGHEST_SKILL+1] = effect_value;
|
||||||
|
|
||||||
@ -2226,6 +2292,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_SkillDamageTaken:
|
case SE_SkillDamageTaken:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
//When using npc_spells_effects if MAX value set, use stackable quest based modifier.
|
//When using npc_spells_effects if MAX value set, use stackable quest based modifier.
|
||||||
if (IsAISpellEffect && max){
|
if (IsAISpellEffect && max){
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
@ -2344,6 +2413,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_CriticalDamageMob:
|
case SE_CriticalDamageMob:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
new_bonus->CritDmgMob[HIGHEST_SKILL+1] += effect_value;
|
new_bonus->CritDmgMob[HIGHEST_SKILL+1] += effect_value;
|
||||||
else
|
else
|
||||||
@ -2360,6 +2432,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_SkillDamageAmount:
|
case SE_SkillDamageAmount:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
new_bonus->SkillDamageAmount[HIGHEST_SKILL+1] += effect_value;
|
new_bonus->SkillDamageAmount[HIGHEST_SKILL+1] += effect_value;
|
||||||
else
|
else
|
||||||
@ -2465,6 +2540,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_SkillDamageAmount2:
|
case SE_SkillDamageAmount2:
|
||||||
{
|
{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if(base2 == ALL_SKILLS)
|
if(base2 == ALL_SKILLS)
|
||||||
new_bonus->SkillDamageAmount2[HIGHEST_SKILL+1] += effect_value;
|
new_bonus->SkillDamageAmount2[HIGHEST_SKILL+1] += effect_value;
|
||||||
else
|
else
|
||||||
@ -2980,10 +3058,6 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
new_bonus->PetMeleeMitigation += effect_value;
|
new_bonus->PetMeleeMitigation += effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_MeleeVulnerability:
|
|
||||||
new_bonus->MeleeVulnerability += effect_value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SE_Sanctuary:
|
case SE_Sanctuary:
|
||||||
new_bonus->Sanctuary = true;
|
new_bonus->Sanctuary = true;
|
||||||
break;
|
break;
|
||||||
@ -3003,6 +3077,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitToSkill:{
|
case SE_LimitToSkill:{
|
||||||
|
// Bad data or unsupported new skill
|
||||||
|
if (base2 > HIGHEST_SKILL)
|
||||||
|
break;
|
||||||
if (effect_value <= HIGHEST_SKILL){
|
if (effect_value <= HIGHEST_SKILL){
|
||||||
new_bonus->LimitToSkill[effect_value] = true;
|
new_bonus->LimitToSkill[effect_value] = true;
|
||||||
}
|
}
|
||||||
@ -4560,12 +4637,6 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
|||||||
aabonuses.FactionModPct = effect_value;
|
aabonuses.FactionModPct = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_MeleeVulnerability:
|
|
||||||
spellbonuses.MeleeVulnerability = effect_value;
|
|
||||||
itembonuses.MeleeVulnerability = effect_value;
|
|
||||||
aabonuses.MeleeVulnerability = effect_value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SE_IllusionPersistence:
|
case SE_IllusionPersistence:
|
||||||
spellbonuses.IllusionPersistence = false;
|
spellbonuses.IllusionPersistence = false;
|
||||||
itembonuses.IllusionPersistence = false;
|
itembonuses.IllusionPersistence = false;
|
||||||
|
|||||||
688
zone/bot.cpp
688
zone/bot.cpp
@ -1259,601 +1259,40 @@ int32 Bot::GenerateBaseHitPoints() {
|
|||||||
return new_base_hp;
|
return new_base_hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::GenerateAABonuses(StatBonuses* newbon) {
|
|
||||||
// General AA bonus
|
|
||||||
uint8 botClass = GetClass();
|
|
||||||
uint8 botLevel = GetLevel();
|
|
||||||
memset(newbon, 0, sizeof(StatBonuses)); //start fresh
|
|
||||||
if(botLevel >= 51) {
|
|
||||||
//level 51 = 1 AA level
|
|
||||||
int i;
|
|
||||||
int totalAAs = database.CountAAs();
|
|
||||||
uint32 slots = 0;
|
|
||||||
uint32 aa_AA = 0;
|
|
||||||
uint32 aa_value = 0;
|
|
||||||
for (i = 0; i < totalAAs; i++) { //iterate through all of the client's AAs
|
|
||||||
std::map<uint32, BotAA>::iterator aa = botAAs.find(i);
|
|
||||||
if(aa != botAAs.end()) { // make sure aa exists or we'll crash zone
|
|
||||||
aa_AA = aa->second.aa_id; //same as aaid from the aa_effects table
|
|
||||||
aa_value = aa->second.total_levels; //how many points in it
|
|
||||||
if (aa_AA > 0 || aa_value > 0) { //do we have the AA? if 1 of the 2 is set, we can assume we do
|
|
||||||
//slots = database.GetTotalAALevels(aa_AA); //find out how many effects from aa_effects table
|
|
||||||
slots = zone->GetTotalAALevels(aa_AA); //find out how many effects from aa_effects, which is loaded into memory
|
|
||||||
if (slots > 0) //and does it have any effects? may be able to put this above, not sure if it runs on each iteration
|
|
||||||
ApplyAABonuses((aa_AA + aa_value - 1), slots, newbon); //add the bonuses
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Bot::LoadAAs() {
|
void Bot::LoadAAs() {
|
||||||
int maxAAExpansion = RuleI(Bots, BotAAExpansion); //get expansion to get AAs up to
|
int maxAAExpansion = RuleI(Bots, BotAAExpansion); //get expansion to get AAs up to
|
||||||
botAAs.clear(); //start fresh
|
aa_ranks.clear();
|
||||||
|
|
||||||
std::string query;
|
int id = 0;
|
||||||
if(GetClass() == BERSERKER)
|
int points = 0;
|
||||||
query = StringFormat("SELECT skill_id FROM altadv_vars WHERE berserker = 1 AND class_type > 1 AND class_type <= %i AND aa_expansion <= %i ORDER BY skill_id;", GetLevel(), maxAAExpansion);
|
auto iter = zone->aa_abilities.begin();
|
||||||
else
|
while(iter != zone->aa_abilities.end()) {
|
||||||
query = StringFormat("SELECT skill_id FROM altadv_vars WHERE ((classes & ( 1 << %i )) >> %i) = 1 AND class_type > 1 AND class_type <= %i AND aa_expansion <= %i ORDER BY skill_id;", GetClass(), GetClass(), GetLevel(), maxAAExpansion);
|
AA::Ability *ability = (*iter).second.get();
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
//skip expendables
|
||||||
if(!results.Success()) {
|
if(!ability->first || ability->charges > 0) {
|
||||||
Log.Out(Logs::General, Logs::Error, "Error in Bot::LoadAAs()");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int totalAAs = database.CountAAs();
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
uint32 skill_id = 0;
|
|
||||||
skill_id = atoi(row[0]);
|
|
||||||
if(skill_id <= 0 || skill_id >= totalAAs)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SendAA_Struct *sendAA = zone->FindAA(skill_id);
|
|
||||||
|
|
||||||
if(!sendAA)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for(int i=0; i<sendAA->max_level; i++) {
|
|
||||||
//Get AA info & add to list
|
|
||||||
uint32 aaid = (sendAA->id + i);
|
|
||||||
uint8 total_levels = 0;
|
|
||||||
uint8 req_level;
|
|
||||||
std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(aaid);
|
|
||||||
//Get level required for AA
|
|
||||||
if(RequiredLevel != AARequiredLevelAndCost.end())
|
|
||||||
req_level = RequiredLevel->second.Level;
|
|
||||||
else
|
|
||||||
req_level = (sendAA->class_type + i * sendAA->level_inc);
|
|
||||||
|
|
||||||
if(req_level > GetLevel())
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Bot is high enough level for AA
|
|
||||||
std::map<uint32, BotAA>::iterator foundAA = botAAs.find(aaid);
|
|
||||||
// AA is already in list
|
|
||||||
if(foundAA != botAAs.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(sendAA->id == aaid) {
|
|
||||||
BotAA newAA;
|
|
||||||
newAA.total_levels = 0;
|
|
||||||
newAA.aa_id = aaid;
|
|
||||||
newAA.req_level = req_level;
|
|
||||||
newAA.total_levels += 1;
|
|
||||||
botAAs[aaid] = newAA; //add to list
|
|
||||||
}
|
|
||||||
else //update master AA record with number of levels a bot has in AA, based on level.
|
|
||||||
botAAs[sendAA->id].total_levels += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 Bot::GetAA(uint32 aa_id) {
|
|
||||||
std::map<uint32, BotAA >::const_iterator find_iter = botAAs.find(aa_id);
|
|
||||||
int aaLevel = 0;
|
|
||||||
if(find_iter != botAAs.end())
|
|
||||||
aaLevel = find_iter->second.total_levels;
|
|
||||||
|
|
||||||
return aaLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
//current with Client::ApplyAABonuses 9/26/12
|
|
||||||
void Bot::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) {
|
|
||||||
if(slots == 0) //sanity check. why bother if no slots to fill?
|
|
||||||
return;
|
|
||||||
|
|
||||||
//from AA_Ability struct
|
|
||||||
uint32 effect = 0;
|
|
||||||
int32 base1 = 0;
|
|
||||||
int32 base2 = 0; //only really used for SE_RaiseStatCap & SE_ReduceSkillTimer in aa_effects table
|
|
||||||
uint32 slot = 0;
|
|
||||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aaid);
|
|
||||||
if(find_iter == aa_effects.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
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;
|
|
||||||
//we default to 0 (SE_CurrentHP) for the effect, so if there aren't any base1/2 values, we'll just skip it
|
|
||||||
if ((effect == 0 && base1 == 0 && base2 == 0) || effect == SE_Blank || (effect == SE_CHA && base1 == 0) || effect == SE_StackingCommand_Block || effect == SE_StackingCommand_Overwrite)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::AA, "Applying Effect %d from AA %u in slot %d (base1: %d, base2: %d) on %s", effect, aaid, slot, base1, base2, this->GetCleanName());
|
|
||||||
uint8 focus = IsFocusEffect(0, 0, true, effect);
|
|
||||||
if (focus) {
|
|
||||||
newbon->FocusEffects[focus] = effect;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (effect) {
|
id = ability->first->id;
|
||||||
//Note: AA effects that use accuracy are skill limited, while spell effect is not.
|
points = 0;
|
||||||
case SE_Accuracy:
|
|
||||||
if ((base2 == -1) && (newbon->Accuracy[HIGHEST_SKILL+1] < base1))
|
|
||||||
newbon->Accuracy[HIGHEST_SKILL+1] = base1;
|
|
||||||
else if (newbon->Accuracy[base2] < base1)
|
|
||||||
newbon->Accuracy[base2] += base1;
|
|
||||||
break;
|
|
||||||
case SE_CurrentHP: //regens
|
|
||||||
newbon->HPRegen += base1;
|
|
||||||
break;
|
|
||||||
case SE_CurrentEndurance:
|
|
||||||
newbon->EnduranceRegen += base1;
|
|
||||||
break;
|
|
||||||
case SE_MovementSpeed:
|
|
||||||
newbon->movementspeed += base1;
|
|
||||||
break;
|
|
||||||
case SE_STR:
|
|
||||||
newbon->STR += base1;
|
|
||||||
break;
|
|
||||||
case SE_DEX:
|
|
||||||
newbon->DEX += base1;
|
|
||||||
break;
|
|
||||||
case SE_AGI:
|
|
||||||
newbon->AGI += base1;
|
|
||||||
break;
|
|
||||||
case SE_STA:
|
|
||||||
newbon->STA += base1;
|
|
||||||
break;
|
|
||||||
case SE_INT:
|
|
||||||
newbon->INT += base1;
|
|
||||||
break;
|
|
||||||
case SE_WIS:
|
|
||||||
newbon->WIS += base1;
|
|
||||||
break;
|
|
||||||
case SE_CHA:
|
|
||||||
newbon->CHA += base1;
|
|
||||||
break;
|
|
||||||
case SE_WaterBreathing:
|
|
||||||
//handled by client
|
|
||||||
break;
|
|
||||||
case SE_CurrentMana:
|
|
||||||
newbon->ManaRegen += base1;
|
|
||||||
break;
|
|
||||||
case SE_ItemManaRegenCapIncrease:
|
|
||||||
newbon->ItemManaRegenCap += base1;
|
|
||||||
break;
|
|
||||||
case SE_ResistFire:
|
|
||||||
newbon->FR += base1;
|
|
||||||
break;
|
|
||||||
case SE_ResistCold:
|
|
||||||
newbon->CR += base1;
|
|
||||||
break;
|
|
||||||
case SE_ResistPoison:
|
|
||||||
newbon->PR += base1;
|
|
||||||
break;
|
|
||||||
case SE_ResistDisease:
|
|
||||||
newbon->DR += base1;
|
|
||||||
break;
|
|
||||||
case SE_ResistMagic:
|
|
||||||
newbon->MR += base1;
|
|
||||||
break;
|
|
||||||
case SE_ResistCorruption:
|
|
||||||
newbon->Corrup += base1;
|
|
||||||
break;
|
|
||||||
case SE_IncreaseSpellHaste:
|
|
||||||
break;
|
|
||||||
case SE_IncreaseRange:
|
|
||||||
break;
|
|
||||||
case SE_MaxHPChange:
|
|
||||||
newbon->MaxHP += base1;
|
|
||||||
break;
|
|
||||||
case SE_Packrat:
|
|
||||||
newbon->Packrat += base1;
|
|
||||||
break;
|
|
||||||
case SE_TwoHandBash:
|
|
||||||
break;
|
|
||||||
case SE_SetBreathLevel:
|
|
||||||
break;
|
|
||||||
case SE_RaiseStatCap:
|
|
||||||
switch(base2) {
|
|
||||||
//are these #define'd somewhere?
|
|
||||||
case 0: //str
|
|
||||||
newbon->STRCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 1: //sta
|
|
||||||
newbon->STACapMod += base1;
|
|
||||||
break;
|
|
||||||
case 2: //agi
|
|
||||||
newbon->AGICapMod += base1;
|
|
||||||
break;
|
|
||||||
case 3: //dex
|
|
||||||
newbon->DEXCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 4: //wis
|
|
||||||
newbon->WISCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 5: //int
|
|
||||||
newbon->INTCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 6: //cha
|
|
||||||
newbon->CHACapMod += base1;
|
|
||||||
break;
|
|
||||||
case 7: //mr
|
|
||||||
newbon->MRCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 8: //cr
|
|
||||||
newbon->CRCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 9: //fr
|
|
||||||
newbon->FRCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 10: //pr
|
|
||||||
newbon->PRCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 11: //dr
|
|
||||||
newbon->DRCapMod += base1;
|
|
||||||
break;
|
|
||||||
case 12: //corruption
|
|
||||||
newbon->CorrupCapMod += base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SE_PetDiscipline2:
|
|
||||||
break;
|
|
||||||
case SE_SpellSlotIncrease:
|
|
||||||
break;
|
|
||||||
case SE_MysticalAttune:
|
|
||||||
newbon->BuffSlotIncrease += base1;
|
|
||||||
break;
|
|
||||||
case SE_TotalHP:
|
|
||||||
newbon->HP += base1;
|
|
||||||
break;
|
|
||||||
case SE_StunResist:
|
|
||||||
newbon->StunResist += base1;
|
|
||||||
break;
|
|
||||||
case SE_SpellCritChance:
|
|
||||||
newbon->CriticalSpellChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_SpellCritDmgIncrease:
|
|
||||||
newbon->SpellCritDmgIncrease += base1;
|
|
||||||
break;
|
|
||||||
case SE_DotCritDmgIncrease:
|
|
||||||
newbon->DotCritDmgIncrease += base1;
|
|
||||||
break;
|
|
||||||
case SE_ResistSpellChance:
|
|
||||||
newbon->ResistSpellChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_CriticalHealChance:
|
|
||||||
newbon->CriticalHealChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_CriticalHealOverTime:
|
|
||||||
newbon->CriticalHealOverTime += base1;
|
|
||||||
break;
|
|
||||||
case SE_CriticalDoTChance:
|
|
||||||
newbon->CriticalDoTChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_ReduceSkillTimer:
|
|
||||||
newbon->SkillReuseTime[base2] += base1;
|
|
||||||
break;
|
|
||||||
case SE_Fearless:
|
|
||||||
newbon->Fearless = true;
|
|
||||||
break;
|
|
||||||
case SE_PersistantCasting:
|
|
||||||
newbon->PersistantCasting += base1;
|
|
||||||
break;
|
|
||||||
case SE_DelayDeath:
|
|
||||||
newbon->DelayDeath += base1;
|
|
||||||
break;
|
|
||||||
case SE_FrontalStunResist:
|
|
||||||
newbon->FrontalStunResist += base1;
|
|
||||||
break;
|
|
||||||
case SE_ImprovedBindWound:
|
|
||||||
newbon->BindWound += base1;
|
|
||||||
break;
|
|
||||||
case SE_MaxBindWound:
|
|
||||||
newbon->MaxBindWound += base1;
|
|
||||||
break;
|
|
||||||
case SE_ExtraAttackChance:
|
|
||||||
newbon->ExtraAttackChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_SeeInvis:
|
|
||||||
newbon->SeeInvis = base1;
|
|
||||||
break;
|
|
||||||
case SE_BaseMovementSpeed:
|
|
||||||
newbon->BaseMovementSpeed += base1;
|
|
||||||
break;
|
|
||||||
case SE_IncreaseRunSpeedCap:
|
|
||||||
newbon->IncreaseRunSpeedCap += base1;
|
|
||||||
break;
|
|
||||||
case SE_ConsumeProjectile:
|
|
||||||
newbon->ConsumeProjectile += base1;
|
|
||||||
break;
|
|
||||||
case SE_ArcheryDamageModifier:
|
|
||||||
newbon->ArcheryDamageModifier += base1;
|
|
||||||
break;
|
|
||||||
case SE_DamageShield:
|
|
||||||
newbon->DamageShield += base1;
|
|
||||||
break;
|
|
||||||
case SE_CharmBreakChance:
|
|
||||||
newbon->CharmBreakChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_OffhandRiposteFail:
|
|
||||||
newbon->OffhandRiposteFail += base1;
|
|
||||||
break;
|
|
||||||
case SE_ItemAttackCapIncrease:
|
|
||||||
newbon->ItemATKCap += base1;
|
|
||||||
break;
|
|
||||||
case SE_GivePetGroupTarget:
|
|
||||||
newbon->GivePetGroupTarget = true;
|
|
||||||
break;
|
|
||||||
case SE_ItemHPRegenCapIncrease:
|
|
||||||
newbon->ItemHPRegenCap = +base1;
|
|
||||||
break;
|
|
||||||
case SE_Ambidexterity:
|
|
||||||
newbon->Ambidexterity += base1;
|
|
||||||
break;
|
|
||||||
case SE_PetMaxHP:
|
|
||||||
newbon->PetMaxHP += base1;
|
|
||||||
break;
|
|
||||||
case SE_AvoidMeleeChance:
|
|
||||||
newbon->AvoidMeleeChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_CombatStability:
|
|
||||||
newbon->CombatStability += base1;
|
|
||||||
break;
|
|
||||||
case SE_PetCriticalHit:
|
|
||||||
newbon->PetCriticalHit += base1;
|
|
||||||
break;
|
|
||||||
case SE_PetAvoidance:
|
|
||||||
newbon->PetAvoidance += base1;
|
|
||||||
break;
|
|
||||||
case SE_ShieldBlock:
|
|
||||||
newbon->ShieldBlock += base1;
|
|
||||||
break;
|
|
||||||
case SE_SecondaryDmgInc:
|
|
||||||
newbon->SecondaryDmgInc = true;
|
|
||||||
break;
|
|
||||||
case SE_ChangeAggro:
|
|
||||||
newbon->hatemod += base1;
|
|
||||||
break;
|
|
||||||
case SE_EndurancePool:
|
|
||||||
newbon->Endurance += base1;
|
|
||||||
break;
|
|
||||||
case SE_ChannelChanceItems:
|
|
||||||
newbon->ChannelChanceItems += base1;
|
|
||||||
break;
|
|
||||||
case SE_ChannelChanceSpells:
|
|
||||||
newbon->ChannelChanceSpells += base1;
|
|
||||||
break;
|
|
||||||
case SE_DoubleSpecialAttack:
|
|
||||||
newbon->DoubleSpecialAttack += base1;
|
|
||||||
break;
|
|
||||||
case SE_TripleBackstab:
|
|
||||||
newbon->TripleBackstab += base1;
|
|
||||||
break;
|
|
||||||
case SE_FrontalBackstabMinDmg:
|
|
||||||
newbon->FrontalBackstabMinDmg = true;
|
|
||||||
break;
|
|
||||||
case SE_FrontalBackstabChance:
|
|
||||||
newbon->FrontalBackstabChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_BlockBehind:
|
|
||||||
newbon->BlockBehind += base1;
|
|
||||||
break;
|
|
||||||
case SE_StrikeThrough2:
|
|
||||||
newbon->StrikeThrough += base1;
|
|
||||||
break;
|
|
||||||
case SE_DoubleAttackChance:
|
|
||||||
newbon->DoubleAttackChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_GiveDoubleAttack:
|
|
||||||
newbon->GiveDoubleAttack += base1;
|
|
||||||
break;
|
|
||||||
case SE_ProcChance:
|
|
||||||
newbon->ProcChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_RiposteChance:
|
|
||||||
newbon->RiposteChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_Flurry:
|
|
||||||
newbon->FlurryChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_PetFlurry:
|
|
||||||
newbon->PetFlurry = base1;
|
|
||||||
break;
|
|
||||||
case SE_BardSongRange:
|
|
||||||
newbon->SongRange += base1;
|
|
||||||
break;
|
|
||||||
case SE_RootBreakChance:
|
|
||||||
newbon->RootBreakChance += base1;
|
|
||||||
break;
|
|
||||||
case SE_UnfailingDivinity:
|
|
||||||
newbon->UnfailingDivinity += base1;
|
|
||||||
break;
|
|
||||||
case SE_ProcOnKillShot: {
|
|
||||||
for(int i = 0; i < (MAX_SPELL_TRIGGER * 3); i += 3) {
|
|
||||||
if(!newbon->SpellOnKill[i] || ((newbon->SpellOnKill[i] == base2) && (newbon->SpellOnKill[i + 1] < base1))) {
|
|
||||||
//base1 = chance, base2 = SpellID to be triggered, base3 = min npc level
|
|
||||||
newbon->SpellOnKill[i] = base2;
|
|
||||||
newbon->SpellOnKill[i + 1] = base1;
|
|
||||||
|
|
||||||
if (GetLevel() > 15)
|
AA::Rank *current = ability->first;
|
||||||
newbon->SpellOnKill[i + 2] = (GetLevel() - 15); //AA specifiy "non-trivial"
|
|
||||||
else
|
|
||||||
newbon->SpellOnKill[i + 2] = 0;
|
|
||||||
|
|
||||||
break;
|
while(current) {
|
||||||
|
if(!CanUseAlternateAdvancementRank(current)) {
|
||||||
|
current = nullptr;
|
||||||
|
} else {
|
||||||
|
current = current->next;
|
||||||
|
points++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_SpellOnDeath: {
|
|
||||||
for(int i = 0; i < (MAX_SPELL_TRIGGER * 2); i += 2) {
|
|
||||||
if(!newbon->SpellOnDeath[i]) {
|
|
||||||
// base1 = SpellID to be triggered, base2 = chance to fire
|
|
||||||
newbon->SpellOnDeath[i] = base1;
|
|
||||||
newbon->SpellOnDeath[i + 1] = base2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_TriggerOnCast: {
|
|
||||||
for(int i = 0; i < MAX_SPELL_TRIGGER; i++) {
|
|
||||||
if (newbon->SpellTriggers[i] == aaid)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!newbon->SpellTriggers[i]) {
|
if(points > 0) {
|
||||||
//Save the 'aaid' of each triggerable effect to an array
|
SetAA(id, points);
|
||||||
newbon->SpellTriggers[i] = aaid;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_CriticalHitChance: {
|
|
||||||
if(base2 == -1)
|
|
||||||
newbon->CriticalHitChance[HIGHEST_SKILL+1] += base1;
|
|
||||||
else
|
|
||||||
newbon->CriticalHitChance[base2] += base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_CriticalDamageMob: {
|
|
||||||
// base1 = effect value, base2 = skill restrictions(-1 for all)
|
|
||||||
if(base2 == -1)
|
|
||||||
newbon->CritDmgMob[HIGHEST_SKILL + 1] += base1;
|
|
||||||
else
|
|
||||||
newbon->CritDmgMob[base2] += base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_CriticalSpellChance: {
|
|
||||||
newbon->CriticalSpellChance += base1;
|
|
||||||
if (base2 > newbon->SpellCritDmgIncrease)
|
|
||||||
newbon->SpellCritDmgIncrease = base2;
|
|
||||||
|
|
||||||
break;
|
++iter;
|
||||||
}
|
|
||||||
case SE_ResistFearChance: {
|
|
||||||
if(base1 == 100) // If we reach 100% in a single spell/item then we should be immune to negative fear resist effects until our immunity is over
|
|
||||||
newbon->Fearless = true;
|
|
||||||
|
|
||||||
newbon->ResistFearChance += base1; // these should stack
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_SkillDamageAmount: {
|
|
||||||
if(base2 == -1)
|
|
||||||
newbon->SkillDamageAmount[HIGHEST_SKILL + 1] += base1;
|
|
||||||
else
|
|
||||||
newbon->SkillDamageAmount[base2] += base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_SpecialAttackKBProc: {
|
|
||||||
//You can only have one of these per client. [AA Dragon Punch]
|
|
||||||
newbon->SpecialAttackKBProc[0] = base1; //Chance base 100 = 25% proc rate
|
|
||||||
newbon->SpecialAttackKBProc[1] = base2; //Skill to KB Proc Off
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_DamageModifier: {
|
|
||||||
if(base2 == -1)
|
|
||||||
newbon->DamageModifier[HIGHEST_SKILL + 1] += base1;
|
|
||||||
else
|
|
||||||
newbon->DamageModifier[base2] += base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_SlayUndead: {
|
|
||||||
if(newbon->SlayUndead[1] < base1)
|
|
||||||
newbon->SlayUndead[0] = base1; // Rate
|
|
||||||
newbon->SlayUndead[1] = base2; // Damage Modifier
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_GiveDoubleRiposte: {
|
|
||||||
//0=Regular Riposte 1=Skill Attack Riposte 2=Skill
|
|
||||||
if(base2 == 0) {
|
|
||||||
if(newbon->GiveDoubleRiposte[0] < base1)
|
|
||||||
newbon->GiveDoubleRiposte[0] = base1;
|
|
||||||
}
|
|
||||||
//Only for special attacks.
|
|
||||||
else if(base2 > 0 && (newbon->GiveDoubleRiposte[1] < base1)) {
|
|
||||||
newbon->GiveDoubleRiposte[1] = base1;
|
|
||||||
newbon->GiveDoubleRiposte[2] = base2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//Kayen: Not sure best way to implement this yet.
|
|
||||||
//Physically raises skill cap ie if 55/55 it will raise to 55/60
|
|
||||||
case SE_RaiseSkillCap: {
|
|
||||||
if(newbon->RaiseSkillCap[0] < base1) {
|
|
||||||
newbon->RaiseSkillCap[0] = base1; //value
|
|
||||||
newbon->RaiseSkillCap[1] = base2; //skill
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_MasteryofPast: {
|
|
||||||
if(newbon->MasteryofPast < base1)
|
|
||||||
newbon->MasteryofPast = base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_CastingLevel2:
|
|
||||||
case SE_CastingLevel: {
|
|
||||||
newbon->effective_casting_level += base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_DivineSave: {
|
|
||||||
if(newbon->DivineSaveChance[0] < base1) {
|
|
||||||
newbon->DivineSaveChance[0] = base1;
|
|
||||||
newbon->DivineSaveChance[1] = base2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_SpellEffectResistChance: {
|
|
||||||
for(int e = 0; e < (MAX_RESISTABLE_EFFECTS * 2); e += 2) {
|
|
||||||
if(!newbon->SEResist[e] || ((newbon->SEResist[e] = base2) && (newbon->SEResist[e + 1] < base1)) ){
|
|
||||||
newbon->SEResist[e] = base2;
|
|
||||||
newbon->SEResist[e + 1] = base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_MitigateDamageShield: {
|
|
||||||
if (base1 < 0)
|
|
||||||
base1 = (base1 * -1);
|
|
||||||
|
|
||||||
newbon->DSMitigationOffHand += base1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_FinishingBlow: {
|
|
||||||
//base1 = chance, base2 = damage
|
|
||||||
if (newbon->FinishingBlow[1] < base2) {
|
|
||||||
newbon->FinishingBlow[0] = base1;
|
|
||||||
newbon->FinishingBlow[1] = base2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_FinishingBlowLvl: {
|
|
||||||
//base1 = level, base2 = ??? (Set to 200 in AA data, possible proc rate mod?)
|
|
||||||
if (newbon->FinishingBlowLvl[0] < base1) {
|
|
||||||
newbon->FinishingBlowLvl[0] = base1;
|
|
||||||
newbon->FinishingBlowLvl[1] = base2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5495,7 +4934,8 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) {
|
int32 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint32 points, uint16 spell_id)
|
||||||
|
{
|
||||||
const SPDat_Spell_Struct &spell = spells[spell_id];
|
const SPDat_Spell_Struct &spell = spells[spell_id];
|
||||||
int32 value = 0;
|
int32 value = 0;
|
||||||
int lvlModifier = 100;
|
int lvlModifier = 100;
|
||||||
@ -5509,15 +4949,21 @@ int32 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) {
|
|||||||
uint32 slot = 0;
|
uint32 slot = 0;
|
||||||
bool LimitFound = false;
|
bool LimitFound = false;
|
||||||
int FocusCount = 0;
|
int FocusCount = 0;
|
||||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aa_ID);
|
|
||||||
if(find_iter == aa_effects.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (std::map<uint32, AA_Ability>::const_iterator iter = aa_effects[aa_ID].begin(); iter != aa_effects[aa_ID].end(); ++iter) {
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa_ID, points);
|
||||||
effect = iter->second.skill_id;
|
auto ability = ability_rank.first;
|
||||||
base1 = iter->second.base1;
|
auto rank = ability_rank.second;
|
||||||
base2 = iter->second.base2;
|
|
||||||
slot = iter->second.slot;
|
if(!ability) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto &eff : rank->effects) {
|
||||||
|
effect = eff.effect_id;
|
||||||
|
base1 = eff.base1;
|
||||||
|
base2 = eff.base2;
|
||||||
|
slot = eff.slot;
|
||||||
|
|
||||||
//AA Foci's can contain multiple focus effects within the same AA.
|
//AA Foci's can contain multiple focus effects within the same AA.
|
||||||
//To handle this we will not automatically return zero if a limit is found.
|
//To handle this we will not automatically return zero if a limit is found.
|
||||||
//Instead if limit is found and multiple effects, we will reset the limit check
|
//Instead if limit is found and multiple effects, we will reset the limit check
|
||||||
@ -5731,6 +5177,24 @@ int32 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) {
|
|||||||
value = base1;
|
value = base1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
case SE_SympatheticProc:
|
||||||
|
{
|
||||||
|
if(type == focusSympatheticProc)
|
||||||
|
{
|
||||||
|
float ProcChance, ProcBonus;
|
||||||
|
int16 ProcRateMod = base1; //Baseline is 100 for most Sympathetic foci
|
||||||
|
int32 cast_time = GetActSpellCasttime(spell_id, spells[spell_id].cast_time);
|
||||||
|
GetSympatheticProcChances(ProcBonus, ProcChance, cast_time, ProcRateMod);
|
||||||
|
|
||||||
|
if(zone->random.Real(0, 1) <= ProcChance)
|
||||||
|
value = focus_id;
|
||||||
|
|
||||||
|
else
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
case SE_FcDamageAmt: {
|
case SE_FcDamageAmt: {
|
||||||
if(type == focusFcDamageAmt)
|
if(type == focusFcDamageAmt)
|
||||||
value = base1;
|
value = base1;
|
||||||
@ -5915,21 +5379,30 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) {
|
|||||||
|
|
||||||
// AA Focus
|
// AA Focus
|
||||||
if (aabonuses.FocusEffects[bottype]) {
|
if (aabonuses.FocusEffects[bottype]) {
|
||||||
int totalAAs = database.CountAAs();
|
|
||||||
int32 Total3 = 0;
|
int32 Total3 = 0;
|
||||||
uint32 slots = 0;
|
uint32 slots = 0;
|
||||||
uint32 aa_AA = 0;
|
uint32 aa_AA = 0;
|
||||||
uint32 aa_value = 0;
|
uint32 aa_value = 0;
|
||||||
for (int i = 0; i < totalAAs; i++) { //iterate through all of the client's AAs
|
|
||||||
std::map<uint32, BotAA>::iterator aa = botAAs.find(i);
|
for(auto &aa : aa_ranks) {
|
||||||
if(aa != botAAs.end()) { // make sure aa exists or we'll crash zone
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa.first, aa.second.first);
|
||||||
aa_AA = aa->second.aa_id; //same as aaid from the aa_effects table
|
auto ability = ability_rank.first;
|
||||||
aa_value = aa->second.total_levels; //how many points in it
|
auto rank = ability_rank.second;
|
||||||
|
|
||||||
|
if(!ability) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_AA = ability->id;
|
||||||
|
aa_value = aa.second.first;
|
||||||
if (aa_AA < 1 || aa_value < 1)
|
if (aa_AA < 1 || aa_value < 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Total3 = CalcBotAAFocus(bottype, aa_AA, spell_id);
|
Total3 = CalcBotAAFocus(bottype, aa_AA, aa_value, spell_id);
|
||||||
if ((Total3 > 0 && realTotal3 >= 0 && Total3 > realTotal3) || (Total3 < 0 && Total3 < realTotal3))
|
if (Total3 > 0 && realTotal3 >= 0 && Total3 > realTotal3) {
|
||||||
|
realTotal3 = Total3;
|
||||||
|
}
|
||||||
|
else if (Total3 < 0 && Total3 < realTotal3) {
|
||||||
realTotal3 = Total3;
|
realTotal3 = Total3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6540,13 +6013,15 @@ void Bot::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
|||||||
if (max_damage > 0)
|
if (max_damage > 0)
|
||||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||||
|
|
||||||
if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skill){
|
//[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill
|
||||||
|
/* if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skill){
|
||||||
int kb_chance = 25;
|
int kb_chance = 25;
|
||||||
kb_chance += (kb_chance * (100 - aabonuses.SpecialAttackKBProc[0]) / 100);
|
kb_chance += (kb_chance * (100 - aabonuses.SpecialAttackKBProc[0]) / 100);
|
||||||
|
|
||||||
if (zone->random.Int(0, 99) < kb_chance)
|
if (zone->random.Int(0, 99) < kb_chance)
|
||||||
SpellFinished(904, who, 10, 0, -1, spells[904].ResistDiff);
|
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())
|
if (HasSkillProcs())
|
||||||
TrySkillProc(who, skill, (ReuseTime * 1000));
|
TrySkillProc(who, skill, (ReuseTime * 1000));
|
||||||
@ -7556,7 +7031,8 @@ void Bot::DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster) {
|
|||||||
Mob::DoBuffTic(buff, slot, caster);
|
Mob::DoBuffTic(buff, slot, caster);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust) {
|
bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost,
|
||||||
|
uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust, uint32 aa_id) {
|
||||||
bool Result = false;
|
bool Result = false;
|
||||||
if(zone && !zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) {
|
if(zone && !zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) {
|
||||||
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", spells[spell_id].name, spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot);
|
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", spells[spell_id].name, spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot);
|
||||||
@ -7612,7 +7088,8 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_t
|
|||||||
bardsong_slot = 0;
|
bardsong_slot = 0;
|
||||||
bardsong_timer.Disable();
|
bardsong_timer.Disable();
|
||||||
}
|
}
|
||||||
Result = DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot);
|
|
||||||
|
Result = DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, aa_id);
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -7751,12 +7228,13 @@ bool Bot::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot) {
|
bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, uint32 aa_id) {
|
||||||
bool Result = false;
|
bool Result = false;
|
||||||
if(GetClass() == BARD)
|
if(GetClass() == BARD)
|
||||||
cast_time = 0;
|
cast_time = 0;
|
||||||
|
|
||||||
Result = Mob::DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot);
|
Result = Mob::DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, aa_id);
|
||||||
|
|
||||||
if(oSpellWillFinish) {
|
if(oSpellWillFinish) {
|
||||||
const SPDat_Spell_Struct &spell = spells[spell_id];
|
const SPDat_Spell_Struct &spell = spells[spell_id];
|
||||||
*oSpellWillFinish = Timer::GetCurrentTime() + ((spell.recast_time > 20000) ? 10000 : spell.recast_time);
|
*oSpellWillFinish = Timer::GetCurrentTime() + ((spell.recast_time > 20000) ? 10000 : spell.recast_time);
|
||||||
@ -7941,7 +7419,7 @@ void Bot::CalcBonuses() {
|
|||||||
GenerateBaseStats();
|
GenerateBaseStats();
|
||||||
CalcItemBonuses(&itembonuses);
|
CalcItemBonuses(&itembonuses);
|
||||||
CalcSpellBonuses(&spellbonuses);
|
CalcSpellBonuses(&spellbonuses);
|
||||||
GenerateAABonuses(&aabonuses);
|
CalcAABonuses(&aabonuses);
|
||||||
SetAttackTimer();
|
SetAttackTimer();
|
||||||
CalcATK();
|
CalcATK();
|
||||||
CalcSTR();
|
CalcSTR();
|
||||||
|
|||||||
12
zone/bot.h
12
zone/bot.h
@ -314,11 +314,12 @@ public:
|
|||||||
virtual float GetAOERange(uint16 spell_id);
|
virtual float GetAOERange(uint16 spell_id);
|
||||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
|
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
|
||||||
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
|
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 SpellOnTarget(uint16 spell_id, Mob* spelltar);
|
||||||
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
|
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 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
|
// Bot Action Command Methods
|
||||||
bool MesmerizeTarget(Mob* target);
|
bool MesmerizeTarget(Mob* target);
|
||||||
@ -448,9 +449,6 @@ public:
|
|||||||
bool IsBotWISCaster() { return (GetClass() == CLERIC || GetClass() == DRUID || GetClass() == SHAMAN); }
|
bool IsBotWISCaster() { return (GetClass() == CLERIC || GetClass() == DRUID || GetClass() == SHAMAN); }
|
||||||
bool CanHeal();
|
bool CanHeal();
|
||||||
int GetRawACNoShield(int &shield_ac);
|
int GetRawACNoShield(int &shield_ac);
|
||||||
void LoadAAs();
|
|
||||||
uint32 GetAA(uint32 aa_id);
|
|
||||||
void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon);
|
|
||||||
bool GetHasBeenSummoned() { return _hasBeenSummoned; }
|
bool GetHasBeenSummoned() { return _hasBeenSummoned; }
|
||||||
const glm::vec3 GetPreSummonLocation() const { return m_PreSummonLocation; }
|
const glm::vec3 GetPreSummonLocation() const { return m_PreSummonLocation; }
|
||||||
bool GetGroupMessagesOn() { return _groupMessagesOn; }
|
bool GetGroupMessagesOn() { return _groupMessagesOn; }
|
||||||
@ -564,7 +562,7 @@ protected:
|
|||||||
virtual bool CheckBotDoubleAttack(bool Triple = false);
|
virtual bool CheckBotDoubleAttack(bool Triple = false);
|
||||||
virtual int32 GetBotFocusEffect(BotfocusType bottype, uint16 spell_id);
|
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 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 void PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* client);
|
||||||
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
||||||
virtual float GetMaxMeleeRangeToTarget(Mob* target);
|
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.
|
uint8 _baseGender; // Bots gender. Necessary to preserve the original value otherwise it can be changed by illusions.
|
||||||
|
|
||||||
// Class Methods
|
// Class Methods
|
||||||
|
void LoadAAs();
|
||||||
int32 acmod();
|
int32 acmod();
|
||||||
void GenerateBaseStats();
|
void GenerateBaseStats();
|
||||||
void GenerateAppearance();
|
void GenerateAppearance();
|
||||||
void GenerateArmorClass();
|
void GenerateArmorClass();
|
||||||
int32 GenerateBaseHitPoints();
|
int32 GenerateBaseHitPoints();
|
||||||
void GenerateAABonuses(StatBonuses* newbon);
|
|
||||||
int32 GenerateBaseManaPoints();
|
int32 GenerateBaseManaPoints();
|
||||||
void GenerateSpecialAttacks();
|
void GenerateSpecialAttacks();
|
||||||
void SetBotID(uint32 botID);
|
void SetBotID(uint32 botID);
|
||||||
|
|||||||
118
zone/client.cpp
118
zone/client.cpp
@ -176,7 +176,6 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
admin = 0;
|
admin = 0;
|
||||||
lsaccountid = 0;
|
lsaccountid = 0;
|
||||||
shield_target = nullptr;
|
shield_target = nullptr;
|
||||||
SQL_log = nullptr;
|
|
||||||
guild_id = GUILD_NONE;
|
guild_id = GUILD_NONE;
|
||||||
guildrank = 0;
|
guildrank = 0;
|
||||||
GuildBanker = false;
|
GuildBanker = false;
|
||||||
@ -441,7 +440,7 @@ void Client::SendZoneInPackets()
|
|||||||
|
|
||||||
//Send AA Exp packet:
|
//Send AA Exp packet:
|
||||||
if (GetLevel() >= 51)
|
if (GetLevel() >= 51)
|
||||||
SendAAStats();
|
SendAlternateAdvancementStats();
|
||||||
|
|
||||||
// Send exp packets
|
// Send exp packets
|
||||||
outapp = new EQApplicationPacket(OP_ExpUpdate, sizeof(ExpUpdate_Struct));
|
outapp = new EQApplicationPacket(OP_ExpUpdate, sizeof(ExpUpdate_Struct));
|
||||||
@ -458,7 +457,7 @@ void Client::SendZoneInPackets()
|
|||||||
}
|
}
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
SendAATimers();
|
SendAlternateAdvancementTimers();
|
||||||
|
|
||||||
outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(ZoneInSendName_Struct));
|
outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(ZoneInSendName_Struct));
|
||||||
ZoneInSendName_Struct* zonesendname = (ZoneInSendName_Struct*)outapp->pBuffer;
|
ZoneInSendName_Struct* zonesendname = (ZoneInSendName_Struct*)outapp->pBuffer;
|
||||||
@ -526,47 +525,38 @@ void Client::ReportConnectingState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Client::SaveAA() {
|
bool Client::SaveAA() {
|
||||||
int first_entry = 0;
|
std::string iquery;
|
||||||
std::string rquery;
|
|
||||||
/* Save Player AA */
|
|
||||||
int spentpoints = 0;
|
int spentpoints = 0;
|
||||||
for (int a = 0; a < MAX_PP_AA_ARRAY; a++) {
|
int i = 0;
|
||||||
uint32 points = aa[a]->value;
|
for(auto &rank : aa_ranks) {
|
||||||
if (points > HIGHEST_AA_VALUE) {
|
AA::Ability *ability = zone->GetAlternateAdvancementAbility(rank.first);
|
||||||
aa[a]->value = HIGHEST_AA_VALUE;
|
if(!ability)
|
||||||
points = HIGHEST_AA_VALUE;
|
continue;
|
||||||
}
|
|
||||||
if (points > 0) {
|
if(rank.second.first > 0) {
|
||||||
SendAA_Struct* curAA = zone->FindAA(aa[a]->AA - aa[a]->value + 1);
|
AA::Rank *r = ability->GetRankByPointsSpent(rank.second.first);
|
||||||
if (curAA) {
|
|
||||||
for (int rank = 0; rank<points; rank++) {
|
if(!r)
|
||||||
std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(aa[a]->AA - aa[a]->value + 1 + rank);
|
continue;
|
||||||
if (RequiredLevel != AARequiredLevelAndCost.end()) {
|
|
||||||
spentpoints += RequiredLevel->second.Cost;
|
spentpoints += r->total_cost;
|
||||||
}
|
|
||||||
else
|
if(i == 0) {
|
||||||
spentpoints += (curAA->cost + (curAA->cost_inc * rank));
|
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);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
} else {
|
} 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 */
|
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
|
||||||
rquery = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u AND `slot` > %d", character_id, highest);
|
|
||||||
|
if(iquery.length() > 0) {
|
||||||
|
database.QueryDatabase(iquery);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
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) {
|
void Client::SendItemScale(ItemInst *inst) {
|
||||||
int slot = m_inv.GetSlotByItemInst(inst);
|
int slot = m_inv.GetSlotByItemInst(inst);
|
||||||
if(slot != -1) {
|
if(slot != -1) {
|
||||||
|
|||||||
@ -45,7 +45,6 @@ struct Item_Struct;
|
|||||||
#include "../common/item_struct.h"
|
#include "../common/item_struct.h"
|
||||||
#include "../common/clientversions.h"
|
#include "../common/clientversions.h"
|
||||||
|
|
||||||
#include "aa.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "merc.h"
|
#include "merc.h"
|
||||||
#include "mob.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 int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||||
virtual void SetAttackTimer();
|
virtual void SetAttackTimer();
|
||||||
float GetQuiverHaste();
|
float GetQuiverHaste();
|
||||||
|
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
||||||
|
|
||||||
void AI_Init();
|
void AI_Init();
|
||||||
void AI_Start(uint32 iMoveDelay = 0);
|
void AI_Start(uint32 iMoveDelay = 0);
|
||||||
@ -541,7 +541,6 @@ public:
|
|||||||
|
|
||||||
bool Flurry();
|
bool Flurry();
|
||||||
bool Rampage();
|
bool Rampage();
|
||||||
void DurationRampage(uint32 duration);
|
|
||||||
|
|
||||||
inline uint32 GetEXP() const { return m_pp.exp; }
|
inline uint32 GetEXP() const { return m_pp.exp; }
|
||||||
|
|
||||||
@ -623,6 +622,7 @@ public:
|
|||||||
inline uint32 AccountID() const { return account_id; }
|
inline uint32 AccountID() const { return account_id; }
|
||||||
|
|
||||||
inline const char* AccountName()const { return account_name; }
|
inline const char* AccountName()const { return account_name; }
|
||||||
|
inline int GetAccountCreation() const { return account_creation; }
|
||||||
inline int16 Admin() const { return admin; }
|
inline int16 Admin() const { return admin; }
|
||||||
inline uint32 CharacterID() const { return character_id; }
|
inline uint32 CharacterID() const { return character_id; }
|
||||||
void UpdateAdmin(bool iFromDB = true);
|
void UpdateAdmin(bool iFromDB = true);
|
||||||
@ -759,45 +759,35 @@ public:
|
|||||||
|
|
||||||
inline PTimerList &GetPTimers() { return(p_timers); }
|
inline PTimerList &GetPTimers() { return(p_timers); }
|
||||||
|
|
||||||
//AA Methods
|
//New AA Methods
|
||||||
void SendAAList();
|
void SendAlternateAdvancementRank(int aa_id, int level);
|
||||||
void ResetAA();
|
void SendAlternateAdvancementTable();
|
||||||
void SendClearAA();
|
void SendAlternateAdvancementStats();
|
||||||
void SendAA(uint32 id, int seq=1);
|
void PurchaseAlternateAdvancementRank(int rank_id);
|
||||||
void SendPreviousAA(uint32 id, int seq=1);
|
bool GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost = false);
|
||||||
void BuyAA(AA_Action* action);
|
void IncrementAlternateAdvancementRank(int rank_id);
|
||||||
//this function is used by some AA stuff
|
void ActivateAlternateAdvancementAbility(int rank_id, int target_id);
|
||||||
void MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing);
|
void SendAlternateAdvancementPoints();
|
||||||
void SetAATitle(const char *Title);
|
void SendAlternateAdvancementTimer(int ability, int begin, int end);
|
||||||
void SetTitleSuffix(const char *txt);
|
void SendAlternateAdvancementTimers();
|
||||||
inline uint32 GetMaxAAXP(void) const { return max_AAXP; }
|
void ResetAlternateAdvancementTimer(int ability);
|
||||||
inline uint32 GetAAXP() const { return m_pp.expAA; }
|
void ResetAlternateAdvancementTimers();
|
||||||
void SendAAStats();
|
|
||||||
void SendAATable();
|
void SetAAPoints(uint32 points) { m_pp.aapoints = points; SendAlternateAdvancementStats(); }
|
||||||
void SendAATimers();
|
void AddAAPoints(uint32 points) { m_pp.aapoints += points; SendAlternateAdvancementStats(); }
|
||||||
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(); }
|
|
||||||
int GetAAPoints() { return m_pp.aapoints; }
|
int GetAAPoints() { return m_pp.aapoints; }
|
||||||
int GetSpentAA() { return m_pp.aapoints_spent; }
|
int GetSpentAA() { return m_pp.aapoints_spent; }
|
||||||
|
|
||||||
|
//old AA methods that we still use
|
||||||
|
void ResetAA();
|
||||||
void RefundAA();
|
void RefundAA();
|
||||||
void IncrementAA(int aa_id);
|
void SendClearAA();
|
||||||
int32 GetAAEffectDataBySlot(uint32 aa_ID, uint32 slot_id, bool GetEffect, bool GetBase1, bool GetBase2);
|
inline uint32 GetMaxAAXP(void) const { return max_AAXP; }
|
||||||
int32 GetAAEffectid(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, true, false,false); }
|
inline uint32 GetAAXP() const { return m_pp.expAA; }
|
||||||
int32 GetAABase1(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, false, true,false); }
|
int16 CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id);
|
||||||
int32 GetAABase2(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, false, false,true); }
|
void SetAATitle(const char *Title);
|
||||||
|
void SetTitleSuffix(const char *txt);
|
||||||
|
void MemorizeSpell(uint32 slot, uint32 spellid, uint32 scribing);
|
||||||
int32 acmod();
|
int32 acmod();
|
||||||
|
|
||||||
// Item methods
|
// Item methods
|
||||||
@ -1271,8 +1261,6 @@ protected:
|
|||||||
void AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false);
|
void AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false);
|
||||||
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
||||||
void CalcEdibleBonuses(StatBonuses* newbon);
|
void CalcEdibleBonuses(StatBonuses* newbon);
|
||||||
void CalcAABonuses(StatBonuses* newbon);
|
|
||||||
void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon);
|
|
||||||
void ProcessItemCaps();
|
void ProcessItemCaps();
|
||||||
void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true);
|
void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true);
|
||||||
bool client_data_loaded;
|
bool client_data_loaded;
|
||||||
@ -1280,6 +1268,8 @@ protected:
|
|||||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||||
uint16 GetSympatheticFocusEffect(focusType type, uint16 spell_id);
|
uint16 GetSympatheticFocusEffect(focusType type, uint16 spell_id);
|
||||||
|
|
||||||
|
void FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost);
|
||||||
|
|
||||||
Mob* bind_sight_target;
|
Mob* bind_sight_target;
|
||||||
|
|
||||||
glm::vec4 m_AutoAttackPosition;
|
glm::vec4 m_AutoAttackPosition;
|
||||||
@ -1497,11 +1487,7 @@ private:
|
|||||||
|
|
||||||
uint32 tribute_master_id;
|
uint32 tribute_master_id;
|
||||||
|
|
||||||
FILE *SQL_log;
|
|
||||||
uint32 max_AAXP;
|
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;
|
bool npcflag;
|
||||||
uint8 npclevel;
|
uint8 npclevel;
|
||||||
bool feigned;
|
bool feigned;
|
||||||
|
|||||||
@ -1121,7 +1121,7 @@ int32 Client::CalcMaxMana()
|
|||||||
switch (GetCasterClass()) {
|
switch (GetCasterClass()) {
|
||||||
case 'I':
|
case 'I':
|
||||||
case 'W': {
|
case 'W': {
|
||||||
max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'N': {
|
case 'N': {
|
||||||
@ -1978,7 +1978,18 @@ uint32 Mob::GetInstrumentMod(uint16 spell_id) const
|
|||||||
return 10;
|
return 10;
|
||||||
|
|
||||||
uint32 effectmod = 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...
|
// this should never use spell modifiers...
|
||||||
// if a spell grants better modifers, they are copied into the item mods
|
// 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.
|
// 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;
|
effectmod = 10;
|
||||||
return effectmod;
|
return effectmod;
|
||||||
}
|
}
|
||||||
|
if (!RuleB(Character, UseSpellFileSongCap))
|
||||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
||||||
if (effectmod < 10)
|
if (effectmod < 10)
|
||||||
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;
|
effectmod = effectmodcap;
|
||||||
Log.Out(Logs::Detail, Logs::Spells, "%s::GetInstrumentMod() spell=%d mod=%d modcap=%d\n", GetName(), spell_id,
|
Log.Out(Logs::Detail, Logs::Spells, "%s::GetInstrumentMod() spell=%d mod=%d modcap=%d\n", GetName(), spell_id,
|
||||||
effectmod, effectmodcap);
|
effectmod, effectmodcap);
|
||||||
|
|||||||
@ -389,6 +389,7 @@ void MapOpcodes()
|
|||||||
ConnectedOpcodes[OP_XTargetRequest] = &Client::Handle_OP_XTargetRequest;
|
ConnectedOpcodes[OP_XTargetRequest] = &Client::Handle_OP_XTargetRequest;
|
||||||
ConnectedOpcodes[OP_YellForHelp] = &Client::Handle_OP_YellForHelp;
|
ConnectedOpcodes[OP_YellForHelp] = &Client::Handle_OP_YellForHelp;
|
||||||
ConnectedOpcodes[OP_ZoneChange] = &Client::Handle_OP_ZoneChange;
|
ConnectedOpcodes[OP_ZoneChange] = &Client::Handle_OP_ZoneChange;
|
||||||
|
ConnectedOpcodes[OP_ResetAA] = &Client::Handle_OP_ResetAA;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearMappedOpcode(EmuOpcode op)
|
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)
|
void Client::Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
SendAATimers();
|
SendAlternateAdvancementTimers();
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SendAAStats, 0);
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SendAAStats, 0);
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(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)
|
void Client::Handle_Connect_OP_SendAATable(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
SendAAList();
|
SendAlternateAdvancementTable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1152,7 +1153,7 @@ void Client::Handle_Connect_OP_TGB(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app)
|
void Client::Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
SendAATable();
|
SendAlternateAdvancementPoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_Connect_OP_WearChange(const EQApplicationPacket *app)
|
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_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; }
|
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 */
|
if(RuleB(World, UseClientBasedExpansionSettings)) {
|
||||||
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++)
|
m_pp.expansions = ExpansionFromClientVersion(GetClientVersion());
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++){
|
else {
|
||||||
uint32 id = aa[a]->AA;
|
m_pp.expansions = RuleI(World, ExpansionSettings);
|
||||||
//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) */
|
if(!database.LoadAlternateAdvancement(this)) {
|
||||||
aa_points[(id - aa[a]->value + 1)] = aa[a]->value;
|
Log.Out(Logs::General, Logs::Error, "Error loading AA points for %s", GetName());
|
||||||
else
|
|
||||||
aa_points[id] = aa[a]->value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SPDAT_RECORDS > 0) {
|
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. */
|
/* Update LFP in case any (or all) of our group disbanded while we were zoning. */
|
||||||
if (IsLFP()) { UpdateLFP(); }
|
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());
|
p_timers.SetCharID(CharacterID());
|
||||||
if (!p_timers.Load(&database)) {
|
if (!p_timers.Load(&database)) {
|
||||||
Log.Out(Logs::General, Logs::Error, "Unable to load ability timers from the database for %s (%i)!", GetCleanName(), CharacterID());
|
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");
|
Log.Out(Logs::Detail, Logs::AA, "Received OP_AAAction");
|
||||||
|
|
||||||
if (app->size != sizeof(AA_Action)){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
AA_Action* action = (AA_Action*)app->pBuffer;
|
AA_Action* action = (AA_Action*)app->pBuffer;
|
||||||
|
|
||||||
if (action->action == aaActionActivate) {//AA Hotkey
|
if (action->action == aaActionActivate) {//AA Hotkey
|
||||||
Log.Out(Logs::Detail, Logs::AA, "Activating AA %d", action->ability);
|
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) {
|
else if (action->action == aaActionBuy) {
|
||||||
BuyAA(action);
|
PurchaseAlternateAdvancementRank(action->ability);
|
||||||
}
|
}
|
||||||
else if (action->action == aaActionDisableEXP){ //Turn Off AA Exp
|
else if (action->action == aaActionDisableEXP){ //Turn Off AA Exp
|
||||||
if (m_epp.perAA > 0)
|
if (m_epp.perAA > 0)
|
||||||
Message_StringID(0, AA_OFF);
|
Message_StringID(0, AA_OFF);
|
||||||
|
|
||||||
m_epp.perAA = 0;
|
m_epp.perAA = 0;
|
||||||
SendAAStats();
|
SendAlternateAdvancementStats();
|
||||||
}
|
}
|
||||||
else if (action->action == aaActionSetEXP) {
|
else if (action->action == aaActionSetEXP) {
|
||||||
if (m_epp.perAA == 0)
|
if (m_epp.perAA == 0)
|
||||||
Message_StringID(0, AA_ON);
|
Message_StringID(0, AA_ON);
|
||||||
m_epp.perAA = action->exp_value;
|
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
|
// send an update
|
||||||
SendAAStats();
|
SendAlternateAdvancementStats();
|
||||||
SendAATable();
|
SendAlternateAdvancementTable();
|
||||||
}
|
}
|
||||||
else {
|
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)
|
void Client::Handle_OP_AcceptNewTask(const EQApplicationPacket *app)
|
||||||
@ -3898,8 +3852,6 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_TargetRing = glm::vec3(castspell->x_pos, castspell->y_pos, castspell->z_pos);
|
|
||||||
|
|
||||||
CastSpell(spell_to_cast, castspell->target_id, castspell->slot);
|
CastSpell(spell_to_cast, castspell->target_id, castspell->slot);
|
||||||
}
|
}
|
||||||
/* Spell Slot or Potion Belt 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(QSG_LFGuild_UpdatePlayerInfo);
|
||||||
pack->WriteUInt32(GetBaseClass());
|
pack->WriteUInt32(GetBaseClass());
|
||||||
pack->WriteUInt32(GetLevel());
|
pack->WriteUInt32(GetLevel());
|
||||||
pack->WriteUInt32(GetAAPointsSpent());
|
pack->WriteUInt32(GetSpentAA());
|
||||||
pack->WriteString(pts->Comment);
|
pack->WriteString(pts->Comment);
|
||||||
pack->WriteUInt32(pts->Toggle);
|
pack->WriteUInt32(pts->Toggle);
|
||||||
pack->WriteUInt32(pts->TimeZone);
|
pack->WriteUInt32(pts->TimeZone);
|
||||||
@ -14228,9 +14180,12 @@ void Client::Handle_OP_YellForHelp(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void Client::Handle_OP_ResetAA(const EQApplicationPacket *app)
|
||||||
void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app)
|
|
||||||
{
|
{
|
||||||
|
if(Admin() >= 50) {
|
||||||
|
Message(0, "Resetting AA points.");
|
||||||
|
ResetAA();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|||||||
@ -295,3 +295,4 @@
|
|||||||
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
|
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
|
||||||
void Handle_OP_YellForHelp(const EQApplicationPacket *app);
|
void Handle_OP_YellForHelp(const EQApplicationPacket *app);
|
||||||
void Handle_OP_ZoneChange(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
|
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);
|
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
||||||
TryWeaponProc(wpn, auto_attack_target, MainPrimary);
|
TryWeaponProc(wpn, auto_attack_target, MainPrimary);
|
||||||
|
|
||||||
bool tripleAttackSuccess = false;
|
DoAttackRounds(auto_attack_target, MainPrimary);
|
||||||
if( auto_attack_target && CanThisClassDoubleAttack() ) {
|
if (CheckAATimer(aaTimerRampage))
|
||||||
|
|
||||||
CheckIncreaseSkill(SkillDoubleAttack, auto_attack_target, -10);
|
|
||||||
if(CheckDoubleAttack()) {
|
|
||||||
//should we allow rampage on double attack?
|
|
||||||
if(CheckAAEffect(aaEffectRampage)) {
|
|
||||||
entity_list.AEAttack(this, 30);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,22 +438,10 @@ bool Client::Process() {
|
|||||||
float random = zone->random.Real(0, 1);
|
float random = zone->random.Real(0, 1);
|
||||||
CheckIncreaseSkill(SkillDualWield, auto_attack_target, -10);
|
CheckIncreaseSkill(SkillDualWield, auto_attack_target, -10);
|
||||||
if (random < DualWieldProbability) { // Max 78% of DW
|
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
|
|
||||||
}
|
|
||||||
ItemInst *wpn = GetInv().GetItem(MainSecondary);
|
ItemInst *wpn = GetInv().GetItem(MainSecondary);
|
||||||
TryWeaponProc(wpn, auto_attack_target, MainSecondary);
|
TryWeaponProc(wpn, auto_attack_target, MainSecondary);
|
||||||
|
|
||||||
if( CanThisClassDoubleAttack() && CheckDoubleAttack()) {
|
DoAttackRounds(auto_attack_target, MainSecondary);
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
141
zone/command.cpp
141
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("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("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("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("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("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) ||
|
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("los", nullptr,0, command_checklos) ||
|
||||||
command_add("makepet", "[level] [class] [race] [texture] - Make a pet", 50, command_makepet) ||
|
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("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("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("memspell", "[slotid] [spellid] - Memorize spellid in the specified slot", 50, command_memspell) ||
|
||||||
command_add("merchant_close_shop", "Closes a merchant shop", 100, command_merchantcloseshop) ||
|
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("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("randomfeatures", "- Temporarily randomizes the Facial Features of your target", 80, command_randomfeatures) ||
|
||||||
command_add("refreshgroup", "- Refreshes Group.", 0, command_refreshgroup) ||
|
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("reloadallrules", "Executes a reload of all rules.", 80, command_reloadallrules) ||
|
||||||
command_add("reloademote", "Reloads NPC Emotes", 80, command_reloademote) ||
|
command_add("reloademote", "Reloads NPC Emotes", 80, command_reloademote) ||
|
||||||
command_add("reloadlevelmods", nullptr,255, command_reloadlevelmods) ||
|
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("reloadzonepoints", "- Reload zone points from database", 150, command_reloadzps) ||
|
||||||
command_add("reloadzps", nullptr,0, command_reloadzps) ||
|
command_add("reloadzps", nullptr,0, command_reloadzps) ||
|
||||||
command_add("repop", "[delay] - Repop the zone with optional delay", 100, command_repop) ||
|
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("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("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) ||
|
command_add("save", "- Force your player or player corpse target to be saved to the database", 50, command_save) ||
|
||||||
@ -674,7 +674,7 @@ void command_incstat(Client* c, const Seperator* sep){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void command_resetaa(Client* c,const Seperator *sep) {
|
void command_resetaa(Client* c,const Seperator *sep) {
|
||||||
if(c->GetTarget()!=0 && c->GetTarget()->IsClient()){
|
if(c->GetTarget() && c->GetTarget()->IsClient()){
|
||||||
c->GetTarget()->CastToClient()->ResetAA();
|
c->GetTarget()->CastToClient()->ResetAA();
|
||||||
c->Message(13,"Successfully reset %s's AAs", c->GetTarget()->GetName());
|
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)
|
void command_doanim(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
if (!sep->IsNumber(1))
|
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')
|
if(sep->arg[1][0] == '\0' || sep->arg[2][0] == '\0')
|
||||||
c->Message(0, "Usage: #setaapts <AA|group|raid> <new AA points value>");
|
c->Message(0, "Usage: #setaapts <AA|group|raid> <new AA points value>");
|
||||||
else if(atoi(sep->arg[2]) <= 0 || atoi(sep->arg[2]) > 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 200.");
|
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")) {
|
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")) {
|
} 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 {
|
} else {
|
||||||
t->SetEXP(t->GetEXP(),t->GetMaxAAXP()*atoi(sep->arg[2]),false);
|
t->GetPP().aapoints = atoi(sep->arg[2]);
|
||||||
t->SendAAStats();
|
t->GetPP().expAA = 0;
|
||||||
t->SendAATable();
|
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)
|
void command_traindisc(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
uint8 max_level, min_level;
|
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);
|
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);
|
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);
|
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_zonestatus(Client *c, const Seperator *sep);
|
||||||
void command_manaburn(Client *c, const Seperator *sep);
|
|
||||||
void command_doanim(Client *c, const Seperator *sep);
|
void command_doanim(Client *c, const Seperator *sep);
|
||||||
void command_randomfeatures(Client *c, const Seperator *sep);
|
void command_randomfeatures(Client *c, const Seperator *sep);
|
||||||
void command_face(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_rules(Client *c, const Seperator *sep);
|
||||||
void command_task(Client *c, const Seperator *sep);
|
void command_task(Client *c, const Seperator *sep);
|
||||||
void command_reloadtitles(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_refundaa(Client *c, const Seperator *sep);
|
||||||
void command_traindisc(Client *c, const Seperator *sep);
|
void command_traindisc(Client *c, const Seperator *sep);
|
||||||
void command_deletegraveyard(Client *c, const Seperator *sep);
|
void command_deletegraveyard(Client *c, const Seperator *sep);
|
||||||
@ -325,6 +323,8 @@ void command_tune(Client *c, const Seperator *sep);
|
|||||||
void command_logtest(Client *c, const Seperator *sep);
|
void command_logtest(Client *c, const Seperator *sep);
|
||||||
void command_mysqltest(Client *c, const Seperator *sep);
|
void command_mysqltest(Client *c, const Seperator *sep);
|
||||||
void command_logs(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
|
#ifdef EQPROFILE
|
||||||
void command_profiledump(Client *c, const Seperator *sep);
|
void command_profiledump(Client *c, const Seperator *sep);
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#define TARGET_RING_SPELL_SLOT 12
|
#define TARGET_RING_SPELL_SLOT 12
|
||||||
#define DISCIPLINE_SPELL_SLOT 10
|
#define DISCIPLINE_SPELL_SLOT 10
|
||||||
#define ABILITY_SPELL_SLOT 9
|
#define ABILITY_SPELL_SLOT 9
|
||||||
|
#define ALTERNATE_ABILITY_SPELL_SLOT 0xFF
|
||||||
|
|
||||||
//LOS Parameters:
|
//LOS Parameters:
|
||||||
#define HEAD_POSITION 0.9f //ratio of GetSize() where NPCs see from
|
#define HEAD_POSITION 0.9f //ratio of GetSize() where NPCs see from
|
||||||
@ -400,7 +401,6 @@ struct StatBonuses {
|
|||||||
int32 Metabolism; // Food/drink consumption rates.
|
int32 Metabolism; // Food/drink consumption rates.
|
||||||
bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others.
|
bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others.
|
||||||
int32 FactionModPct; // Modifies amount of faction gained.
|
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.
|
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 SkillProc[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs.
|
||||||
uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
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.
|
int8 BaseMovementSpeed; // Adjust base run speed, does not stack with other movement bonuses.
|
||||||
uint8 IncreaseRunSpeedCap; // Increase max run speed above cap.
|
uint8 IncreaseRunSpeedCap; // Increase max run speed above cap.
|
||||||
int32 DoubleSpecialAttack; // Chance to to perform a double special attack (ie flying kick 2x)
|
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
|
uint8 FrontalStunResist; // Chance to resist a frontal stun
|
||||||
int32 BindWound; // Increase amount of HP by percent.
|
int32 BindWound; // Increase amount of HP by percent.
|
||||||
int32 MaxBindWound; // Increase max amount of HP you can bind wound.
|
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.
|
uint8 AssassinateLevel; // Max Level Assassinate will be effective at.
|
||||||
int32 PetMeleeMitigation; // Add AC to owner's pet.
|
int32 PetMeleeMitigation; // Add AC to owner's pet.
|
||||||
bool IllusionPersistence; // Causes illusions not to fade.
|
bool IllusionPersistence; // Causes illusions not to fade.
|
||||||
|
uint16 extra_xtargets; // extra xtarget entries
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@ -421,12 +421,6 @@ int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
|||||||
int tic_inc = 0;
|
int tic_inc = 0;
|
||||||
tic_inc = GetFocusEffect(focusSpellDurByTic, spell_id);
|
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;
|
float focused = ((duration * increase) / 100.0f) + tic_inc;
|
||||||
int ifocused = static_cast<int>(focused);
|
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);
|
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
|
//NPCs handle it differently in Mob::Rampage
|
||||||
void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool IsFromSpell) {
|
void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool IsFromSpell) {
|
||||||
//Dook- Will need tweaking, currently no pets or players or horses
|
//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 */
|
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
|
||||||
&& (DistanceSquared(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
|
&& (DistanceSquared(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
|
||||||
) {
|
) {
|
||||||
|
if (!attacker->IsClient() || attacker->GetClass() == MONK || attacker->GetClass() == RANGER)
|
||||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||||
|
else
|
||||||
|
attacker->CastToClient()->DoAttackRounds(curmob, Hand, IsFromSpell);
|
||||||
hit++;
|
hit++;
|
||||||
if (count != 0 && hit >= count)
|
if (count != 0 && hit >= count)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -58,7 +58,6 @@ extern uint32 numclients;
|
|||||||
extern PetitionList petition_list;
|
extern PetitionList petition_list;
|
||||||
|
|
||||||
extern char errorname[32];
|
extern char errorname[32];
|
||||||
extern uint16 adverrornum;
|
|
||||||
|
|
||||||
Entity::Entity()
|
Entity::Entity()
|
||||||
{
|
{
|
||||||
@ -4705,3 +4704,11 @@ void EntityList::StopMobAI()
|
|||||||
mob.second->AI_ShutDown();
|
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 SaveAllClientsTaskState();
|
||||||
void ReloadAllClientsTaskState(int TaskID=0);
|
void ReloadAllClientsTaskState(int TaskID=0);
|
||||||
|
|
||||||
uint16 CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time = 300000);
|
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 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);
|
uint16 CreateDoor(const char *model, const glm::vec4& position, uint8 type = 0, uint16 size = 100);
|
||||||
@ -429,6 +428,7 @@ public:
|
|||||||
uint16 GetFreeID();
|
uint16 GetFreeID();
|
||||||
void RefreshAutoXTargets(Client *c);
|
void RefreshAutoXTargets(Client *c);
|
||||||
void RefreshClientXTargets(Client *c);
|
void RefreshClientXTargets(Client *c);
|
||||||
|
void SendAlternateAdvancementStats();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Zone;
|
friend class Zone;
|
||||||
|
|||||||
@ -515,7 +515,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
if (GetLevel() < 51) {
|
if (GetLevel() < 51) {
|
||||||
m_epp.perAA = 0; // turn off aa exp if they drop below 51
|
m_epp.perAA = 0; // turn off aa exp if they drop below 51
|
||||||
} else
|
} 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
|
//send the expdata in any case so the xp bar isnt stuck after leveling
|
||||||
uint32 tmpxp1 = GetEXPForLevel(GetLevel()+1);
|
uint32 tmpxp1 = GetEXPForLevel(GetLevel()+1);
|
||||||
|
|||||||
@ -350,6 +350,11 @@ const char *Lua_Client::AccountName() {
|
|||||||
return self->AccountName();
|
return self->AccountName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Lua_Client::GetAccountAge() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return time(nullptr) - self->GetAccountCreation();
|
||||||
|
}
|
||||||
|
|
||||||
int Lua_Client::Admin() {
|
int Lua_Client::Admin() {
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
return self->Admin();
|
return self->Admin();
|
||||||
@ -1024,7 +1029,17 @@ void Lua_Client::AddLevelBasedExp(int exp_pct, int max_level) {
|
|||||||
|
|
||||||
void Lua_Client::IncrementAA(int aa) {
|
void Lua_Client::IncrementAA(int aa) {
|
||||||
Lua_Safe_Call_Void();
|
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) {
|
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("GetRawItemAC", (int(Lua_Client::*)(void))&Lua_Client::GetRawItemAC)
|
||||||
.def("AccountID", (uint32(Lua_Client::*)(void))&Lua_Client::AccountID)
|
.def("AccountID", (uint32(Lua_Client::*)(void))&Lua_Client::AccountID)
|
||||||
.def("AccountName", (const char *(Lua_Client::*)(void))&Lua_Client::AccountName)
|
.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("Admin", (int(Lua_Client::*)(void))&Lua_Client::Admin)
|
||||||
.def("CharacterID", (uint32(Lua_Client::*)(void))&Lua_Client::CharacterID)
|
.def("CharacterID", (uint32(Lua_Client::*)(void))&Lua_Client::CharacterID)
|
||||||
.def("GuildRank", (int(Lua_Client::*)(void))&Lua_Client::GuildRank)
|
.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))&Lua_Client::AddLevelBasedExp)
|
||||||
.def("AddLevelBasedExp", (void(Lua_Client::*)(int,int))&Lua_Client::AddLevelBasedExp)
|
.def("AddLevelBasedExp", (void(Lua_Client::*)(int,int))&Lua_Client::AddLevelBasedExp)
|
||||||
.def("IncrementAA", (void(Lua_Client::*)(int))&Lua_Client::IncrementAA)
|
.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))&Lua_Client::MarkSingleCompassLoc)
|
||||||
.def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float,int))&Lua_Client::MarkSingleCompassLoc)
|
.def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float,int))&Lua_Client::MarkSingleCompassLoc)
|
||||||
.def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(void))&Lua_Client::GetNextAvailableSpellBookSlot)
|
.def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(void))&Lua_Client::GetNextAvailableSpellBookSlot)
|
||||||
|
|||||||
@ -233,6 +233,8 @@ public:
|
|||||||
void AddLevelBasedExp(int exp_pct);
|
void AddLevelBasedExp(int exp_pct);
|
||||||
void AddLevelBasedExp(int exp_pct, int max_level);
|
void AddLevelBasedExp(int exp_pct, int max_level);
|
||||||
void IncrementAA(int aa);
|
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);
|
||||||
void MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count);
|
void MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count);
|
||||||
int GetNextAvailableSpellBookSlot();
|
int GetNextAvailableSpellBookSlot();
|
||||||
@ -260,6 +262,7 @@ public:
|
|||||||
bool HasSpellScribed(int spell_id);
|
bool HasSpellScribed(int spell_id);
|
||||||
void SetAccountFlag(std::string flag, std::string val);
|
void SetAccountFlag(std::string flag, std::string val);
|
||||||
std::string GetAccountFlag(std::string flag);
|
std::string GetAccountFlag(std::string flag);
|
||||||
|
int GetAccountAge();
|
||||||
Lua_Group GetGroup();
|
Lua_Group GetGroup();
|
||||||
Lua_Raid GetRaid();
|
Lua_Raid GetRaid();
|
||||||
bool PutItemInInventory(int slot_id, Lua_ItemInst inst);
|
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;
|
int16 res = resist_adjust;
|
||||||
|
|
||||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
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) {
|
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target) {
|
||||||
@ -1195,6 +1195,21 @@ int Lua_Mob::GetAA(int id) {
|
|||||||
return self->GetAA(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() {
|
bool Lua_Mob::DivineAura() {
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
return self->DivineAura();
|
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))&Lua_Mob::CheckHealAggroAmount)
|
||||||
.def("CheckHealAggroAmount", (int(Lua_Mob::*)(int,uint32))&Lua_Mob::CheckHealAggroAmount)
|
.def("CheckHealAggroAmount", (int(Lua_Mob::*)(int,uint32))&Lua_Mob::CheckHealAggroAmount)
|
||||||
.def("GetAA", (int(Lua_Mob::*)(int))&Lua_Mob::GetAA)
|
.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("DivineAura", (bool(Lua_Mob::*)(void))&Lua_Mob::DivineAura)
|
||||||
.def("SetOOCRegen", (void(Lua_Mob::*)(int))&Lua_Mob::SetOOCRegen)
|
.def("SetOOCRegen", (void(Lua_Mob::*)(int))&Lua_Mob::SetOOCRegen)
|
||||||
.def("GetEntityVariable", (const char*(Lua_Mob::*)(const char*))&Lua_Mob::GetEntityVariable)
|
.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);
|
||||||
int CheckHealAggroAmount(int spell_id, uint32 heal_possible);
|
int CheckHealAggroAmount(int spell_id, uint32 heal_possible);
|
||||||
int GetAA(int id);
|
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();
|
bool DivineAura();
|
||||||
void SetOOCRegen(int regen);
|
void SetOOCRegen(int regen);
|
||||||
const char* GetEntityVariable(const char *name);
|
const char* GetEntityVariable(const char *name);
|
||||||
|
|||||||
13
zone/mob.cpp
13
zone/mob.cpp
@ -307,8 +307,8 @@ Mob::Mob(const char* in_name,
|
|||||||
casting_spell_id = 0;
|
casting_spell_id = 0;
|
||||||
casting_spell_timer = 0;
|
casting_spell_timer = 0;
|
||||||
casting_spell_timer_duration = 0;
|
casting_spell_timer_duration = 0;
|
||||||
casting_spell_type = 0;
|
|
||||||
casting_spell_inventory_slot = 0;
|
casting_spell_inventory_slot = 0;
|
||||||
|
casting_spell_aa_id = 0;
|
||||||
target = 0;
|
target = 0;
|
||||||
|
|
||||||
ActiveProjectileATK = false;
|
ActiveProjectileATK = false;
|
||||||
@ -1142,6 +1142,10 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
|||||||
else
|
else
|
||||||
ns->spawn.flymode = flymode;
|
ns->spawn.flymode = flymode;
|
||||||
|
|
||||||
|
if(IsBoat()) {
|
||||||
|
ns->spawn.flymode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
ns->spawn.lastName[0] = '\0';
|
ns->spawn.lastName[0] = '\0';
|
||||||
|
|
||||||
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
|
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
|
||||||
@ -3512,7 +3516,9 @@ void Mob::TriggerOnCast(uint32 focus_spell, uint32 spell_id, bool aa_trigger)
|
|||||||
|
|
||||||
if (aa_trigger && IsClient()) {
|
if (aa_trigger && IsClient()) {
|
||||||
// focus_spell = aaid
|
// focus_spell = aaid
|
||||||
trigger_spell_id = CastToClient()->CalcAAFocus(focusTriggerOnCast, focus_spell, spell_id);
|
auto rank = zone->GetAlternateAdvancementRank(focus_spell);
|
||||||
|
if (rank)
|
||||||
|
trigger_spell_id = CastToClient()->CalcAAFocus(focusTriggerOnCast, *rank, spell_id);
|
||||||
|
|
||||||
if(IsValidSpell(trigger_spell_id) && GetTarget())
|
if(IsValidSpell(trigger_spell_id) && GetTarget())
|
||||||
SpellFinished(trigger_spell_id, GetTarget(), 10, 0, -1, spells[trigger_spell_id].ResistDiff);
|
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] +
|
skilldmg_mod += itembonuses.SkillDmgTaken[HIGHEST_SKILL+1] + spellbonuses.SkillDmgTaken[HIGHEST_SKILL+1] +
|
||||||
itembonuses.SkillDmgTaken[skill_used] + spellbonuses.SkillDmgTaken[skill_used];
|
itembonuses.SkillDmgTaken[skill_used] + spellbonuses.SkillDmgTaken[skill_used];
|
||||||
|
|
||||||
|
|
||||||
skilldmg_mod += SkillDmgTaken_Mod[skill_used] + SkillDmgTaken_Mod[HIGHEST_SKILL+1];
|
skilldmg_mod += SkillDmgTaken_Mod[skill_used] + SkillDmgTaken_Mod[HIGHEST_SKILL+1];
|
||||||
|
|
||||||
skilldmg_mod += spellbonuses.MeleeVulnerability + itembonuses.MeleeVulnerability + aabonuses.MeleeVulnerability;
|
|
||||||
|
|
||||||
if(skilldmg_mod < -100)
|
if(skilldmg_mod < -100)
|
||||||
skilldmg_mod = -100;
|
skilldmg_mod = -100;
|
||||||
|
|
||||||
|
|||||||
27
zone/mob.h
27
zone/mob.h
@ -23,6 +23,8 @@
|
|||||||
#include "hate_list.h"
|
#include "hate_list.h"
|
||||||
#include "pathing.h"
|
#include "pathing.h"
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
|
#include "aa_ability.h"
|
||||||
|
#include "aa.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -221,10 +223,12 @@ public:
|
|||||||
virtual void SpellProcess();
|
virtual void SpellProcess();
|
||||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1,
|
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,
|
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,
|
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,
|
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,
|
void CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, uint16 mana_used,
|
||||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
|
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
|
||||||
bool SpellFinished(uint16 spell_id, Mob *target, uint16 slot = 10, uint16 mana_used = 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
|
uint32 GetZoneID() const; //for perl
|
||||||
virtual int32 CheckAggroAmount(uint16 spell_id, bool isproc = false);
|
virtual int32 CheckAggroAmount(uint16 spell_id, bool isproc = false);
|
||||||
virtual int32 CheckHealAggroAmount(uint16 spell_id, uint32 heal_possible = 0);
|
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;
|
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);
|
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_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);
|
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:
|
protected:
|
||||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
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);
|
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||||
@ -969,7 +985,6 @@ protected:
|
|||||||
virtual bool AI_PursueCastCheck() { return(false); }
|
virtual bool AI_PursueCastCheck() { return(false); }
|
||||||
virtual bool AI_IdleCastCheck() { return(false); }
|
virtual bool AI_IdleCastCheck() { return(false); }
|
||||||
|
|
||||||
|
|
||||||
bool IsFullHP;
|
bool IsFullHP;
|
||||||
bool moved;
|
bool moved;
|
||||||
|
|
||||||
@ -1145,6 +1160,7 @@ protected:
|
|||||||
uint32 casting_spell_timer_duration;
|
uint32 casting_spell_timer_duration;
|
||||||
uint32 casting_spell_type;
|
uint32 casting_spell_type;
|
||||||
int16 casting_spell_resist_adjust;
|
int16 casting_spell_resist_adjust;
|
||||||
|
uint32 casting_spell_aa_id;
|
||||||
bool casting_spell_checks;
|
bool casting_spell_checks;
|
||||||
uint16 bardsong;
|
uint16 bardsong;
|
||||||
uint8 bardsong_slot;
|
uint8 bardsong_slot;
|
||||||
@ -1311,6 +1327,9 @@ protected:
|
|||||||
bool bEnraged;
|
bool bEnraged;
|
||||||
bool destructibleobject;
|
bool destructibleobject;
|
||||||
|
|
||||||
|
std::unordered_map<uint32, std::pair<uint32, uint32>> aa_ranks;
|
||||||
|
Timer aa_timers[aaTimerMax];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _StopSong(); //this is not what you think it is
|
void _StopSong(); //this is not what you think it is
|
||||||
Mob* target;
|
Mob* target;
|
||||||
|
|||||||
@ -342,7 +342,7 @@ bool NPC::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
|
|||||||
SetCurrentSpeed(0);
|
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) {
|
bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint16 iSpellTypes) {
|
||||||
|
|||||||
@ -96,7 +96,6 @@ EntityList entity_list;
|
|||||||
WorldServer worldserver;
|
WorldServer worldserver;
|
||||||
uint32 numclients = 0;
|
uint32 numclients = 0;
|
||||||
char errorname[32];
|
char errorname[32];
|
||||||
uint16 adverrornum = 0;
|
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
EQStreamFactory eqsf(ZoneStream);
|
EQStreamFactory eqsf(ZoneStream);
|
||||||
npcDecayTimes_Struct npcCorpseDecayTimes[100];
|
npcDecayTimes_Struct npcCorpseDecayTimes[100];
|
||||||
@ -249,9 +248,6 @@ int main(int argc, char** argv) {
|
|||||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading titles");
|
Log.Out(Logs::General, Logs::Zone_Server, "Loading titles");
|
||||||
title_manager.LoadTitles();
|
title_manager.LoadTitles();
|
||||||
|
|
||||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading AA effects");
|
|
||||||
database.LoadAAEffects();
|
|
||||||
|
|
||||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading tributes");
|
Log.Out(Logs::General, Logs::Zone_Server, "Loading tributes");
|
||||||
database.LoadTributes();
|
database.LoadTributes();
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,6 @@
|
|||||||
#include "../common/linked_list.h"
|
#include "../common/linked_list.h"
|
||||||
#include "../common/servertalk.h"
|
#include "../common/servertalk.h"
|
||||||
|
|
||||||
#include "aa.h"
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
#include "npc.h"
|
#include "npc.h"
|
||||||
|
|||||||
@ -4077,33 +4077,7 @@ XS(XS_Client_RefundAA) {
|
|||||||
if(THIS == nullptr)
|
if(THIS == nullptr)
|
||||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
int curpt = 0;
|
THIS->RefundAA();
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
@ -4915,11 +4889,44 @@ XS(XS_Client_IncrementAA)
|
|||||||
if(THIS == nullptr)
|
if(THIS == nullptr)
|
||||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
THIS->IncrementAA(aaskillid);
|
THIS->IncrementAlternateAdvancementRank(aaskillid);
|
||||||
}
|
}
|
||||||
XSRETURN_EMPTY;
|
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);
|
||||||
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, "GetIP"), XS_Client_GetIP, file, "$");
|
||||||
newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$");
|
newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$");
|
||||||
newXSproto(strcpy(buf, "IncrementAA"), XS_Client_IncrementAA, 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, "GetAALevel"), XS_Client_GetAALevel, file, "$$");
|
||||||
newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$");
|
newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$");
|
||||||
newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, 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
|
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
|
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;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
@ -6360,7 +6360,34 @@ XS(XS_Mob_GetAA)
|
|||||||
{
|
{
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
if (items != 2)
|
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 rank_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->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;
|
Mob * THIS;
|
||||||
uint32 RETVAL;
|
uint32 RETVAL;
|
||||||
@ -6376,12 +6403,41 @@ XS(XS_Mob_GetAA)
|
|||||||
if(THIS == nullptr)
|
if(THIS == nullptr)
|
||||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
RETVAL = THIS->GetAA(aa_id);
|
RETVAL = THIS->GetAAByAAID(aa_id);
|
||||||
XSprePUSH; PUSHu((UV)RETVAL);
|
XSprePUSH; PUSHu((UV)RETVAL);
|
||||||
}
|
}
|
||||||
XSRETURN(1);
|
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); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_Mob_DivineAura)
|
XS(XS_Mob_DivineAura)
|
||||||
{
|
{
|
||||||
@ -8625,6 +8681,8 @@ XS(boot_Mob)
|
|||||||
newXSproto(strcpy(buf, "CheckAggroAmount"), XS_Mob_CheckAggroAmount, file, "$$");
|
newXSproto(strcpy(buf, "CheckAggroAmount"), XS_Mob_CheckAggroAmount, file, "$$");
|
||||||
newXSproto(strcpy(buf, "CheckHealAggroAmount"), XS_Mob_CheckHealAggroAmount, file, "$$");
|
newXSproto(strcpy(buf, "CheckHealAggroAmount"), XS_Mob_CheckHealAggroAmount, file, "$$");
|
||||||
newXSproto(strcpy(buf, "GetAA"), XS_Mob_GetAA, 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, "DivineAura"), XS_Mob_DivineAura, file, "$");
|
||||||
newXSproto(strcpy(buf, "AddFeignMemory"), XS_Mob_AddFeignMemory, file, "$$");
|
newXSproto(strcpy(buf, "AddFeignMemory"), XS_Mob_AddFeignMemory, file, "$$");
|
||||||
newXSproto(strcpy(buf, "RemoveFromFeignMemory"), XS_Mob_RemoveFromFeignMemory, 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);
|
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);
|
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).
|
//Make sure 'this' has not killed the target and 'this' is not dead (Damage shield ect).
|
||||||
if(!GetTarget())return;
|
if(!GetTarget())return;
|
||||||
if (HasDied()) 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())
|
if (HasSkillProcs())
|
||||||
TrySkillProc(who, skill, ReuseTime*1000);
|
TrySkillProc(who, skill, ReuseTime*1000);
|
||||||
|
|
||||||
@ -2442,19 +2439,18 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
}
|
}
|
||||||
|
|
||||||
other->AddToHateList(this, hate, 0, false);
|
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);
|
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse);
|
||||||
|
|
||||||
if (HasDied())
|
if (HasDied())
|
||||||
return;
|
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())
|
if (CanSkillProc && HasSkillProcs())
|
||||||
TrySkillProc(other, skillinuse, ReuseTime);
|
TrySkillProc(other, skillinuse, ReuseTime);
|
||||||
|
|
||||||
|
|||||||
@ -638,41 +638,23 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
snprintf(effect_desc, _EDLEN, "Group Fear Immunity");
|
snprintf(effect_desc, _EDLEN, "Group Fear Immunity");
|
||||||
#endif
|
#endif
|
||||||
//Added client messages to give some indication this effect is active.
|
//Added client messages to give some indication this effect is active.
|
||||||
uint32 group_id_caster = 0;
|
// Is there a message generated? Too disgusted by raids.
|
||||||
uint32 time = spell.base[i]*10;
|
uint32 time = spell.base[i] * 10 * 1000;
|
||||||
if(caster->IsClient())
|
if (caster->IsClient()) {
|
||||||
{
|
if (caster->IsGrouped()) {
|
||||||
if(caster->IsGrouped())
|
auto group = caster->GetGroup();
|
||||||
{
|
for (int i = 0; i < 6; ++i)
|
||||||
group_id_caster = GetGroup()->GetID();
|
if (group->members[i])
|
||||||
}
|
group->members[i]->aa_timers[aaTimerWarcry].Start(time);
|
||||||
else if(caster->IsRaidGrouped())
|
} else if (caster->IsRaidGrouped()) {
|
||||||
{
|
auto raid = caster->GetRaid();
|
||||||
group_id_caster = (GetRaid()->GetGroup(CastToClient()) == 0xFFFF) ? 0 : (GetRaid()->GetGroup(CastToClient()) + 1);
|
uint32 gid = raid->GetGroup(caster->CastToClient());
|
||||||
|
if (gid < 12)
|
||||||
|
for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
|
||||||
|
if (raid->members[i].member && raid->members[i].GroupNumber == gid)
|
||||||
|
raid->members[i].member->aa_timers[aaTimerWarcry].Start(time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(group_id_caster){
|
|
||||||
Group *g = entity_list.GetGroupByID(group_id_caster);
|
|
||||||
uint32 time = spell.base[i]*10;
|
|
||||||
if(g){
|
|
||||||
for(int gi=0; gi < 6; gi++){
|
|
||||||
if(g->members[gi] && g->members[gi]->IsClient())
|
|
||||||
{
|
|
||||||
g->members[gi]->CastToClient()->EnableAAEffect(aaEffectWarcry , time);
|
|
||||||
if (g->members[gi]->GetID() != caster->GetID())
|
|
||||||
g->members[gi]->Message(13, "You hear the war cry.");
|
|
||||||
else
|
|
||||||
Message(13, "You let loose a fierce war cry.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else{
|
|
||||||
CastToClient()->EnableAAEffect(aaEffectWarcry , time);
|
|
||||||
Message(13, "You let loose a fierce war cry.");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1788,9 +1770,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(spells[spell_id].base2[i] == 0)
|
if(spells[spell_id].base2[i] == 0)
|
||||||
AddProcToWeapon(procid, false, 100, spell_id, level_override);
|
AddProcToWeapon(procid, false, 100, spell_id, caster_level);
|
||||||
else
|
else
|
||||||
AddProcToWeapon(procid, false, spells[spell_id].base2[i]+100, spell_id, level_override);
|
AddProcToWeapon(procid, false, spells[spell_id].base2[i]+100, spell_id, caster_level);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2232,12 +2214,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
|
|
||||||
case SE_AEMelee:
|
case SE_AEMelee:
|
||||||
{
|
{
|
||||||
|
//old aa
|
||||||
|
|
||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
snprintf(effect_desc, _EDLEN, "Duration Rampage");
|
snprintf(effect_desc, _EDLEN, "Duration Rampage");
|
||||||
#endif
|
#endif
|
||||||
if (caster && caster->IsClient()) { // will tidy this up later so that NPCs can duration ramp from spells too
|
aa_timers[aaTimerRampage].Start(effect_value * 10 * 1000); // Live bug, was suppose to be 1 second per value
|
||||||
CastToClient()->DurationRampage(effect_value*12);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2966,7 +2948,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
case SE_FcIncreaseNumHits:
|
case SE_FcIncreaseNumHits:
|
||||||
case SE_CastonFocusEffect:
|
case SE_CastonFocusEffect:
|
||||||
case SE_FcHealAmtIncoming:
|
case SE_FcHealAmtIncoming:
|
||||||
case SE_MeleeVulnerability:
|
case SE_LimitManaMax:
|
||||||
case SE_DoubleRangedAttack:
|
case SE_DoubleRangedAttack:
|
||||||
case SE_ShieldEquipHateMod:
|
case SE_ShieldEquipHateMod:
|
||||||
case SE_ShieldEquipDmgMod:
|
case SE_ShieldEquipDmgMod:
|
||||||
@ -3374,7 +3356,7 @@ void Mob::BuffProcess()
|
|||||||
{
|
{
|
||||||
--buffs[buffs_i].ticsremaining;
|
--buffs[buffs_i].ticsremaining;
|
||||||
|
|
||||||
if ((buffs[buffs_i].ticsremaining == 0 && !IsShortDurationBuff(buffs[buffs_i].spellid)) || buffs[buffs_i].ticsremaining < 0) {
|
if ((buffs[buffs_i].ticsremaining == 0 && !(IsShortDurationBuff(buffs[buffs_i].spellid) || IsBardSong(buffs[buffs_i].spellid))) || buffs[buffs_i].ticsremaining < 0) {
|
||||||
Log.Out(Logs::Detail, Logs::Spells, "Buff %d in slot %d has expired. Fading.", buffs[buffs_i].spellid, buffs_i);
|
Log.Out(Logs::Detail, Logs::Spells, "Buff %d in slot %d has expired. Fading.", buffs[buffs_i].spellid, buffs_i);
|
||||||
BuffFadeBySlot(buffs_i);
|
BuffFadeBySlot(buffs_i);
|
||||||
}
|
}
|
||||||
@ -3435,11 +3417,6 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for non buff spell effects to fade
|
|
||||||
// AE melee effects
|
|
||||||
if (IsClient())
|
|
||||||
CastToClient()->CheckAAEffect(aaEffectRampage);
|
|
||||||
|
|
||||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||||
if (IsBlankSpellEffect(buff.spellid, i))
|
if (IsBlankSpellEffect(buff.spellid, i))
|
||||||
continue;
|
continue;
|
||||||
@ -4149,44 +4126,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
|||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 Client::GetAAEffectDataBySlot(uint32 aa_ID, uint32 slot_id, bool GetEffect, bool GetBase1, bool GetBase2)
|
int16 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
|
||||||
{
|
|
||||||
int32 aa_effects_data[3] = { 0 };
|
|
||||||
uint32 effect = 0;
|
|
||||||
int32 base1 = 0;
|
|
||||||
int32 base2 = 0;
|
|
||||||
uint32 slot = 0;
|
|
||||||
|
|
||||||
|
|
||||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aa_ID);
|
|
||||||
if(find_iter == aa_effects.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (std::map<uint32, AA_Ability>::const_iterator iter = aa_effects[aa_ID].begin(); iter != aa_effects[aa_ID].end(); ++iter)
|
|
||||||
{
|
|
||||||
effect = iter->second.skill_id;
|
|
||||||
base1 = iter->second.base1;
|
|
||||||
base2 = iter->second.base2;
|
|
||||||
slot = iter->second.slot;
|
|
||||||
|
|
||||||
if (slot && slot == slot_id) {
|
|
||||||
|
|
||||||
if (GetEffect)
|
|
||||||
return effect;
|
|
||||||
|
|
||||||
if (GetBase1)
|
|
||||||
return base1;
|
|
||||||
|
|
||||||
if (GetBase2)
|
|
||||||
return base2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|
||||||
{
|
{
|
||||||
const SPDat_Spell_Struct &spell = spells[spell_id];
|
const SPDat_Spell_Struct &spell = spells[spell_id];
|
||||||
|
|
||||||
@ -4201,7 +4141,8 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
|
|
||||||
bool LimitFailure = false;
|
bool LimitFailure = false;
|
||||||
bool LimitInclude[MaxLimitInclude] = {false};
|
bool LimitInclude[MaxLimitInclude] = {false};
|
||||||
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice spells.
|
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice
|
||||||
|
spells.
|
||||||
0/1 SE_LimitResist
|
0/1 SE_LimitResist
|
||||||
2/3 SE_LimitSpell
|
2/3 SE_LimitSpell
|
||||||
4/5 SE_LimitEffect
|
4/5 SE_LimitEffect
|
||||||
@ -4214,18 +4155,11 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
*/
|
*/
|
||||||
int FocusCount = 0;
|
int FocusCount = 0;
|
||||||
|
|
||||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aa_ID);
|
for (const auto &e : rank.effects) {
|
||||||
if(find_iter == aa_effects.end())
|
effect = e.effect_id;
|
||||||
{
|
base1 = e.base1;
|
||||||
return 0;
|
base2 = e.base2;
|
||||||
}
|
slot = e.slot;
|
||||||
|
|
||||||
for (std::map<uint32, AA_Ability>::const_iterator iter = aa_effects[aa_ID].begin(); iter != aa_effects[aa_ID].end(); ++iter)
|
|
||||||
{
|
|
||||||
effect = iter->second.skill_id;
|
|
||||||
base1 = iter->second.base1;
|
|
||||||
base2 = iter->second.base2;
|
|
||||||
slot = iter->second.slot;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AA Foci's can contain multiple focus effects within the same AA.
|
AA Foci's can contain multiple focus effects within the same AA.
|
||||||
@ -4259,9 +4193,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (effect) {
|
||||||
switch (effect)
|
|
||||||
{
|
|
||||||
case SE_Blank:
|
case SE_Blank:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4271,8 +4203,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (base1 < 0) {
|
if (base1 < 0) {
|
||||||
if (spell.resisttype == -base1) // Exclude
|
if (spell.resisttype == -base1) // Exclude
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[0] = true;
|
LimitInclude[0] = true;
|
||||||
if (spell.resisttype == base1) // Include
|
if (spell.resisttype == base1) // Include
|
||||||
LimitInclude[1] = true;
|
LimitInclude[1] = true;
|
||||||
@ -4290,14 +4221,15 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
case SE_LimitMaxLevel:
|
case SE_LimitMaxLevel:
|
||||||
spell_level = spell.classes[(GetClass() % 16) - 1];
|
spell_level = spell.classes[(GetClass() % 16) - 1];
|
||||||
lvldiff = spell_level - base1;
|
lvldiff = spell_level - base1;
|
||||||
//every level over cap reduces the effect by base2 percent unless from a clicky when ItemCastsUseFocus is true
|
// every level over cap reduces the effect by base2 percent unless from a clicky when
|
||||||
if(lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) || RuleB(Character, ItemCastsUseFocus) == false)) {
|
// ItemCastsUseFocus is true
|
||||||
|
if (lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) ||
|
||||||
|
RuleB(Character, ItemCastsUseFocus) == false)) {
|
||||||
if (base2 > 0) {
|
if (base2 > 0) {
|
||||||
lvlModifier -= base2 * lvldiff;
|
lvlModifier -= base2 * lvldiff;
|
||||||
if (lvlModifier < 1)
|
if (lvlModifier < 1)
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4321,8 +4253,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (base1 < 0) { // Exclude
|
if (base1 < 0) { // Exclude
|
||||||
if (spell_id == -base1)
|
if (spell_id == -base1)
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[2] = true;
|
LimitInclude[2] = true;
|
||||||
if (spell_id == base1) // Include
|
if (spell_id == base1) // Include
|
||||||
LimitInclude[3] = true;
|
LimitInclude[3] = true;
|
||||||
@ -4339,17 +4270,21 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (base1 < 0) {
|
if (base1 < 0) {
|
||||||
if (IsEffectInSpell(spell_id, -base1)) // Exclude
|
if (IsEffectInSpell(spell_id, -base1)) // Exclude
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
LimitInclude[4] = true;
|
LimitInclude[4] = true;
|
||||||
|
// they use 33 here for all classes ... unsure if the type check is really needed
|
||||||
|
if (base1 == SE_SummonPet && type == focusReagentCost) {
|
||||||
|
if (IsSummonPetSpell(spell_id) || IsSummonSkeletonSpell(spell_id))
|
||||||
|
LimitInclude[5] = true;
|
||||||
|
} else {
|
||||||
if (IsEffectInSpell(spell_id, base1)) // Include
|
if (IsEffectInSpell(spell_id, base1)) // Include
|
||||||
LimitInclude[5] = true;
|
LimitInclude[5] = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitSpellType:
|
case SE_LimitSpellType:
|
||||||
switch(base1)
|
switch (base1) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
if (!IsDetrimentalSpell(spell_id))
|
if (!IsDetrimentalSpell(spell_id))
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
@ -4366,12 +4301,16 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_LimitManaMax:
|
||||||
|
if (spell.mana > base1)
|
||||||
|
LimitFailure = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case SE_LimitTarget:
|
case SE_LimitTarget:
|
||||||
if (base1 < 0) {
|
if (base1 < 0) {
|
||||||
if (-base1 == spell.targettype) // Exclude
|
if (-base1 == spell.targettype) // Exclude
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[6] = true;
|
LimitInclude[6] = true;
|
||||||
if (base1 == spell.targettype) // Include
|
if (base1 == spell.targettype) // Include
|
||||||
LimitInclude[7] = true;
|
LimitInclude[7] = true;
|
||||||
@ -4390,8 +4329,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (base1 < 0) {
|
if (base1 < 0) {
|
||||||
if (-base1 == spell.spellgroup) // Exclude
|
if (-base1 == spell.spellgroup) // Exclude
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[8] = true;
|
LimitInclude[8] = true;
|
||||||
if (base1 == spell.spellgroup) // Include
|
if (base1 == spell.spellgroup) // Include
|
||||||
LimitInclude[9] = true;
|
LimitInclude[9] = true;
|
||||||
@ -4402,8 +4340,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (base1 < 0) {
|
if (base1 < 0) {
|
||||||
if (-base1 == spell.skill)
|
if (-base1 == spell.skill)
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[10] = true;
|
LimitInclude[10] = true;
|
||||||
if (base1 == spell.skill)
|
if (base1 == spell.skill)
|
||||||
LimitInclude[11] = true;
|
LimitInclude[11] = true;
|
||||||
@ -4414,8 +4351,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (base1 < 0) { // Exclude
|
if (base1 < 0) { // Exclude
|
||||||
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass))
|
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass))
|
||||||
return (0);
|
return (0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[12] = true;
|
LimitInclude[12] = true;
|
||||||
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass)) // Include
|
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass)) // Include
|
||||||
LimitInclude[13] = true;
|
LimitInclude[13] = true;
|
||||||
@ -4426,8 +4362,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (base1 < 0) { // Exclude
|
if (base1 < 0) { // Exclude
|
||||||
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass))
|
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass))
|
||||||
return (0);
|
return (0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[14] = true;
|
LimitInclude[14] = true;
|
||||||
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass)) // Include
|
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass)) // Include
|
||||||
LimitInclude[15] = true;
|
LimitInclude[15] = true;
|
||||||
@ -4435,7 +4370,8 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitClass:
|
case SE_LimitClass:
|
||||||
//Do not use this limit more then once per spell. If multiple class, treat value like items would.
|
// Do not use this limit more then once per spell. If multiple class, treat value like items
|
||||||
|
// would.
|
||||||
if (!PassLimitClass(base1, GetClass()))
|
if (!PassLimitClass(base1, GetClass()))
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
break;
|
break;
|
||||||
@ -4517,13 +4453,11 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
if (base1 > value)
|
if (base1 > value)
|
||||||
value = base1;
|
value = base1;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
if (base1 < value)
|
if (base1 < value)
|
||||||
value = base1;
|
value = base1;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
value = base1;
|
value = base1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4636,7 +4570,6 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (type == focusFcStunTimeMod)
|
if (type == focusFcStunTimeMod)
|
||||||
value = base1;
|
value = base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4653,12 +4586,11 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
|
|
||||||
//given an item/spell's focus ID and the spell being cast, determine the focus ammount, if any
|
//given an item/spell's focus ID and the spell being cast, determine the focus ammount, if any
|
||||||
//assumes that spell_id is not a bard spell and that both ids are valid spell ids
|
//assumes that spell_id is not a bard spell and that both ids are valid spell ids
|
||||||
int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus) {
|
int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus)
|
||||||
|
{
|
||||||
if (!IsValidSpell(focus_id) || !IsValidSpell(spell_id))
|
if (!IsValidSpell(focus_id) || !IsValidSpell(spell_id))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
const SPDat_Spell_Struct &focus_spell = spells[focus_id];
|
const SPDat_Spell_Struct &focus_spell = spells[focus_id];
|
||||||
const SPDat_Spell_Struct &spell = spells[spell_id];
|
const SPDat_Spell_Struct &spell = spells[spell_id];
|
||||||
|
|
||||||
@ -4669,7 +4601,8 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
uint32 Caston_spell_id = 0;
|
uint32 Caston_spell_id = 0;
|
||||||
|
|
||||||
bool LimitInclude[MaxLimitInclude] = {false};
|
bool LimitInclude[MaxLimitInclude] = {false};
|
||||||
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice spells.
|
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice
|
||||||
|
spells.
|
||||||
0/1 SE_LimitResist
|
0/1 SE_LimitResist
|
||||||
2/3 SE_LimitSpell
|
2/3 SE_LimitSpell
|
||||||
4/5 SE_LimitEffect
|
4/5 SE_LimitEffect
|
||||||
@ -4692,8 +4625,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (focus_spell.base[i] < 0) {
|
if (focus_spell.base[i] < 0) {
|
||||||
if (spell.resisttype == -focus_spell.base[i]) // Exclude
|
if (spell.resisttype == -focus_spell.base[i]) // Exclude
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[0] = true;
|
LimitInclude[0] = true;
|
||||||
if (spell.resisttype == focus_spell.base[i]) // Include
|
if (spell.resisttype == focus_spell.base[i]) // Include
|
||||||
LimitInclude[1] = true;
|
LimitInclude[1] = true;
|
||||||
@ -4713,14 +4645,15 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
break;
|
break;
|
||||||
spell_level = spell.classes[(GetClass() % 16) - 1];
|
spell_level = spell.classes[(GetClass() % 16) - 1];
|
||||||
lvldiff = spell_level - focus_spell.base[i];
|
lvldiff = spell_level - focus_spell.base[i];
|
||||||
//every level over cap reduces the effect by focus_spell.base2[i] percent unless from a clicky when ItemCastsUseFocus is true
|
// every level over cap reduces the effect by focus_spell.base2[i] percent unless from a clicky
|
||||||
if(lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) || RuleB(Character, ItemCastsUseFocus) == false)){
|
// when ItemCastsUseFocus is true
|
||||||
|
if (lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) ||
|
||||||
|
RuleB(Character, ItemCastsUseFocus) == false)) {
|
||||||
if (focus_spell.base2[i] > 0) {
|
if (focus_spell.base2[i] > 0) {
|
||||||
lvlModifier -= focus_spell.base2[i] * lvldiff;
|
lvlModifier -= focus_spell.base2[i] * lvldiff;
|
||||||
if (lvlModifier < 1)
|
if (lvlModifier < 1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4746,8 +4679,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (focus_spell.base[i] < 0) { // Exclude
|
if (focus_spell.base[i] < 0) { // Exclude
|
||||||
if (spell_id == -focus_spell.base[i])
|
if (spell_id == -focus_spell.base[i])
|
||||||
return (0);
|
return (0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[2] = true;
|
LimitInclude[2] = true;
|
||||||
if (spell_id == focus_spell.base[i]) // Include
|
if (spell_id == focus_spell.base[i]) // Include
|
||||||
LimitInclude[3] = true;
|
LimitInclude[3] = true;
|
||||||
@ -4755,7 +4687,8 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitMinDur:
|
case SE_LimitMinDur:
|
||||||
if (focus_spell.base[i] > CalcBuffDuration_formula(GetLevel(), spell.buffdurationformula, spell.buffduration))
|
if (focus_spell.base[i] >
|
||||||
|
CalcBuffDuration_formula(GetLevel(), spell.buffdurationformula, spell.buffduration))
|
||||||
return (0);
|
return (0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4763,15 +4696,13 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (focus_spell.base[i] < 0) {
|
if (focus_spell.base[i] < 0) {
|
||||||
if (IsEffectInSpell(spell_id, -focus_spell.base[i])) // Exclude
|
if (IsEffectInSpell(spell_id, -focus_spell.base[i])) // Exclude
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
LimitInclude[4] = true;
|
LimitInclude[4] = true;
|
||||||
if (IsEffectInSpell(spell_id, focus_spell.base[i])) // Include
|
if (IsEffectInSpell(spell_id, focus_spell.base[i])) // Include
|
||||||
LimitInclude[5] = true;
|
LimitInclude[5] = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case SE_LimitSpellType:
|
case SE_LimitSpellType:
|
||||||
switch (focus_spell.base[i]) {
|
switch (focus_spell.base[i]) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -4783,7 +4714,8 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
|
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown limit spelltype %d",
|
||||||
|
focus_spell.base[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4792,12 +4724,16 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_LimitManaMax:
|
||||||
|
if (spell.mana > focus_spell.base[i])
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case SE_LimitTarget:
|
case SE_LimitTarget:
|
||||||
if (focus_spell.base[i] < 0) {
|
if (focus_spell.base[i] < 0) {
|
||||||
if (-focus_spell.base[i] == spell.targettype) // Exclude
|
if (-focus_spell.base[i] == spell.targettype) // Exclude
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[6] = true;
|
LimitInclude[6] = true;
|
||||||
if (focus_spell.base[i] == spell.targettype) // Include
|
if (focus_spell.base[i] == spell.targettype) // Include
|
||||||
LimitInclude[7] = true;
|
LimitInclude[7] = true;
|
||||||
@ -4805,9 +4741,11 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitCombatSkills:
|
case SE_LimitCombatSkills:
|
||||||
if (focus_spell.base[i] == 0 && (IsCombatSkill(spell_id) || IsCombatProc(spell_id))) //Exclude Discs / Procs
|
if (focus_spell.base[i] == 0 &&
|
||||||
|
(IsCombatSkill(spell_id) || IsCombatProc(spell_id))) // Exclude Discs / Procs
|
||||||
return 0;
|
return 0;
|
||||||
else if (focus_spell.base[i] == 1 && (!IsCombatSkill(spell_id) || !IsCombatProc(spell_id))) //Exclude Spells
|
else if (focus_spell.base[i] == 1 &&
|
||||||
|
(!IsCombatSkill(spell_id) || !IsCombatProc(spell_id))) // Exclude Spells
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -4816,8 +4754,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (focus_spell.base[i] < 0) {
|
if (focus_spell.base[i] < 0) {
|
||||||
if (-focus_spell.base[i] == spell.spellgroup) // Exclude
|
if (-focus_spell.base[i] == spell.spellgroup) // Exclude
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[8] = true;
|
LimitInclude[8] = true;
|
||||||
if (focus_spell.base[i] == spell.spellgroup) // Include
|
if (focus_spell.base[i] == spell.spellgroup) // Include
|
||||||
LimitInclude[9] = true;
|
LimitInclude[9] = true;
|
||||||
@ -4828,8 +4765,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (focus_spell.base[i] < 0) {
|
if (focus_spell.base[i] < 0) {
|
||||||
if (-focus_spell.base[i] == spell.skill)
|
if (-focus_spell.base[i] == spell.skill)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[10] = true;
|
LimitInclude[10] = true;
|
||||||
if (focus_spell.base[i] == spell.skill)
|
if (focus_spell.base[i] == spell.skill)
|
||||||
LimitInclude[11] = true;
|
LimitInclude[11] = true;
|
||||||
@ -4837,7 +4773,8 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitClass:
|
case SE_LimitClass:
|
||||||
//Do not use this limit more then once per spell. If multiple class, treat value like items would.
|
// Do not use this limit more then once per spell. If multiple class, treat value like items
|
||||||
|
// would.
|
||||||
if (!PassLimitClass(focus_spell.base[i], GetClass()))
|
if (!PassLimitClass(focus_spell.base[i], GetClass()))
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
@ -4866,8 +4803,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (focus_spell.base[i] < 0) { // Exclude
|
if (focus_spell.base[i] < 0) { // Exclude
|
||||||
if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellClass))
|
if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellClass))
|
||||||
return (0);
|
return (0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[12] = true;
|
LimitInclude[12] = true;
|
||||||
if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellClass)) // Include
|
if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellClass)) // Include
|
||||||
LimitInclude[13] = true;
|
LimitInclude[13] = true;
|
||||||
@ -4878,15 +4814,13 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (focus_spell.base[i] < 0) { // Exclude
|
if (focus_spell.base[i] < 0) { // Exclude
|
||||||
if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellSubclass))
|
if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellSubclass))
|
||||||
return (0);
|
return (0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LimitInclude[14] = true;
|
LimitInclude[14] = true;
|
||||||
if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellSubclass)) // Include
|
if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellSubclass)) // Include
|
||||||
LimitInclude[15] = true;
|
LimitInclude[15] = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
// handle effects
|
// handle effects
|
||||||
case SE_ImprovedDamage:
|
case SE_ImprovedDamage:
|
||||||
if (type == focusImprovedDamage) {
|
if (type == focusImprovedDamage) {
|
||||||
@ -4896,7 +4830,8 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (focus_spell.base2[i] != 0) {
|
if (focus_spell.base2[i] != 0) {
|
||||||
value = focus_spell.base2[i];
|
value = focus_spell.base2[i];
|
||||||
}
|
}
|
||||||
// If the spell does not contain a base2 value, then its a straight non random value
|
// If the spell does not contain a base2 value, then its a straight non random
|
||||||
|
// value
|
||||||
else {
|
else {
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
}
|
||||||
@ -4904,8 +4839,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
// Actual focus calculation starts here
|
// Actual focus calculation starts here
|
||||||
else if (focus_spell.base2[i] == 0 || focus_spell.base[i] == focus_spell.base2[i]) {
|
else if (focus_spell.base2[i] == 0 || focus_spell.base[i] == focus_spell.base2[i]) {
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]);
|
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4916,15 +4850,12 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (best_focus) {
|
if (best_focus) {
|
||||||
if (focus_spell.base2[i] != 0) {
|
if (focus_spell.base2[i] != 0) {
|
||||||
value = focus_spell.base2[i];
|
value = focus_spell.base2[i];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
}
|
||||||
}
|
} else if (focus_spell.base2[i] == 0 || focus_spell.base[i] == focus_spell.base2[i]) {
|
||||||
else if (focus_spell.base2[i] == 0 || focus_spell.base[i] == focus_spell.base2[i]) {
|
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]);
|
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4935,15 +4866,12 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (best_focus) {
|
if (best_focus) {
|
||||||
if (focus_spell.base2[i] != 0) {
|
if (focus_spell.base2[i] != 0) {
|
||||||
value = focus_spell.base2[i];
|
value = focus_spell.base2[i];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
}
|
||||||
}
|
} else if (focus_spell.base2[i] == 0 || focus_spell.base[i] == focus_spell.base2[i]) {
|
||||||
else if (focus_spell.base2[i] == 0 || focus_spell.base[i] == focus_spell.base2[i]) {
|
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]);
|
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4995,13 +4923,11 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
if (focus_spell.base[i] > value)
|
if (focus_spell.base[i] > value)
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
if (focus_spell.base[i] < value)
|
if (focus_spell.base[i] < value)
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -5122,10 +5048,10 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
// this spits up a lot of garbage when calculating spell focuses
|
// this spits up a lot of garbage when calculating spell focuses
|
||||||
// since they have all kinds of extra effects on them.
|
// since they have all kinds of extra effects on them.
|
||||||
default:
|
default:
|
||||||
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown effectid %d",
|
||||||
|
focus_spell.effectid[i]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int e = 0; e < MaxLimitInclude; e += 2) {
|
for (int e = 0; e < MaxLimitInclude; e += 2) {
|
||||||
@ -5227,31 +5153,31 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
/*Note: At present, ff designing custom AA to have a sympathetic proc effect, only use one focus
|
/*Note: At present, ff designing custom AA to have a sympathetic proc effect, only use one focus
|
||||||
effect within the aa_effects data for each AA*[No live AA's use this effect to my knowledge]*/
|
effect within the aa_effects data for each AA*[No live AA's use this effect to my knowledge]*/
|
||||||
if (aabonuses.FocusEffects[type]) {
|
if (aabonuses.FocusEffects[type]) {
|
||||||
|
for (const auto &aa : aa_ranks) {
|
||||||
uint32 aa_AA = 0;
|
|
||||||
uint32 aa_value = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_PP_AA_ARRAY; i++)
|
|
||||||
{
|
|
||||||
aa_AA = this->aa[i]->AA;
|
|
||||||
aa_value = this->aa[i]->value;
|
|
||||||
if (aa_AA < 1 || aa_value < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS)
|
if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa.first, aa.second.first);
|
||||||
|
auto ability = ability_rank.first;
|
||||||
|
auto rank = ability_rank.second;
|
||||||
|
|
||||||
|
if(!ability) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rank->effects.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
proc_spellid = CalcAAFocus(type, aa_AA, spell_id);
|
proc_spellid = CalcAAFocus(type, *rank, spell_id);
|
||||||
|
|
||||||
if (IsValidSpell(proc_spellid)) {
|
if (IsValidSpell(proc_spellid)) {
|
||||||
ProcChance = GetSympatheticProcChances(spell_id, GetAABase1(aa_AA, 1));
|
ProcChance = GetSympatheticProcChances(spell_id, rank->effects[0].base1);
|
||||||
if (zone->random.Roll(ProcChance))
|
if (zone->random.Roll(ProcChance))
|
||||||
SympatheticProcList.push_back(proc_spellid);
|
SympatheticProcList.push_back(proc_spellid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SympatheticProcList.size() > 0)
|
if (!SympatheticProcList.empty())
|
||||||
{
|
{
|
||||||
uint8 random = zone->random.Int(0, SympatheticProcList.size()-1);
|
uint8 random = zone->random.Int(0, SympatheticProcList.size()-1);
|
||||||
int FinalSympatheticProc = SympatheticProcList[random];
|
int FinalSympatheticProc = SympatheticProcList[random];
|
||||||
@ -5262,9 +5188,9 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
|
int16 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||||
|
{
|
||||||
if (IsBardSong(spell_id) && type != focusFcBaseEffects)
|
if (IsBardSong(spell_id) && type != focusFcBaseEffects && type != focusSpellDuration)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int16 realTotal = 0;
|
int16 realTotal = 0;
|
||||||
@ -5499,18 +5425,20 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
if (aabonuses.FocusEffects[type]){
|
if (aabonuses.FocusEffects[type]){
|
||||||
|
|
||||||
int16 Total3 = 0;
|
int16 Total3 = 0;
|
||||||
uint32 slots = 0;
|
|
||||||
uint32 aa_AA = 0;
|
|
||||||
uint32 aa_value = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_PP_AA_ARRAY; i++)
|
for (const auto &aa : aa_ranks) {
|
||||||
{
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa.first, aa.second.first);
|
||||||
aa_AA = this->aa[i]->AA;
|
auto ability = ability_rank.first;
|
||||||
aa_value = this->aa[i]->value;
|
auto rank = ability_rank.second;
|
||||||
if (aa_AA < 1 || aa_value < 1)
|
|
||||||
|
if(!ability) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rank->effects.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Total3 = CalcAAFocus(type, aa_AA, spell_id);
|
Total3 = CalcAAFocus(type, *rank, spell_id);
|
||||||
if (Total3 > 0 && realTotal3 >= 0 && Total3 > realTotal3) {
|
if (Total3 > 0 && realTotal3 >= 0 && Total3 > realTotal3) {
|
||||||
realTotal3 = Total3;
|
realTotal3 = Total3;
|
||||||
}
|
}
|
||||||
@ -5520,9 +5448,6 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == focusReagentCost && IsSummonPetSpell(spell_id) && GetAA(aaElementalPact))
|
|
||||||
return 100;
|
|
||||||
|
|
||||||
if(type == focusReagentCost && (IsEffectInSpell(spell_id, SE_SummonItem) || IsSacrificeSpell(spell_id)))
|
if(type == focusReagentCost && (IsEffectInSpell(spell_id, SE_SummonItem) || IsSacrificeSpell(spell_id)))
|
||||||
return 0;
|
return 0;
|
||||||
//Summon Spells that require reagents are typically imbue type spells, enchant metal, sacrifice and shouldn't be affected
|
//Summon Spells that require reagents are typically imbue type spells, enchant metal, sacrifice and shouldn't be affected
|
||||||
|
|||||||
@ -146,7 +146,8 @@ void NPC::SpellProcess()
|
|||||||
// to allow procs to work
|
// to allow procs to work
|
||||||
bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||||
int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_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",
|
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);
|
(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)
|
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
|
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,
|
bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||||
int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish,
|
int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish,
|
||||||
uint32 item_slot, uint32 timer, uint32 timer_duration, uint32 type,
|
uint32 item_slot, uint32 timer, uint32 timer_duration,
|
||||||
int16 resist_adjust)
|
int16 resist_adjust, uint32 aa_id)
|
||||||
{
|
{
|
||||||
Mob* pMob = nullptr;
|
Mob* pMob = nullptr;
|
||||||
int32 orgcasttime;
|
int32 orgcasttime;
|
||||||
@ -361,7 +362,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
|||||||
casting_spell_timer = timer;
|
casting_spell_timer = timer;
|
||||||
casting_spell_timer_duration = timer_duration;
|
casting_spell_timer_duration = timer_duration;
|
||||||
}
|
}
|
||||||
casting_spell_type = type;
|
casting_spell_aa_id = aa_id;
|
||||||
|
|
||||||
SaveSpellLoc();
|
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);
|
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
|
// ok now we know the target
|
||||||
casting_spell_targetid = target_id;
|
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 = 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
|
// 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
|
// If you're at full mana, let it cast even if you dont have enough mana
|
||||||
|
|
||||||
// we calculated this above, now enforce it
|
// 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_curmana = GetMana();
|
||||||
int my_maxmana = GetMaxMana();
|
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...
|
//this is a special case for NPCs with no mana...
|
||||||
if(IsNPC() && my_curmana == my_maxmana)
|
if(IsNPC() && my_curmana == my_maxmana)
|
||||||
@ -783,9 +779,9 @@ void Mob::ZeroCastingVars()
|
|||||||
casting_spell_inventory_slot = 0;
|
casting_spell_inventory_slot = 0;
|
||||||
casting_spell_timer = 0;
|
casting_spell_timer = 0;
|
||||||
casting_spell_timer_duration = 0;
|
casting_spell_timer_duration = 0;
|
||||||
casting_spell_type = 0;
|
|
||||||
casting_spell_resist_adjust = 0;
|
casting_spell_resist_adjust = 0;
|
||||||
casting_spell_checks = false;
|
casting_spell_checks = false;
|
||||||
|
casting_spell_aa_id = 0;
|
||||||
delaytimer = false;
|
delaytimer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -816,10 +812,9 @@ void Mob::InterruptSpell(uint16 message, uint16 color, uint16 spellid)
|
|||||||
CastToNPC()->AI_Event_SpellCastFinished(false, casting_spell_slot);
|
CastToNPC()->AI_Event_SpellCastFinished(false, casting_spell_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(casting_spell_type == 1 && IsClient()) { //Rest AA Timer on failed cast
|
if(casting_spell_aa_id && IsClient()) { //Rest AA Timer on failed cast
|
||||||
CastToClient()->SendAATimer(casting_spell_timer - pTimerAAStart, 0, 0xFFFFFF);
|
CastToClient()->Message_StringID(MT_SpellFailure, ABILITY_FAILED);
|
||||||
CastToClient()->Message_StringID(15,ABILITY_FAILED);
|
CastToClient()->ResetAlternateAdvancementTimer(casting_spell_aa_id);
|
||||||
CastToClient()->GetPTimers().Clear(&database, casting_spell_timer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroCastingVars(); // resets all the state keeping stuff
|
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)) {
|
else if(!SpellOnTarget(spell_id, spell_target, false, true, resist_adjust, false, level_override)) {
|
||||||
if(IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) {
|
if(IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) {
|
||||||
// Prevent mana usage/timers being set for beneficial buffs
|
// Prevent mana usage/timers being set for beneficial buffs
|
||||||
if(casting_spell_type == 1)
|
if(casting_spell_aa_id)
|
||||||
InterruptSpell();
|
InterruptSpell();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2157,11 +2152,11 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
|||||||
}
|
}
|
||||||
#endif //BOTS
|
#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())
|
if(spells[spell_id].can_mgb && HasMGB())
|
||||||
{
|
{
|
||||||
SpellOnTarget(spell_id, this);
|
SpellOnTarget(spell_id, this);
|
||||||
entity_list.MassGroupBuff(this, this, spell_id, true);
|
entity_list.MassGroupBuff(this, this, spell_id, true);
|
||||||
SetMGB(false);
|
|
||||||
}
|
}
|
||||||
else
|
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
|
// 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)
|
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);
|
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);
|
SetMana(GetMana() - mana_used);
|
||||||
TryTriggerOnValueAmount(false, true);
|
TryTriggerOnValueAmount(false, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//set our reuse timer on long ass reuse_time spells...
|
//set our reuse timer on long ass reuse_time spells...
|
||||||
if(IsClient() && !isproc)
|
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);
|
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);
|
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
|
// if SpellEffect returned false there's a problem applying the
|
||||||
// spell. It's most likely a buff that can't stack.
|
// 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());
|
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);
|
Message_StringID(MT_SpellFailure, SPELL_NO_HOLD);
|
||||||
safe_delete(action_packet);
|
safe_delete(action_packet);
|
||||||
return false;
|
return false;
|
||||||
@ -4116,8 +4127,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (CheckAATimer(aaTimerWarcry))
|
||||||
else if (IsClient() && CastToClient()->CheckAAEffect(aaEffectWarcry))
|
|
||||||
{
|
{
|
||||||
Message(13, "Your are immune to fear.");
|
Message(13, "Your are immune to fear.");
|
||||||
Log.Out(Logs::Detail, Logs::Spells, "Clients has WarCry effect, 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))
|
if((Title->Class >= 0) && (c->GetBaseClass() != Title->Class))
|
||||||
return false;
|
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;
|
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;
|
return false;
|
||||||
|
|
||||||
if(Title->SkillID >= 0)
|
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);
|
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
|
//fix up pathing Z
|
||||||
if(zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints))
|
if(zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints) && !IsBoat())
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!RuleB(Watermap, CheckForWaterAtWaypoints) || !zone->HasWaterMap() ||
|
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;
|
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) {
|
if(tar_ndx < compare_steps && m_TargetLocation.x==x && m_TargetLocation.y==y) {
|
||||||
|
|
||||||
float new_x = m_Position.x + m_TargetV.x*tar_vector;
|
float new_x = m_Position.x + m_TargetV.x*tar_vector;
|
||||||
|
|||||||
@ -68,7 +68,6 @@ extern bool staticzone;
|
|||||||
extern NetConnection net;
|
extern NetConnection net;
|
||||||
extern PetitionList petition_list;
|
extern PetitionList petition_list;
|
||||||
extern QuestParserCollection* parse;
|
extern QuestParserCollection* parse;
|
||||||
extern uint16 adverrornum;
|
|
||||||
extern uint32 numclients;
|
extern uint32 numclients;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
@ -805,8 +804,6 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
|||||||
weather_intensity = 0;
|
weather_intensity = 0;
|
||||||
blocked_spells = nullptr;
|
blocked_spells = nullptr;
|
||||||
totalBS = 0;
|
totalBS = 0;
|
||||||
aas = nullptr;
|
|
||||||
totalAAs = 0;
|
|
||||||
zone_has_current_time = false;
|
zone_has_current_time = false;
|
||||||
|
|
||||||
Instance_Shutdown_Timer = nullptr;
|
Instance_Shutdown_Timer = nullptr;
|
||||||
@ -865,16 +862,6 @@ Zone::~Zone() {
|
|||||||
safe_delete(qGlobals);
|
safe_delete(qGlobals);
|
||||||
safe_delete_array(adv_data);
|
safe_delete_array(adv_data);
|
||||||
safe_delete_array(map_name);
|
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);
|
safe_delete(GuildBanks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,16 +940,12 @@ bool Zone::Init(bool iStaticZone) {
|
|||||||
zone->LoadAlternateCurrencies();
|
zone->LoadAlternateCurrencies();
|
||||||
zone->LoadNPCEmotes(&NPCEmoteList);
|
zone->LoadNPCEmotes(&NPCEmoteList);
|
||||||
|
|
||||||
//Load AA information
|
LoadAlternateAdvancement();
|
||||||
adverrornum = 500;
|
|
||||||
LoadAAs();
|
|
||||||
|
|
||||||
//Load merchant data
|
//Load merchant data
|
||||||
adverrornum = 501;
|
|
||||||
zone->GetMerchantDataForZoneLoad();
|
zone->GetMerchantDataForZoneLoad();
|
||||||
|
|
||||||
//Load temporary merchant data
|
//Load temporary merchant data
|
||||||
adverrornum = 502;
|
|
||||||
zone->LoadTempMerchantData();
|
zone->LoadTempMerchantData();
|
||||||
|
|
||||||
// Merc data
|
// Merc data
|
||||||
@ -974,7 +957,6 @@ bool Zone::Init(bool iStaticZone) {
|
|||||||
if (RuleB(Zone, LevelBasedEXPMods))
|
if (RuleB(Zone, LevelBasedEXPMods))
|
||||||
zone->LoadLevelEXPMods();
|
zone->LoadLevelEXPMods();
|
||||||
|
|
||||||
adverrornum = 503;
|
|
||||||
petition_list.ClearPetitions();
|
petition_list.ClearPetitions();
|
||||||
petition_list.ReadDatabase();
|
petition_list.ReadDatabase();
|
||||||
|
|
||||||
|
|||||||
20
zone/zone.h
20
zone/zone.h
@ -27,6 +27,7 @@
|
|||||||
#include "qglobals.h"
|
#include "qglobals.h"
|
||||||
#include "spawn2.h"
|
#include "spawn2.h"
|
||||||
#include "spawngroup.h"
|
#include "spawngroup.h"
|
||||||
|
#include "aa_ability.h"
|
||||||
|
|
||||||
struct ZonePoint
|
struct ZonePoint
|
||||||
{
|
{
|
||||||
@ -113,11 +114,13 @@ public:
|
|||||||
|
|
||||||
inline const uint32& GetMaxClients() { return pMaxClients; }
|
inline const uint32& GetMaxClients() { return pMaxClients; }
|
||||||
|
|
||||||
void LoadAAs();
|
//new AA
|
||||||
int GetTotalAAs() { return totalAAs; }
|
void LoadAlternateAdvancement();
|
||||||
SendAA_Struct* GetAABySequence(uint32 seq) { return aas[seq]; }
|
AA::Ability *GetAlternateAdvancementAbility(int id);
|
||||||
SendAA_Struct* FindAA(uint32 id);
|
AA::Ability *GetAlternateAdvancementAbilityByRank(int rank_id);
|
||||||
uint8 GetTotalAALevels(uint32 skill_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);
|
void LoadZoneDoors(const char* zone, int16 version);
|
||||||
bool LoadZoneObjects();
|
bool LoadZoneObjects();
|
||||||
bool LoadGroundSpawns();
|
bool LoadGroundSpawns();
|
||||||
@ -193,6 +196,10 @@ public:
|
|||||||
char *adv_data;
|
char *adv_data;
|
||||||
bool did_adventure_actions;
|
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 DoAdventureCountIncrease();
|
||||||
void DoAdventureAssassinationCountIncrease();
|
void DoAdventureAssassinationCountIncrease();
|
||||||
void DoAdventureActions();
|
void DoAdventureActions();
|
||||||
@ -313,9 +320,6 @@ private:
|
|||||||
int totalBS;
|
int totalBS;
|
||||||
ZoneSpellsBlocked *blocked_spells;
|
ZoneSpellsBlocked *blocked_spells;
|
||||||
|
|
||||||
int totalAAs;
|
|
||||||
SendAA_Struct **aas; //array of AA structs
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Spawn related things
|
Spawn related things
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "../common/faction.h"
|
#include "../common/faction.h"
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
|
#include "aa_ability.h"
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
class Corpse;
|
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 SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list); // needed for factions Dec, 16 2001
|
||||||
bool LoadFactionData();
|
bool LoadFactionData();
|
||||||
|
|
||||||
/* AAs */
|
/* AAs New */
|
||||||
bool LoadAAEffects();
|
bool LoadAlternateAdvancementAbilities(std::unordered_map<int, std::unique_ptr<AA::Ability>> &abilities,
|
||||||
bool LoadAAEffects2();
|
std::unordered_map<int, std::unique_ptr<AA::Rank>> &ranks);
|
||||||
bool LoadSwarmSpells();
|
bool LoadAlternateAdvancement(Client *c);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Zone related */
|
/* 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);
|
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