mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
Merge from master
This commit is contained in:
commit
9f1f36cca6
@ -1,5 +1,46 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 07/06/2015 ==
|
||||||
|
mackal: Implement Triple Attack Skill
|
||||||
|
Parses showed about rand(1000) for the chance, may need more investigating
|
||||||
|
Corrected Double Attack chances as well
|
||||||
|
Running optional 2015_07_06_TripleAttack.sql will set current toons to their max skill
|
||||||
|
This is optional because the admins might want to go a different route.
|
||||||
|
|
||||||
|
== 07/05/2015 ==
|
||||||
|
mackal: Rewrite NPC combat attack round logic
|
||||||
|
An NPC "quading" is really just an NPC with innate dual wield that doubles on both hands
|
||||||
|
The old rules allowed NPCs to hit 6 times in one round
|
||||||
|
NPCs also seem to have their own skill progression for DW/DA
|
||||||
|
See: http://www.eqemulator.org/forums/showthread.php?t=38708
|
||||||
|
You can set Combat:UseLiveCombatRounds to false to use the old rules
|
||||||
|
PC Double Attack rates kind of follow the same thing but still needs to be implemented
|
||||||
|
Kinglykrab: WARNING: summonburriedplayercorpse is now summonburiedplayercorpse, getplayerburriedcorpsecount is now getplayerburiedcorpsecount, summon_burried_player_corpse is now summon_buried_player_corpse, and get_player_burried_corpse_count is now get_player_buried_corpse_count FIX THESE IN YOUR SCRIPTS OR THEY WILL NOT WORK!!!!
|
||||||
|
Added bot saylinks (thanks Uleat!)
|
||||||
|
Command aliases for #augmentitem (#aug), #findnpctype (#fn), #findspell (#fs)
|
||||||
|
Bot command changes: #bot sow -> #bot speed, #bot magepet -> #bot setpet, #bot resurrectme -> #bot resurrect
|
||||||
|
Changed all occurrences of burried to buried in the code.
|
||||||
|
client_packet.cpp was referencing old columns in character_corpses, not sure how we didn't already see this before.
|
||||||
|
|
||||||
|
== 7/4/2015 ==
|
||||||
|
mackal: Reworked the activated avoidace skills (riposte, dodge, etc) based on dev quotes
|
||||||
|
This also fixes the order things are checked (avoidance skills, THEN hit/miss)
|
||||||
|
Also riposte immunity from the increase riposte chance spell effect.
|
||||||
|
|
||||||
|
== 7/2/2015 ==
|
||||||
|
KLS/Demonstar55: AA system has been rewritten fixing a ton of bugs and extending functionality while making it easier to create new AA points.
|
||||||
|
KLS/Demonstar55: New tables are needed and so older data will need to be migrated to the new system.
|
||||||
|
KLS/Demonstar55: The SQL saves the old aa points spent/avail/character_alt_abilities data if any server ops want to do something different than PEQ did with it.
|
||||||
|
KLS/Demonstar55: Will try to get a wiki entry written up next week some time explaining the system but it's really not hard to follow the db tables in the meantime.
|
||||||
|
|
||||||
|
== 7/1/2015 ==
|
||||||
|
Akkadius: Fix an issue where emote messages would overflow the buffer of 256 by increasing the size and changing some of the initialization
|
||||||
|
Akkadius: Added a custom Health Update message that will display in the middle of the players screen, to enable this server wide you must enable rule 'Character:MarqueeHPUpdates'
|
||||||
|
Example: https://www.youtube.com/watch?v=KUVdbPxLIn0
|
||||||
|
Akkadius: (Haynar) Fixed some runspeed issues with Perl and LUA scripts
|
||||||
|
Akkadius: (Haynar) Updated #showstats and #npcstats for new speed calcs to display speeds again in familiar float format.
|
||||||
|
Akkadius: (Haynar) Improved client movement while AI Controlled, such as feared and charmed. Movement will be much smoother from clients perspective.
|
||||||
|
|
||||||
== 06/12/2015 ==
|
== 06/12/2015 ==
|
||||||
Uleat: Adjusted SessionStats to better reflect a sister implementation
|
Uleat: Adjusted SessionStats to better reflect a sister implementation
|
||||||
|
|
||||||
|
|||||||
@ -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 */
|
||||||
|
|||||||
@ -1384,7 +1384,7 @@ bool Database::MoveCharacterToZone(const char* charname, const char* zonename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) {
|
bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) {
|
||||||
std::string query = StringFormat("UPDATE `character_data` SET `zone_id` = %i, `x` = -1, `y` = -1, `z` = -1 WHERE `id` = %i", iZonename, GetZoneID(iZonename), iCharID);
|
std::string query = StringFormat("UPDATE `character_data` SET `zone_id` = %i, `x` = -1, `y` = -1, `z` = -1 WHERE `id` = %i", GetZoneID(iZonename), iCharID);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
|
|||||||
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -867,7 +867,7 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
|
|||||||
//factored out so I dont have to copy this crap.
|
//factored out so I dont have to copy this crap.
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define GuildMemberBaseQuery \
|
#define GuildMemberBaseQuery \
|
||||||
"SELECT c.id,c.name,c.class,c.level,c.timelaston,c.zoneid," \
|
"SELECT c.id,c.name,c.class,c.level,c.last_login,c.zone_id," \
|
||||||
" g.guild_id,g.rank,g.tribute_enable,g.total_tribute,g.last_tribute," \
|
" g.guild_id,g.rank,g.tribute_enable,g.total_tribute,g.last_tribute," \
|
||||||
" g.banker,g.public_note,g.alt" \
|
" g.banker,g.public_note,g.alt" \
|
||||||
" FROM vwBotCharacterMobs AS c LEFT JOIN vwGuildMembers AS g ON c.id=g.char_id AND c.mobtype = g.mobtype "
|
" FROM vwBotCharacterMobs AS c LEFT JOIN vwGuildMembers AS g ON c.id=g.char_id AND c.mobtype = g.mobtype "
|
||||||
|
|||||||
@ -146,6 +146,7 @@ INr(OP_GuildDelete); //?
|
|||||||
IN(OP_GuildPublicNote, GuildUpdate_PublicNote);
|
IN(OP_GuildPublicNote, GuildUpdate_PublicNote);
|
||||||
INz(OP_GetGuildsList); //?
|
INz(OP_GetGuildsList); //?
|
||||||
IN(OP_SetGuildMOTD, GuildMOTD_Struct);
|
IN(OP_SetGuildMOTD, GuildMOTD_Struct);
|
||||||
|
IN(OP_SetRunMode, SetRunMode_Struct);
|
||||||
INz(OP_GuildPeace); //?
|
INz(OP_GuildPeace); //?
|
||||||
INz(OP_GuildWar); //?
|
INz(OP_GuildWar); //?
|
||||||
IN(OP_GuildLeader, GuildMakeLeader);
|
IN(OP_GuildLeader, GuildMakeLeader);
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
// the structs::SendAA_Struct includes enough space for 1 prereq which is the min even if it has no prereqs
|
||||||
|
auto prereq_size = emu->total_prereqs > 1 ? (emu->total_prereqs - 1) * 8 : 0;
|
||||||
|
auto outapp = new EQApplicationPacket(OP_SendAATable, sizeof(structs::SendAA_Struct) + emu->total_effects * sizeof(structs::AA_Ability) + prereq_size);
|
||||||
|
inapp->SetReadPosition(sizeof(AARankInfo_Struct)+emu->total_effects * sizeof(AARankEffect_Struct));
|
||||||
|
|
||||||
|
|
||||||
// Check clientver field to verify this AA should be sent for SoF
|
std::vector<int32> skill;
|
||||||
// clientver 1 is for all clients and 5 is for Live
|
std::vector<int32> points;
|
||||||
if (emu->clientver <= 8)
|
for(auto i = 0; i < emu->total_prereqs; ++i) {
|
||||||
{
|
skill.push_back(inapp->ReadUInt32());
|
||||||
OUT(id);
|
points.push_back(inapp->ReadUInt32());
|
||||||
eq->unknown004 = 1;
|
|
||||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
|
||||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? -1 : (emu->sof_next_skill);
|
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? -1 : (emu->sof_next_skill);
|
|
||||||
eq->title_sid = emu->sof_next_skill;
|
|
||||||
eq->desc_sid = emu->sof_next_skill;
|
|
||||||
OUT(class_type);
|
|
||||||
OUT(cost);
|
|
||||||
OUT(seq);
|
|
||||||
OUT(current_level);
|
|
||||||
eq->prereq_skill_count = 1; // min 1
|
|
||||||
OUT(prereq_skill);
|
|
||||||
eq->prereq_minpoints_count = 1; // min 1
|
|
||||||
OUT(prereq_minpoints);
|
|
||||||
eq->type = emu->sof_type;
|
|
||||||
OUT(spellid);
|
|
||||||
eq->unknown057 = 1; // Introduced during HoT
|
|
||||||
OUT(spell_type);
|
|
||||||
OUT(spell_refresh);
|
|
||||||
OUT(classes);
|
|
||||||
OUT(berserker);
|
|
||||||
//eq->max_level = emu->sof_max_level;
|
|
||||||
OUT(max_level);
|
|
||||||
OUT(last_id);
|
|
||||||
OUT(next_id);
|
|
||||||
OUT(cost2);
|
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
|
||||||
eq->special_category = emu->special_category;
|
|
||||||
OUT(total_abilities);
|
|
||||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
|
||||||
unsigned int r;
|
|
||||||
for (r = 0; r < emu->total_abilities; r++) {
|
|
||||||
OUT(abilities[r].skill_id);
|
|
||||||
OUT(abilities[r].base1);
|
|
||||||
OUT(abilities[r].base2);
|
|
||||||
OUT(abilities[r].slot);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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->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->unknown004 = 1;
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
eq->id = emu->id;
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->desc_sid = emu->desc_sid;
|
||||||
eq->title_sid = emu->sof_next_skill;
|
eq->title_sid = emu->title_sid;
|
||||||
eq->desc_sid = emu->sof_next_skill;
|
eq->class_type = emu->level_req;
|
||||||
OUT(class_type);
|
eq->cost = emu->cost;
|
||||||
OUT(cost);
|
eq->seq = emu->seq;
|
||||||
OUT(seq);
|
eq->current_level = emu->current_level;
|
||||||
OUT(current_level);
|
eq->type = emu->type;
|
||||||
OUT(prereq_skill);
|
eq->spellid = emu->spell;
|
||||||
OUT(prereq_minpoints);
|
eq->spell_type = emu->spell_type;
|
||||||
eq->type = emu->sof_type;
|
eq->spell_refresh = emu->spell_refresh;
|
||||||
OUT(spellid);
|
eq->classes = emu->classes;
|
||||||
OUT(spell_type);
|
eq->max_level = emu->max_level;
|
||||||
OUT(spell_refresh);
|
eq->last_id = emu->prev_id;
|
||||||
OUT(classes);
|
eq->next_id = emu->next_id;
|
||||||
OUT(berserker);
|
eq->cost2 = emu->total_cost;
|
||||||
//eq->max_level = emu->sof_max_level;
|
eq->grant_only = emu->grant_only;
|
||||||
OUT(max_level);
|
eq->expendable_charges = emu->charges;
|
||||||
OUT(last_id);
|
eq->aa_expansion = emu->expansion;
|
||||||
OUT(next_id);
|
eq->special_category = emu->category;
|
||||||
OUT(cost2);
|
eq->total_abilities = emu->total_effects;
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
|
||||||
eq->special_category = emu->special_category;
|
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
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)
|
||||||
|
|||||||
@ -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->id = emu->id;
|
||||||
//eq->hotkey_sid = (emu->hotkey_sid==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||||
//eq->hotkey_sid2 = (emu->hotkey_sid2==4294967295UL)?0:(emu->id - emu->current_level + 1);
|
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
eq->desc_sid = emu->desc_sid;
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
eq->title_sid = emu->title_sid;
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->class_type = emu->level_req;
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->cost = emu->cost;
|
||||||
eq->title_sid = emu->sof_next_skill;
|
eq->seq = emu->seq;
|
||||||
eq->desc_sid = emu->sof_next_skill;
|
eq->current_level = emu->current_level;
|
||||||
OUT(class_type);
|
eq->type = emu->type;
|
||||||
OUT(cost);
|
eq->spellid = emu->spell;
|
||||||
OUT(seq);
|
eq->spell_type = emu->spell_type;
|
||||||
OUT(current_level);
|
eq->spell_refresh = emu->spell_refresh;
|
||||||
OUT(prereq_skill);
|
eq->classes = emu->classes;
|
||||||
OUT(prereq_minpoints);
|
eq->max_level = emu->max_level;
|
||||||
eq->type = emu->sof_type;
|
eq->last_id = emu->prev_id;
|
||||||
OUT(spellid);
|
eq->next_id = emu->next_id;
|
||||||
OUT(spell_type);
|
eq->cost2 = emu->total_cost;
|
||||||
OUT(spell_refresh);
|
eq->grant_only = emu->grant_only;
|
||||||
OUT(classes);
|
eq->expendable_charges = emu->charges;
|
||||||
OUT(berserker);
|
eq->aa_expansion = emu->expansion;
|
||||||
//eq->max_level = emu->sof_max_level;
|
eq->special_category = emu->category;
|
||||||
OUT(max_level);
|
eq->total_abilities = emu->total_effects;
|
||||||
OUT(last_id);
|
|
||||||
OUT(next_id);
|
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||||
OUT(cost2);
|
eq->abilities[i].skill_id = inapp->ReadUInt32();
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->abilities[i].base1 = inapp->ReadUInt32();
|
||||||
eq->special_category = emu->special_category;
|
eq->abilities[i].base2 = inapp->ReadUInt32();
|
||||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
eq->abilities[i].slot = inapp->ReadUInt32();
|
||||||
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();
|
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->id = emu->id;
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->id - emu->current_level + 1);
|
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->id - emu->current_level + 1);
|
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||||
eq->title_sid = emu->id - emu->current_level + 1;
|
eq->desc_sid = emu->desc_sid;
|
||||||
eq->desc_sid = emu->id - emu->current_level + 1;
|
eq->title_sid = emu->title_sid;
|
||||||
OUT(class_type);
|
eq->class_type = emu->level_req;
|
||||||
OUT(cost);
|
eq->cost = emu->cost;
|
||||||
OUT(seq);
|
eq->seq = emu->seq;
|
||||||
OUT(current_level);
|
eq->current_level = emu->current_level;
|
||||||
OUT(prereq_skill);
|
eq->type = emu->type;
|
||||||
OUT(prereq_minpoints);
|
eq->spellid = emu->spell;
|
||||||
OUT(type);
|
eq->spell_type = emu->spell_type;
|
||||||
OUT(spellid);
|
eq->spell_refresh = emu->spell_refresh;
|
||||||
OUT(spell_type);
|
eq->classes = emu->classes;
|
||||||
OUT(spell_refresh);
|
eq->max_level = emu->max_level;
|
||||||
OUT(classes);
|
eq->last_id = emu->prev_id;
|
||||||
OUT(berserker);
|
eq->next_id = emu->next_id;
|
||||||
OUT(max_level);
|
eq->cost2 = emu->total_cost;
|
||||||
OUT(last_id);
|
eq->total_abilities = emu->total_effects;
|
||||||
OUT(next_id);
|
|
||||||
OUT(cost2);
|
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||||
OUT(unknown80[0]);
|
eq->abilities[i].skill_id = inapp->ReadUInt32();
|
||||||
OUT(unknown80[1]);
|
eq->abilities[i].base1 = inapp->ReadUInt32();
|
||||||
OUT(total_abilities);
|
eq->abilities[i].base2 = inapp->ReadUInt32();
|
||||||
unsigned int r;
|
eq->abilities[i].slot = inapp->ReadUInt32();
|
||||||
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)
|
||||||
|
|||||||
@ -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->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->unknown004 = 1;
|
||||||
//eq->title_sid = emu->id - emu->current_level + 1;
|
eq->id = emu->id;
|
||||||
//eq->desc_sid = emu->id - emu->current_level + 1;
|
eq->hotkey_sid = emu->upper_hotkey_sid;
|
||||||
eq->hotkey_sid = (emu->hotkey_sid == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->hotkey_sid2 = emu->lower_hotkey_sid;
|
||||||
eq->hotkey_sid2 = (emu->hotkey_sid2 == 4294967295UL) ? 0 : (emu->sof_next_skill);
|
eq->desc_sid = emu->desc_sid;
|
||||||
eq->title_sid = emu->sof_next_skill;
|
eq->title_sid = emu->title_sid;
|
||||||
eq->desc_sid = emu->sof_next_skill;
|
eq->class_type = emu->level_req;
|
||||||
OUT(class_type);
|
eq->cost = emu->cost;
|
||||||
OUT(cost);
|
eq->seq = emu->seq;
|
||||||
OUT(seq);
|
eq->current_level = emu->current_level;
|
||||||
OUT(current_level);
|
eq->type = emu->type;
|
||||||
OUT(prereq_skill);
|
eq->spellid = emu->spell;
|
||||||
OUT(prereq_minpoints);
|
eq->spell_type = emu->spell_type;
|
||||||
eq->type = emu->sof_type;
|
eq->spell_refresh = emu->spell_refresh;
|
||||||
OUT(spellid);
|
eq->classes = emu->classes;
|
||||||
OUT(spell_type);
|
eq->max_level = emu->max_level;
|
||||||
OUT(spell_refresh);
|
eq->last_id = emu->prev_id;
|
||||||
OUT(classes);
|
eq->next_id = emu->next_id;
|
||||||
OUT(berserker);
|
eq->cost2 = emu->total_cost;
|
||||||
//eq->max_level = emu->sof_max_level;
|
eq->grant_only = emu->grant_only;
|
||||||
OUT(max_level);
|
eq->expendable_charges = emu->charges;
|
||||||
OUT(last_id);
|
eq->aa_expansion = emu->expansion;
|
||||||
OUT(next_id);
|
eq->special_category = emu->category;
|
||||||
OUT(cost2);
|
eq->total_abilities = emu->total_effects;
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
|
||||||
eq->special_category = emu->special_category;
|
for(auto i = 0; i < eq->total_abilities; ++i) {
|
||||||
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
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)
|
||||||
|
|||||||
@ -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)
|
||||||
@ -113,6 +114,8 @@ RULE_INT(Character, TradeskillUpMakePoison, 2) // Make Poison skillup rate adjus
|
|||||||
RULE_INT(Character, TradeskillUpPottery, 4) // Pottery skillup rate adjust. Lower is faster.
|
RULE_INT(Character, TradeskillUpPottery, 4) // Pottery skillup rate adjust. Lower is faster.
|
||||||
RULE_INT(Character, TradeskillUpResearch, 1) // Research skillup rate adjust. Lower is faster.
|
RULE_INT(Character, TradeskillUpResearch, 1) // Research skillup rate adjust. Lower is faster.
|
||||||
RULE_INT(Character, TradeskillUpTinkering, 2) // Tinkering skillup rate adjust. Lower is faster.
|
RULE_INT(Character, TradeskillUpTinkering, 2) // Tinkering skillup rate adjust. Lower is faster.
|
||||||
|
RULE_BOOL(Character, SpamHPUpdates, false) // if your server has stupid amounts of HP that causes client display issues, turn this on!
|
||||||
|
RULE_BOOL(Character, MarqueeHPUpdates, false) // Will show Health % in center of screen < 100%
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Mercs)
|
RULE_CATEGORY(Mercs)
|
||||||
@ -183,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.
|
||||||
@ -444,6 +448,7 @@ RULE_BOOL(Combat, OneProcPerWeapon, true) //If enabled, One proc per weapon per
|
|||||||
RULE_BOOL(Combat, ProjectileDmgOnImpact, true) //If enabled, projectiles (ie arrows) will hit on impact, instead of instantly.
|
RULE_BOOL(Combat, ProjectileDmgOnImpact, true) //If enabled, projectiles (ie arrows) will hit on impact, instead of instantly.
|
||||||
RULE_BOOL(Combat, MeleePush, true) // enable melee push
|
RULE_BOOL(Combat, MeleePush, true) // enable melee push
|
||||||
RULE_INT(Combat, MeleePushChance, 50) // (NPCs) chance the target will be pushed. Made up, 100 actually isn't that bad
|
RULE_INT(Combat, MeleePushChance, 50) // (NPCs) chance the target will be pushed. Made up, 100 actually isn't that bad
|
||||||
|
RULE_BOOL(Combat, UseLiveCombatRounds, true) // turn this false if you don't want to worry about fixing up combat rounds for NPCs
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(NPC)
|
RULE_CATEGORY(NPC)
|
||||||
@ -501,6 +506,8 @@ RULE_INT(Bots, BotAAExpansion, 8) // Bots get AAs through this expansion
|
|||||||
RULE_BOOL(Bots, BotGroupXP, false) // Determines whether client gets xp for bots outside their group.
|
RULE_BOOL(Bots, BotGroupXP, false) // Determines whether client gets xp for bots outside their group.
|
||||||
RULE_BOOL(Bots, BotBardUseOutOfCombatSongs, true) // Determines whether bard bots use additional out of combat songs.
|
RULE_BOOL(Bots, BotBardUseOutOfCombatSongs, true) // Determines whether bard bots use additional out of combat songs.
|
||||||
RULE_BOOL(Bots, BotLevelsWithOwner, false) // Auto-updates spawned bots as owner levels/de-levels (false is original behavior)
|
RULE_BOOL(Bots, BotLevelsWithOwner, false) // Auto-updates spawned bots as owner levels/de-levels (false is original behavior)
|
||||||
|
RULE_BOOL(Bots, BotCharacterLevelEnabled, false) // Enables required level to spawn bots
|
||||||
|
RULE_INT(Bots, BotCharacterLevel, 0) // 0 as default (if level > this value you can spawn bots if BotCharacterLevelEnabled is true)
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -761,6 +761,7 @@ typedef enum {
|
|||||||
struct LauncherZoneRequest {
|
struct LauncherZoneRequest {
|
||||||
uint8 command;
|
uint8 command;
|
||||||
char short_name[33];
|
char short_name[33];
|
||||||
|
uint16 port;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LauncherZoneStatus {
|
struct LauncherZoneStatus {
|
||||||
|
|||||||
@ -1662,6 +1662,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]);
|
||||||
@ -1992,7 +1993,7 @@ const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
|
|||||||
|
|
||||||
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
|
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
|
||||||
std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
|
std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
memset(message, '\0', sizeof(InspectMessage_Struct));
|
memset(message, '\0', sizeof(InspectMessage_Struct));
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
@ -2002,7 +2003,7 @@ void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMes
|
|||||||
|
|
||||||
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) {
|
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) {
|
||||||
std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, EscapeString(message->text).c_str());
|
std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, EscapeString(message->text).c_str());
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) {
|
void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) {
|
||||||
|
|||||||
@ -108,16 +108,17 @@ enum SkillUseTypes
|
|||||||
/*13869*/ SkillBerserking,
|
/*13869*/ SkillBerserking,
|
||||||
/*13902*/ SkillTaunt,
|
/*13902*/ SkillTaunt,
|
||||||
/*05837*/ SkillFrenzy, // This appears to be the only listed one not grouped with the others
|
/*05837*/ SkillFrenzy, // This appears to be the only listed one not grouped with the others
|
||||||
/*00000*/ _EmuSkillCount // move to last position of active enumeration labels
|
|
||||||
|
|
||||||
// SoF+ specific skills
|
// SoF+ specific skills
|
||||||
// /*03670*/ SkillRemoveTraps,
|
/*03670*/ SkillRemoveTraps,
|
||||||
// /*13049*/ SkillTripleAttack,
|
/*13049*/ SkillTripleAttack,
|
||||||
|
|
||||||
// RoF2+ specific skills
|
// RoF2+ specific skills
|
||||||
// /*00789*/ Skill2HPiercing,
|
// /*00789*/ Skill2HPiercing,
|
||||||
// /*01216*/ SkillNone, // This needs to move down as new skills are added
|
// /*01216*/ SkillNone, // This needs to move down as new skills are added
|
||||||
|
|
||||||
|
/*00000*/ _EmuSkillCount // move to last position of active enumeration labels
|
||||||
|
|
||||||
// Skill Counts
|
// Skill Counts
|
||||||
// /*-----*/ _SkillCount_62 = 75, // use for Ti and earlier max skill checks
|
// /*-----*/ _SkillCount_62 = 75, // use for Ti and earlier max skill checks
|
||||||
// /*-----*/ _SkillCount_SoF = 77, // use for SoF thru RoF1 max skill checks
|
// /*-----*/ _SkillCount_SoF = 77, // use for SoF thru RoF1 max skill checks
|
||||||
@ -170,7 +171,7 @@ enum SkillUseTypes
|
|||||||
};
|
};
|
||||||
|
|
||||||
// temporary until it can be sorted out...
|
// temporary until it can be sorted out...
|
||||||
#define HIGHEST_SKILL SkillFrenzy
|
#define HIGHEST_SKILL SkillTripleAttack
|
||||||
// Spell Effects use this value to determine if an effect applies to all skills.
|
// Spell Effects use this value to determine if an effect applies to all skills.
|
||||||
#define ALL_SKILLS -1
|
#define ALL_SKILLS -1
|
||||||
|
|
||||||
|
|||||||
@ -447,7 +447,7 @@ bool IsTGBCompatibleSpell(uint16 spell_id)
|
|||||||
|
|
||||||
bool IsBardSong(uint16 spell_id)
|
bool IsBardSong(uint16 spell_id)
|
||||||
{
|
{
|
||||||
if (IsValidSpell(spell_id) && spells[spell_id].classes[BARD - 1] < 127 && !spells[spell_id].IsDisciplineBuff)
|
if (IsValidSpell(spell_id) && spells[spell_id].classes[BARD - 1] < 255 && !spells[spell_id].IsDisciplineBuff)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -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 9083
|
#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
|
||||||
|
|||||||
@ -102,8 +102,6 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Launcher, "Starting main loop...");
|
Log.Out(Logs::Detail, Logs::Launcher, "Starting main loop...");
|
||||||
|
|
||||||
// zones["test"] = new ZoneLaunch(&world, "./zone", "dynamic_1");
|
|
||||||
|
|
||||||
ProcLauncher *launch = ProcLauncher::get();
|
ProcLauncher *launch = ProcLauncher::get();
|
||||||
RunLoops = true;
|
RunLoops = true;
|
||||||
while(RunLoops) {
|
while(RunLoops) {
|
||||||
|
|||||||
@ -86,14 +86,13 @@ void WorldServer::Process() {
|
|||||||
}
|
}
|
||||||
const LauncherZoneRequest *lzr = (const LauncherZoneRequest *) pack->pBuffer;
|
const LauncherZoneRequest *lzr = (const LauncherZoneRequest *) pack->pBuffer;
|
||||||
|
|
||||||
|
|
||||||
switch(ZoneRequestCommands(lzr->command)) {
|
switch(ZoneRequestCommands(lzr->command)) {
|
||||||
case ZR_Start: {
|
case ZR_Start: {
|
||||||
if(m_zones.find(lzr->short_name) != m_zones.end()) {
|
if(m_zones.find(lzr->short_name) != m_zones.end()) {
|
||||||
Log.Out(Logs::Detail, Logs::Launcher, "World told us to start zone %s, but it is already running.", lzr->short_name);
|
Log.Out(Logs::Detail, Logs::Launcher, "World told us to start zone %s, but it is already running.", lzr->short_name);
|
||||||
} else {
|
} else {
|
||||||
Log.Out(Logs::Detail, Logs::Launcher, "World told us to start zone %s.", lzr->short_name);
|
Log.Out(Logs::Detail, Logs::Launcher, "World told us to start zone %s.", lzr->short_name);
|
||||||
ZoneLaunch *l = new ZoneLaunch(this, m_name, lzr->short_name, m_config);
|
ZoneLaunch *l = new ZoneLaunch(this, m_name, lzr->short_name, lzr->port, m_config);
|
||||||
m_zones[lzr->short_name] = l;
|
m_zones[lzr->short_name] = l;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -34,10 +34,11 @@ void ZoneLaunch::InitStartTimer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ZoneLaunch::ZoneLaunch(WorldServer *world, const char *launcher_name,
|
ZoneLaunch::ZoneLaunch(WorldServer *world, const char *launcher_name,
|
||||||
const char *zone_name, const EQEmuConfig *config)
|
const char *zone_name, uint16 port, const EQEmuConfig *config)
|
||||||
: m_state(StateStartPending),
|
: m_state(StateStartPending),
|
||||||
m_world(world),
|
m_world(world),
|
||||||
m_zone(zone_name),
|
m_zone(zone_name),
|
||||||
|
m_port(port),
|
||||||
m_launcherName(launcher_name),
|
m_launcherName(launcher_name),
|
||||||
m_config(config),
|
m_config(config),
|
||||||
m_timer(config->RestartWait),
|
m_timer(config->RestartWait),
|
||||||
@ -61,10 +62,14 @@ void ZoneLaunch::SendStatus() const {
|
|||||||
void ZoneLaunch::Start() {
|
void ZoneLaunch::Start() {
|
||||||
ProcLauncher::Spec *spec = new ProcLauncher::Spec();
|
ProcLauncher::Spec *spec = new ProcLauncher::Spec();
|
||||||
spec->program = m_config->ZoneExe;
|
spec->program = m_config->ZoneExe;
|
||||||
// if(m_zone.substr(0,7) == "dynamic")
|
|
||||||
// spec->args.push_back(".");
|
if(m_port) {
|
||||||
// else
|
std::string arg = m_zone + std::string(":") + std::to_string(m_port);
|
||||||
spec->args.push_back(m_zone);
|
spec->args.push_back(arg);
|
||||||
|
} else {
|
||||||
|
spec->args.push_back(m_zone);
|
||||||
|
}
|
||||||
|
|
||||||
spec->args.push_back(m_launcherName);
|
spec->args.push_back(m_launcherName);
|
||||||
spec->handler = this;
|
spec->handler = this;
|
||||||
spec->logFile = m_config->LogPrefix + m_zone + m_config->LogSuffix;
|
spec->logFile = m_config->LogPrefix + m_zone + m_config->LogSuffix;
|
||||||
|
|||||||
@ -28,7 +28,7 @@ class EQEmuConfig;
|
|||||||
class ZoneLaunch : protected ProcLauncher::EventHandler {
|
class ZoneLaunch : protected ProcLauncher::EventHandler {
|
||||||
public:
|
public:
|
||||||
ZoneLaunch(WorldServer *world, const char *launcher_name,
|
ZoneLaunch(WorldServer *world, const char *launcher_name,
|
||||||
const char *zone_name, const EQEmuConfig *config);
|
const char *zone_name, uint16 port, const EQEmuConfig *config);
|
||||||
virtual ~ZoneLaunch();
|
virtual ~ZoneLaunch();
|
||||||
|
|
||||||
void Stop(bool graceful = true);
|
void Stop(bool graceful = true);
|
||||||
@ -63,6 +63,7 @@ protected:
|
|||||||
const std::string m_zone;
|
const std::string m_zone;
|
||||||
const char *const m_launcherName;
|
const char *const m_launcherName;
|
||||||
const EQEmuConfig *const m_config;
|
const EQEmuConfig *const m_config;
|
||||||
|
const uint16 m_port;
|
||||||
|
|
||||||
Timer m_timer;
|
Timer m_timer;
|
||||||
ProcLauncher::ProcRef m_ref;
|
ProcLauncher::ProcRef m_ref;
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -337,6 +337,9 @@
|
|||||||
9081|2015_05_23_dbstr_us.sql|SHOW TABLES LIKE 'db_str'|empty|
|
9081|2015_05_23_dbstr_us.sql|SHOW TABLES LIKE 'db_str'|empty|
|
||||||
9082|2015_05_25_npc_types_texture_fields.sql|SHOW COLUMNS FROM `npc_types` LIKE 'armtexture'|empty|
|
9082|2015_05_25_npc_types_texture_fields.sql|SHOW COLUMNS FROM `npc_types` LIKE 'armtexture'|empty|
|
||||||
9083|2015_06_07_aa_update.sql|SHOW COLUMNS FROM `character_alternate_abilities` LIKE 'charges'|empty|
|
9083|2015_06_07_aa_update.sql|SHOW COLUMNS FROM `character_alternate_abilities` LIKE 'charges'|empty|
|
||||||
|
9084|2015_06_30_runspeed_adjustments.sql|SELECT `runspeed` FROM `npc_types` WHERE `runspeed` > 3|not_empty|
|
||||||
|
9085|2015_07_01_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
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
/* This rescales the old peq runspeeds which were about 80 percent too high to new values */
|
||||||
|
/* This section should only ever be run once */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.050 WHERE (npc_types.runspeed > 0 and npc_types.runspeed < 1.2);
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.325 WHERE (npc_types.runspeed > 1.19 and npc_types.runspeed < 1.75 and race != 73 and race != 72);
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE (npc_types.runspeed > 1.69 and npc_types.runspeed < 2.2);
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE (npc_types.runspeed > 2.19 and npc_types.runspeed < 3);
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = (npc_types.runspeed * 0.8) WHERE (npc_types.runspeed > 2.99 and npc_types.runspeed < 20);
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
/* some specific by name */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 3.175 WHERE npc_types.name = 'a_shadowed_man';
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE npc_types.name = 'aviak_egret';
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE npc_types.name = 'froglok_hunter';
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE npc_types.name = 'froglok_forager';
|
||||||
|
/* rhinos */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE npc_types.race = 135;
|
||||||
|
/* centaurs */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE npc_types.race = 16;
|
||||||
|
/* griffins */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE npc_types.race = 47;
|
||||||
|
/* wolves - use size, to not change cubs*/
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE (npc_types.race = 42 and npc_types.size > 5);
|
||||||
|
/* sarnaks */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.325 WHERE npc_types.race = 131;
|
||||||
|
/* sabertooth tigers - use size, to not change cubs*/
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE (npc_types.race = 119 and npc_types.size > 6);
|
||||||
|
/* lions */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE (npc_types.race = 50 and npc_types.size > 7);
|
||||||
|
/* panthers/pumas */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE npc_types.race = 76;
|
||||||
|
/* beetles */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.05 WHERE npc_types.race = 22;
|
||||||
|
/*leeches*/
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.05 WHERE npc_types.race = 104;
|
||||||
|
/*a_brontotherium*/
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE npc_types.race = 169;
|
||||||
|
/* raptors */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE npc_types.race = 163;
|
||||||
|
/* vicious plants */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE npc_types.race = 162;
|
||||||
|
/* western wastes, drakes, cragwyrms and wyvern */
|
||||||
|
UPDATE npc_types
|
||||||
|
JOIN spawnentry ON npc_types.id = spawnentry.npcID
|
||||||
|
JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID
|
||||||
|
SET npc_types.runspeed = 1.575
|
||||||
|
WHERE ((npc_types.race = 89 OR npc_types.race = 157 OR npc_types.race = 158) AND spawn2.zone = 'westwastes');
|
||||||
|
/* velium hounds/wolves */
|
||||||
|
UPDATE npc_types
|
||||||
|
JOIN spawnentry ON npc_types.id = spawnentry.npcID
|
||||||
|
JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID
|
||||||
|
SET npc_types.runspeed = 1.850
|
||||||
|
WHERE (npc_types.race = 42 AND spawn2.zone = 'westwastes');
|
||||||
|
/* Overthere Specials, goons, etc. */
|
||||||
|
UPDATE npc_types
|
||||||
|
JOIN spawnentry ON npc_types.id = spawnentry.npcID
|
||||||
|
JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID
|
||||||
|
SET npc_types.runspeed = 1.850
|
||||||
|
WHERE ((npc_types.race = 77 or npc_types.race = 147) AND spawn2.zone = 'overthere');
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE npc_types.name = 'Captain_Rottgrime';
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE npc_types.name = 'an_undead_marine';
|
||||||
|
/* Pet Speeds. */
|
||||||
|
UPDATE npc_types
|
||||||
|
JOIN pets ON npc_types.id = pets.npcID
|
||||||
|
SET npc_types.runspeed = 1.575;
|
||||||
|
/* raptors in tim are slower than other raptors in kunark */
|
||||||
|
UPDATE npc_types
|
||||||
|
JOIN spawnentry ON npc_types.id = spawnentry.npcID
|
||||||
|
JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID
|
||||||
|
SET npc_types.runspeed = 1.325
|
||||||
|
WHERE ( npc_types.race = 163 AND spawn2.zone = 'timorous' );
|
||||||
1
utils/sql/git/optional/2015_07_05_LiveCombatRounds.sql
Normal file
1
utils/sql/git/optional/2015_07_05_LiveCombatRounds.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:UseLiveCombatRounds', 'true', 'If true use live NPC combat rules, false will use old rules.');
|
||||||
27
utils/sql/git/optional/2015_07_06_TripleAttack.sql
Normal file
27
utils/sql/git/optional/2015_07_06_TripleAttack.sql
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS GrantTripleAttack$$
|
||||||
|
CREATE PROCEDURE GrantTripleAttack()
|
||||||
|
BEGIN
|
||||||
|
DECLARE finished INT;
|
||||||
|
DECLARE char_id INT;
|
||||||
|
DECLARE skill_max INT;
|
||||||
|
DECLARE cur CURSOR FOR SELECT character_data.id, skill_caps.cap FROM `character_data` LEFT JOIN `skill_caps` ON character_data.`level` = skill_caps.`level` AND character_data.class = skill_caps.class AND skill_caps.skillID = 76;
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
|
||||||
|
|
||||||
|
OPEN cur;
|
||||||
|
|
||||||
|
SET finished = 0;
|
||||||
|
REPEAT
|
||||||
|
FETCH cur INTO char_id, skill_max;
|
||||||
|
|
||||||
|
IF skill_max IS NOT NULL AND skill_max > 0 THEN
|
||||||
|
REPLACE INTO `character_skills` (`id`, `skill_id`, `value`) VALUES(char_id, 76, skill_max);
|
||||||
|
END IF;
|
||||||
|
UNTIL finished END REPEAT;
|
||||||
|
|
||||||
|
CLOSE cur;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL GrantTripleAttack();
|
||||||
|
DROP PROCEDURE GrantTripleAttack;
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
/* This rescales the old peq runspeeds which were about 80 percent too high to new values */
|
||||||
|
/* This section should only ever be run once */
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.050 WHERE (npc_types.runspeed > 0 and npc_types.runspeed < 1.2);
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.325 WHERE (npc_types.runspeed > 1.19 and npc_types.runspeed < 1.75 and race != 73 and race != 72);
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.575 WHERE (npc_types.runspeed > 1.69 and npc_types.runspeed < 2.2);
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 1.850 WHERE (npc_types.runspeed > 2.19 and npc_types.runspeed < 3);
|
||||||
|
UPDATE npc_types SET npc_types.runspeed = 3 WHERE npc_types.runspeed > 3;
|
||||||
1
utils/sql/git/required/2015_07_01_Marquee_Rule.sql
Normal file
1
utils/sql/git/required/2015_07_01_Marquee_Rule.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `rule_values` (`rule_name`, `rule_value`, `notes`) VALUES ('Character:MarqueeHPUpdates', 'false', 'Will show Health % in center of screen < 100%');
|
||||||
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;
|
||||||
eis->Expansions = (RuleI(World, ExpansionSettings));
|
if(RuleB(World, UseClientBasedExpansionSettings)) {
|
||||||
|
eis->Expansions = ExpansionFromClientVersion(eqs->GetClientVersion());
|
||||||
|
//eis->Expansions = ExpansionFromClientVersion(this->GetCLE.
|
||||||
|
} else {
|
||||||
|
eis->Expansions = (RuleI(World, ExpansionSettings));
|
||||||
|
}
|
||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,7 +60,7 @@ bool LauncherLink::Process() {
|
|||||||
end = m_states.end();
|
end = m_states.end();
|
||||||
for(; cur != end; ++cur) {
|
for(; cur != end; ++cur) {
|
||||||
if(!cur->second.up) {
|
if(!cur->second.up) {
|
||||||
StartZone(cur->first.c_str());
|
StartZone(cur->first.c_str(), cur->second.port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_bootTimer.Disable();
|
m_bootTimer.Disable();
|
||||||
@ -184,14 +184,6 @@ bool LauncherLink::Process() {
|
|||||||
|
|
||||||
bool LauncherLink::ContainsZone(const char *short_name) const {
|
bool LauncherLink::ContainsZone(const char *short_name) const {
|
||||||
return(m_states.find(short_name) != m_states.end());
|
return(m_states.find(short_name) != m_states.end());
|
||||||
|
|
||||||
/*
|
|
||||||
* std::map<std::string, bool>::const_iterator cur, end;
|
|
||||||
cur = m_states.begin();
|
|
||||||
end = m_states.end();
|
|
||||||
for(; cur != end; cur++) {
|
|
||||||
if(
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherLink::BootZone(const char *short_name, uint16 port) {
|
void LauncherLink::BootZone(const char *short_name, uint16 port) {
|
||||||
@ -202,15 +194,20 @@ void LauncherLink::BootZone(const char *short_name, uint16 port) {
|
|||||||
Log.Out(Logs::Detail, Logs::World_Server, "%s: Loaded zone '%s' on port %d", m_name.c_str(), short_name, zs.port);
|
Log.Out(Logs::Detail, Logs::World_Server, "%s: Loaded zone '%s' on port %d", m_name.c_str(), short_name, zs.port);
|
||||||
m_states[short_name] = zs;
|
m_states[short_name] = zs;
|
||||||
|
|
||||||
StartZone(short_name);
|
StartZone(short_name, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherLink::StartZone(const char *short_name) {
|
void LauncherLink::StartZone(const char *short_name) {
|
||||||
|
StartZone(short_name, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherLink::StartZone(const char *short_name, uint16 port) {
|
||||||
auto pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
auto pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
||||||
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
||||||
|
|
||||||
strn0cpy(s->short_name, short_name, 32);
|
strn0cpy(s->short_name, short_name, 32);
|
||||||
s->command = ZR_Start;
|
s->command = ZR_Start;
|
||||||
|
s->port = port;
|
||||||
|
|
||||||
SendPacket(pack);
|
SendPacket(pack);
|
||||||
delete pack;
|
delete pack;
|
||||||
@ -222,6 +219,7 @@ void LauncherLink::RestartZone(const char *short_name) {
|
|||||||
|
|
||||||
strn0cpy(s->short_name, short_name, 32);
|
strn0cpy(s->short_name, short_name, 32);
|
||||||
s->command = ZR_Restart;
|
s->command = ZR_Restart;
|
||||||
|
s->port = 0;
|
||||||
|
|
||||||
SendPacket(pack);
|
SendPacket(pack);
|
||||||
delete pack;
|
delete pack;
|
||||||
@ -233,6 +231,7 @@ void LauncherLink::StopZone(const char *short_name) {
|
|||||||
|
|
||||||
strn0cpy(s->short_name, short_name, 32);
|
strn0cpy(s->short_name, short_name, 32);
|
||||||
s->command = ZR_Stop;
|
s->command = ZR_Stop;
|
||||||
|
s->port = 0;
|
||||||
|
|
||||||
SendPacket(pack);
|
SendPacket(pack);
|
||||||
delete pack;
|
delete pack;
|
||||||
@ -332,35 +331,3 @@ void LauncherLink::Shutdown() {
|
|||||||
SendPacket(pack);
|
SendPacket(pack);
|
||||||
delete pack;
|
delete pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,7 @@ public:
|
|||||||
void Shutdown();
|
void Shutdown();
|
||||||
void BootZone(const char *short_name, uint16 port);
|
void BootZone(const char *short_name, uint16 port);
|
||||||
void StartZone(const char *short_name);
|
void StartZone(const char *short_name);
|
||||||
|
void StartZone(const char *short_name, uint16 port);
|
||||||
void RestartZone(const char *short_name);
|
void RestartZone(const char *short_name);
|
||||||
void StopZone(const char *short_name);
|
void StopZone(const char *short_name);
|
||||||
void BootDynamics(uint8 new_total);
|
void BootDynamics(uint8 new_total);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
2281
zone/aa.cpp
2281
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
|
||||||
719
zone/attack.cpp
719
zone/attack.cpp
@ -341,7 +341,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
|||||||
return(tohit_roll <= chancetohit);
|
return(tohit_roll <= chancetohit);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
bool Mob::AvoidDamage(Mob *other, int32 &damage, int hand)
|
||||||
{
|
{
|
||||||
/* called when a mob is attacked, does the checks to see if it's a hit
|
/* called when a mob is attacked, does the checks to see if it's a hit
|
||||||
* and does other mitigation checks. 'this' is the mob being attacked.
|
* and does other mitigation checks. 'this' is the mob being attacked.
|
||||||
@ -353,22 +353,32 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
|||||||
* -4 - dodge
|
* -4 - dodge
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
float skill;
|
|
||||||
float bonus;
|
|
||||||
float RollTable[4] = {0,0,0,0};
|
|
||||||
float roll;
|
|
||||||
Mob *attacker=other;
|
|
||||||
Mob *defender=this;
|
|
||||||
|
|
||||||
//garunteed hit
|
/* Order according to current (SoF+?) dev quotes:
|
||||||
bool ghit = false;
|
* https://forums.daybreakgames.com/eq/index.php?threads/test-update-06-10-15.223510/page-2#post-3261772
|
||||||
if((attacker->aabonuses.MeleeSkillCheck + attacker->spellbonuses.MeleeSkillCheck + attacker->itembonuses.MeleeSkillCheck) > 500)
|
* https://forums.daybreakgames.com/eq/index.php?threads/test-update-06-10-15.223510/page-2#post-3268227
|
||||||
ghit = true;
|
* Riposte 50, hDEX, must have weapon/fists, doesn't work on archery/throwing
|
||||||
|
* Block 25, hDEX, works on archery/throwing, behind block done here if back to attacker base1 is chance
|
||||||
|
* Parry 45, hDEX, doesn't work on throwing/archery, must be facing target
|
||||||
|
* Dodge 45, hAGI, works on archery/throwing, monks can dodge attacks from behind
|
||||||
|
* Shield Block, rand base1
|
||||||
|
* Staff Block, rand base1
|
||||||
|
* regular strike through
|
||||||
|
* avoiding the attack (CheckHitChance)
|
||||||
|
* As soon as one succeeds, none of the rest are checked
|
||||||
|
*
|
||||||
|
* Formula (all int math)
|
||||||
|
* (posted for parry, assume rest at the same)
|
||||||
|
* Chance = (((SKILL + 100) + [((SKILL+100) * SPA(175).Base1) / 100]) / 45) + [(hDex / 25) - min([hDex / 25], hStrikethrough)].
|
||||||
|
* hStrikethrough is a mob stat that was added to counter the bonuses of heroic stats
|
||||||
|
* Number rolled against 100, if the chance is greater than 100 it happens 100% of time
|
||||||
|
*
|
||||||
|
* Things with 10k accuracy mods can be avoided with these skills qq
|
||||||
|
*/
|
||||||
|
Mob *attacker = other;
|
||||||
|
Mob *defender = this;
|
||||||
|
|
||||||
bool InFront = false;
|
bool InFront = attacker->InFrontMob(this, attacker->GetX(), attacker->GetY());
|
||||||
|
|
||||||
if (attacker->InFrontMob(this, attacker->GetX(), attacker->GetY()))
|
|
||||||
InFront = true;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This special ability adds a negative modifer to the defenders riposte/block/parry/chance
|
This special ability adds a negative modifer to the defenders riposte/block/parry/chance
|
||||||
@ -383,10 +393,9 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
|||||||
int counter_parry = 0;
|
int counter_parry = 0;
|
||||||
int counter_dodge = 0;
|
int counter_dodge = 0;
|
||||||
|
|
||||||
if (attacker->GetSpecialAbility(COUNTER_AVOID_DAMAGE)){
|
if (attacker->GetSpecialAbility(COUNTER_AVOID_DAMAGE)) {
|
||||||
|
|
||||||
counter_all = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 0);
|
counter_all = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 0);
|
||||||
counter_riposte = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE,1);
|
counter_riposte = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 1);
|
||||||
counter_block = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 2);
|
counter_block = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 2);
|
||||||
counter_parry = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 3);
|
counter_parry = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 3);
|
||||||
counter_dodge = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 4);
|
counter_dodge = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 4);
|
||||||
@ -400,31 +409,37 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
|||||||
Log.Out(Logs::Detail, Logs::Combat, "I am enraged, riposting frontal attack.");
|
Log.Out(Logs::Detail, Logs::Combat, "I am enraged, riposting frontal attack.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
// riposte -- it may seem crazy, but if the attacker has SPA 173 on them, they are immune to Ripo
|
||||||
// riposte
|
bool ImmuneRipo = attacker->aabonuses.RiposteChance || attacker->spellbonuses.RiposteChance || attacker->itembonuses.RiposteChance;
|
||||||
/////////////////////////////////////////////////////////
|
// Need to check if we have something in MainHand to actually attack with (or fists)
|
||||||
float riposte_chance = 0.0f;
|
if (hand != MainRange && CanThisClassRiposte() && InFront && !ImmuneRipo) {
|
||||||
if (CanRiposte && damage > 0 && CanThisClassRiposte() && InFront)
|
if (IsClient())
|
||||||
{
|
|
||||||
riposte_chance = (100.0f + static_cast<float>(aabonuses.RiposteChance + spellbonuses.RiposteChance +
|
|
||||||
itembonuses.RiposteChance - counter_riposte - counter_all)) / 100.0f;
|
|
||||||
skill = GetSkill(SkillRiposte);
|
|
||||||
if (IsClient()) {
|
|
||||||
CastToClient()->CheckIncreaseSkill(SkillRiposte, other, -10);
|
CastToClient()->CheckIncreaseSkill(SkillRiposte, other, -10);
|
||||||
|
// check auto discs ... I guess aa/items too :P
|
||||||
|
if (spellbonuses.RiposteChance == 10000 || aabonuses.RiposteChance == 10000 || itembonuses.RiposteChance == 10000) {
|
||||||
|
damage = -3;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
int chance = GetSkill(SkillRiposte) + 100;
|
||||||
if (!ghit) { //if they are not using a garunteed hit discipline
|
chance += (chance * (aabonuses.RiposteChance + spellbonuses.RiposteChance + itembonuses.RiposteChance)) / 100;
|
||||||
bonus = 2.0 + skill/60.0 + (GetDEX()/200);
|
chance /= 50;
|
||||||
bonus *= riposte_chance;
|
chance += itembonuses.HeroicDEX / 25; // live has "heroic strickthrough" here to counter
|
||||||
bonus = mod_riposte_chance(bonus, attacker);
|
if (counter_riposte || counter_all) {
|
||||||
RollTable[0] = bonus + (itembonuses.HeroicDEX / 25); // 25 heroic = 1%, applies to ripo, parry, block
|
float counter = (counter_riposte + counter_all) / 100.0f;
|
||||||
|
chance -= chance * counter;
|
||||||
|
}
|
||||||
|
// AA Slippery Attacks
|
||||||
|
if (hand == MainSecondary) {
|
||||||
|
int slip = aabonuses.OffhandRiposteFail + itembonuses.OffhandRiposteFail + spellbonuses.OffhandRiposteFail;
|
||||||
|
chance += chance * slip / 100;
|
||||||
|
}
|
||||||
|
if (chance > 0 && zone->random.Roll(chance)) { // could be <0 from offhand stuff
|
||||||
|
damage = -3;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
|
||||||
// block
|
// block
|
||||||
///////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool bBlockFromRear = false;
|
bool bBlockFromRear = false;
|
||||||
|
|
||||||
// a successful roll on this does not mean a successful block is forthcoming. only that a chance to block
|
// a successful roll on this does not mean a successful block is forthcoming. only that a chance to block
|
||||||
@ -435,101 +450,100 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
|||||||
if (BlockBehindChance && zone->random.Roll(BlockBehindChance))
|
if (BlockBehindChance && zone->random.Roll(BlockBehindChance))
|
||||||
bBlockFromRear = true;
|
bBlockFromRear = true;
|
||||||
|
|
||||||
float block_chance = 0.0f;
|
if (CanThisClassBlock() && (InFront || bBlockFromRear)) {
|
||||||
if (damage > 0 && CanThisClassBlock() && (InFront || bBlockFromRear)) {
|
if (IsClient())
|
||||||
block_chance = (100.0f + static_cast<float>(aabonuses.IncreaseBlockChance + spellbonuses.IncreaseBlockChance +
|
|
||||||
itembonuses.IncreaseBlockChance - counter_block - counter_all)) / 100.0f;
|
|
||||||
skill = CastToClient()->GetSkill(SkillBlock);
|
|
||||||
if (IsClient()) {
|
|
||||||
CastToClient()->CheckIncreaseSkill(SkillBlock, other, -10);
|
CastToClient()->CheckIncreaseSkill(SkillBlock, other, -10);
|
||||||
}
|
// check auto discs ... I guess aa/items too :P
|
||||||
|
if (spellbonuses.IncreaseBlockChance == 10000 || aabonuses.IncreaseBlockChance == 10000 ||
|
||||||
if (!ghit) { //if they are not using a garunteed hit discipline
|
itembonuses.IncreaseBlockChance == 10000) {
|
||||||
bonus = 2.0 + skill/35.0 + (GetDEX()/200);
|
|
||||||
bonus = mod_block_chance(bonus, attacker);
|
|
||||||
RollTable[1] = RollTable[0] + (bonus * block_chance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
RollTable[1] = RollTable[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
//Try Shield Block OR TwoHandBluntBlockCheck
|
|
||||||
if(damage > 0 && HasShieldEquiped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock) && (InFront || bBlockFromRear))
|
|
||||||
RollTable[1] += static_cast<float>(aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock - counter_block - counter_all);
|
|
||||||
|
|
||||||
else if(damage > 0 && HasTwoHandBluntEquiped() && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock) && (InFront || bBlockFromRear))
|
|
||||||
RollTable[1] += static_cast<float>(aabonuses.TwoHandBluntBlock + spellbonuses.TwoHandBluntBlock + itembonuses.TwoHandBluntBlock - counter_block - counter_all);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
|
||||||
// parry
|
|
||||||
//////////////////////////////////////////////////////
|
|
||||||
float parry_chance = 0.0f;
|
|
||||||
if (damage > 0 && CanThisClassParry() && InFront){
|
|
||||||
parry_chance = (100.0f + static_cast<float>(aabonuses.ParryChance + itembonuses.ParryChance +
|
|
||||||
itembonuses.ParryChance - counter_parry - counter_all)) / 100.0f;
|
|
||||||
skill = CastToClient()->GetSkill(SkillParry);
|
|
||||||
if (IsClient()) {
|
|
||||||
CastToClient()->CheckIncreaseSkill(SkillParry, other, -10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ghit) { //if they are not using a garunteed hit discipline
|
|
||||||
bonus = 2.0 + skill/60.0 + (GetDEX()/200);
|
|
||||||
bonus *= parry_chance;
|
|
||||||
bonus = mod_parry_chance(bonus, attacker);
|
|
||||||
RollTable[2] = RollTable[1] + bonus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
RollTable[2] = RollTable[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// dodge
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
float dodge_chance = 0.0f;
|
|
||||||
if (damage > 0 && CanThisClassDodge() && InFront){
|
|
||||||
|
|
||||||
dodge_chance = (100.0f + static_cast<float>(aabonuses.DodgeChance + spellbonuses.DodgeChance +
|
|
||||||
itembonuses.DodgeChance - counter_dodge - counter_all)) / 100.0f;
|
|
||||||
|
|
||||||
skill = CastToClient()->GetSkill(SkillDodge);
|
|
||||||
if (IsClient()) {
|
|
||||||
CastToClient()->CheckIncreaseSkill(SkillDodge, other, -10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ghit) { //if they are not using a garunteed hit discipline
|
|
||||||
bonus = 2.0 + skill/60.0 + (GetAGI()/200);
|
|
||||||
bonus *= dodge_chance;
|
|
||||||
//DCBOOMKAR
|
|
||||||
bonus = mod_dodge_chance(bonus, attacker);
|
|
||||||
RollTable[3] = RollTable[2] + bonus - (itembonuses.HeroicDEX / 25) + (itembonuses.HeroicAGI / 25);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
RollTable[3] = RollTable[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(damage > 0){
|
|
||||||
roll = zone->random.Real(0,100);
|
|
||||||
if(roll <= RollTable[0]){
|
|
||||||
damage = -3;
|
|
||||||
}
|
|
||||||
else if(roll <= RollTable[1]){
|
|
||||||
damage = -1;
|
damage = -1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if(roll <= RollTable[2]){
|
int chance = GetSkill(SkillBlock) + 100;
|
||||||
damage = -2;
|
chance += (chance * (aabonuses.IncreaseBlockChance + spellbonuses.IncreaseBlockChance + itembonuses.IncreaseBlockChance)) / 100;
|
||||||
|
chance /= 25;
|
||||||
|
chance += itembonuses.HeroicDEX / 25; // live has "heroic strickthrough" here to counter
|
||||||
|
if (counter_block || counter_all) {
|
||||||
|
float counter = (counter_block + counter_all) / 100.0f;
|
||||||
|
chance -= chance * counter;
|
||||||
}
|
}
|
||||||
else if(roll <= RollTable[3]){
|
if (zone->random.Roll(chance)) {
|
||||||
damage = -4;
|
damage = -1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all avoidances: %d", damage);
|
// parry
|
||||||
|
if (CanThisClassParry() && InFront && hand != MainRange) {
|
||||||
|
if (IsClient())
|
||||||
|
CastToClient()->CheckIncreaseSkill(SkillParry, other, -10);
|
||||||
|
// check auto discs ... I guess aa/items too :P
|
||||||
|
if (spellbonuses.ParryChance == 10000 || aabonuses.ParryChance == 10000 || itembonuses.ParryChance == 10000) {
|
||||||
|
damage = -2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int chance = GetSkill(SkillParry) + 100;
|
||||||
|
chance += (chance * (aabonuses.ParryChance + spellbonuses.ParryChance + itembonuses.ParryChance)) / 100;
|
||||||
|
chance /= 45;
|
||||||
|
chance += itembonuses.HeroicDEX / 25; // live has "heroic strickthrough" here to counter
|
||||||
|
if (counter_parry || counter_all) {
|
||||||
|
float counter = (counter_parry + counter_all) / 100.0f;
|
||||||
|
chance -= chance * counter;
|
||||||
|
}
|
||||||
|
if (zone->random.Roll(chance)) {
|
||||||
|
damage = -2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dodge
|
||||||
|
if (CanThisClassDodge() && (InFront || GetClass() == MONK) ) {
|
||||||
|
if (IsClient())
|
||||||
|
CastToClient()->CheckIncreaseSkill(SkillDodge, other, -10);
|
||||||
|
// check auto discs ... I guess aa/items too :P
|
||||||
|
if (spellbonuses.DodgeChance == 10000 || aabonuses.DodgeChance == 10000 || itembonuses.DodgeChance == 10000) {
|
||||||
|
damage = -4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int chance = GetSkill(SkillDodge) + 100;
|
||||||
|
chance += (chance * (aabonuses.DodgeChance + spellbonuses.DodgeChance + itembonuses.DodgeChance)) / 100;
|
||||||
|
chance /= 45;
|
||||||
|
chance += itembonuses.HeroicAGI / 25; // live has "heroic strickthrough" here to counter
|
||||||
|
if (counter_dodge || counter_all) {
|
||||||
|
float counter = (counter_dodge + counter_all) / 100.0f;
|
||||||
|
chance -= chance * counter;
|
||||||
|
}
|
||||||
|
if (zone->random.Roll(chance)) {
|
||||||
|
damage = -4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try Shield Block OR TwoHandBluntBlockCheck
|
||||||
|
if (HasShieldEquiped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock) && (InFront || bBlockFromRear)) {
|
||||||
|
int chance = aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock;
|
||||||
|
if (counter_block || counter_all) {
|
||||||
|
float counter = (counter_block + counter_all) / 100.0f;
|
||||||
|
chance -= chance * counter;
|
||||||
|
}
|
||||||
|
if (zone->random.Roll(chance)) {
|
||||||
|
damage = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasTwoHandBluntEquiped() && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock) && (InFront || bBlockFromRear)) {
|
||||||
|
int chance = aabonuses.TwoHandBluntBlock + itembonuses.TwoHandBluntBlock + spellbonuses.TwoHandBluntBlock;
|
||||||
|
if (counter_block || counter_all) {
|
||||||
|
float counter = (counter_block + counter_all) / 100.0f;
|
||||||
|
chance -= chance * counter;
|
||||||
|
}
|
||||||
|
if (zone->random.Roll(chance)) {
|
||||||
|
damage = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (damage < 0)
|
|
||||||
return true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1286,6 +1300,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this effect is actually a min cap that happens after the final damage is calculated
|
||||||
min_hit += min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100;
|
min_hit += min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100;
|
||||||
|
|
||||||
if(max_hit < min_hit)
|
if(max_hit < min_hit)
|
||||||
@ -1312,66 +1327,52 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check to see if we hit..
|
//check to see if we hit..
|
||||||
if(!other->CheckHitChance(this, skillinuse, Hand, hit_chance_bonus)) {
|
if (other->AvoidDamage(this, damage, Hand)) {
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Attack missed. Damage set to 0.");
|
if (!bRiposte && !IsStrikethrough) {
|
||||||
damage = 0;
|
int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
|
||||||
} else { //we hit, try to avoid it
|
if(strike_through && zone->random.Roll(strike_through)) {
|
||||||
other->AvoidDamage(this, damage);
|
Message_StringID(MT_StrikeThrough, STRIKETHROUGH_STRING); // You strike through your opponents defenses!
|
||||||
other->MeleeMitigation(this, damage, min_hit, opts);
|
Attack(other, Hand, false, true); // Strikethrough only gives another attempted hit
|
||||||
if(damage > 0)
|
return false;
|
||||||
CommonOutgoingHitSuccess(other, damage, skillinuse);
|
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
//riposte
|
|
||||||
bool slippery_attack = false; // Part of hack to allow riposte to become a miss, but still allow a Strikethrough chance (like on Live)
|
|
||||||
if (damage == -3) {
|
|
||||||
if (bRiposte) return false;
|
|
||||||
else {
|
|
||||||
if (Hand == MainSecondary) {// Do we even have it & was attack with mainhand? If not, don't bother with other calculations
|
|
||||||
//Live AA - SlipperyAttacks
|
|
||||||
//This spell effect most likely directly modifies the actual riposte chance when using offhand attack.
|
|
||||||
int32 OffhandRiposteFail = aabonuses.OffhandRiposteFail + itembonuses.OffhandRiposteFail + spellbonuses.OffhandRiposteFail;
|
|
||||||
OffhandRiposteFail *= -1; //Live uses a negative value for this.
|
|
||||||
|
|
||||||
if (OffhandRiposteFail &&
|
|
||||||
(OffhandRiposteFail > 99 || zone->random.Roll(OffhandRiposteFail))) {
|
|
||||||
damage = 0; // Counts as a miss
|
|
||||||
slippery_attack = true;
|
|
||||||
} else
|
|
||||||
DoRiposte(other);
|
|
||||||
if (IsDead()) return false;
|
|
||||||
}
|
}
|
||||||
else
|
// I'm pretty sure you can riposte a riposte
|
||||||
|
if (damage == -3 && !bRiposte) {
|
||||||
DoRiposte(other);
|
DoRiposte(other);
|
||||||
if (IsDead()) return false;
|
if (IsDead())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.Out(Logs::Detail, Logs::Combat, "Avoided damage with code %d", damage);
|
||||||
|
} else {
|
||||||
|
if (other->CheckHitChance(this, skillinuse, Hand, hit_chance_bonus)) {
|
||||||
|
other->MeleeMitigation(this, damage, min_hit, opts);
|
||||||
|
if (damage > 0)
|
||||||
|
CommonOutgoingHitSuccess(other, damage, skillinuse);
|
||||||
|
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", damage);
|
||||||
|
} else {
|
||||||
|
Log.Out(Logs::Detail, Logs::Combat, "Attack missed. Damage set to 0.");
|
||||||
|
damage = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (((damage < 0) || slippery_attack) && !bRiposte && !IsStrikethrough) { // Hack to still allow Strikethrough chance w/ Slippery Attacks AA
|
|
||||||
int32 bonusStrikeThrough = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
|
|
||||||
|
|
||||||
if(bonusStrikeThrough && zone->random.Roll(bonusStrikeThrough)) {
|
|
||||||
Message_StringID(MT_StrikeThrough, STRIKETHROUGH_STRING); // You strike through your opponents defenses!
|
|
||||||
Attack(other, Hand, false, true); // Strikethrough only gives another attempted hit
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
damage = -5;
|
damage = -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hate Generation is on a per swing basis, regardless of a hit, miss, or block, its always the same.
|
// Hate Generation is on a per swing basis, regardless of a hit, miss, or block, its always the same.
|
||||||
// If we are this far, this means we are atleast making a swing.
|
// If we are this far, this means we are atleast making a swing.
|
||||||
|
|
||||||
if (!bRiposte) // Ripostes never generate any aggro.
|
other->AddToHateList(this, hate);
|
||||||
other->AddToHateList(this, hate);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
////// 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;
|
||||||
@ -1905,21 +1906,18 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
hit_chance_bonus += opts->hit_chance;
|
hit_chance_bonus += opts->hit_chance;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!other->CheckHitChance(this, skillinuse, Hand, hit_chance_bonus)) {
|
if (other->AvoidDamage(this, damage, Hand)) {
|
||||||
damage = 0; //miss
|
if (!bRiposte && damage == -3)
|
||||||
} else { //hit, check for damage avoidance
|
DoRiposte(other);
|
||||||
other->AvoidDamage(this, damage);
|
} else {
|
||||||
other->MeleeMitigation(this, damage, min_dmg+eleBane, opts);
|
if (other->CheckHitChance(this, skillinuse, Hand, hit_chance_bonus)) {
|
||||||
if(damage > 0) {
|
other->MeleeMitigation(this, damage, min_dmg+eleBane, opts);
|
||||||
CommonOutgoingHitSuccess(other, damage, skillinuse);
|
CommonOutgoingHitSuccess(other, damage, skillinuse);
|
||||||
|
} else {
|
||||||
|
damage = 0;
|
||||||
}
|
}
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Generating hate %d towards %s", hate, GetName());
|
|
||||||
// now add done damage to the hate list
|
|
||||||
if(damage > 0)
|
|
||||||
other->AddToHateList(this, hate);
|
|
||||||
else
|
|
||||||
other->AddToHateList(this, 0);
|
|
||||||
}
|
}
|
||||||
|
other->AddToHateList(this, hate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage against %s: %d", other->GetName(), damage);
|
Log.Out(Logs::Detail, Logs::Combat, "Final damage against %s: %d", other->GetName(), damage);
|
||||||
@ -1932,12 +1930,6 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
else
|
else
|
||||||
damage = -5;
|
damage = -5;
|
||||||
|
|
||||||
//cant riposte a riposte
|
|
||||||
if (bRiposte && damage == -3) {
|
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Riposte of riposte canceled.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GetHP() > 0 && !other->HasDied()) {
|
if(GetHP() > 0 && !other->HasDied()) {
|
||||||
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse, false); // Not avoidable client already had thier chance to Avoid
|
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse, false); // Not avoidable client already had thier chance to Avoid
|
||||||
} else
|
} else
|
||||||
@ -1967,11 +1959,6 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
if(GetHP() > 0 && !other->HasDied())
|
if(GetHP() > 0 && !other->HasDied())
|
||||||
TriggerDefensiveProcs(nullptr, other, Hand, damage);
|
TriggerDefensiveProcs(nullptr, other, Hand, damage);
|
||||||
|
|
||||||
// now check ripostes
|
|
||||||
if (damage == -3) { // riposting
|
|
||||||
DoRiposte(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -3419,41 +3406,39 @@ bool Mob::HasRangedProcs() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::CheckDoubleAttack(bool tripleAttack) {
|
bool Client::CheckDoubleAttack()
|
||||||
|
{
|
||||||
|
int chance = 0;
|
||||||
|
int skill = GetSkill(SkillDoubleAttack);
|
||||||
//Check for bonuses that give you a double attack chance regardless of skill (ie Bestial Frenzy/Harmonious Attack AA)
|
//Check for bonuses that give you a double attack chance regardless of skill (ie Bestial Frenzy/Harmonious Attack AA)
|
||||||
uint32 bonusGiveDA = aabonuses.GiveDoubleAttack + spellbonuses.GiveDoubleAttack + itembonuses.GiveDoubleAttack;
|
int bonusGiveDA = aabonuses.GiveDoubleAttack + spellbonuses.GiveDoubleAttack + itembonuses.GiveDoubleAttack;
|
||||||
|
if (skill > 0)
|
||||||
if(!HasSkill(SkillDoubleAttack) && !bonusGiveDA)
|
chance = skill + GetLevel();
|
||||||
|
else if (!bonusGiveDA)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float chance = 0.0f;
|
if (bonusGiveDA)
|
||||||
|
chance += bonusGiveDA / 100.0f * 500; // convert to skill value
|
||||||
|
int per_inc = aabonuses.DoubleAttackChance + spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance;
|
||||||
|
if (per_inc)
|
||||||
|
chance += chance * per_inc / 100;
|
||||||
|
|
||||||
uint16 skill = GetSkill(SkillDoubleAttack);
|
return zone->random.Int(1, 500) <= chance;
|
||||||
|
}
|
||||||
|
|
||||||
int32 bonusDA = aabonuses.DoubleAttackChance + spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance;
|
// Admittedly these parses were short, but this check worked for 3 toons across multiple levels
|
||||||
|
// with varying triple attack skill (1-3% error at least)
|
||||||
|
bool Client::CheckTripleAttack()
|
||||||
|
{
|
||||||
|
int chance = GetSkill(SkillTripleAttack);
|
||||||
|
if (chance < 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
//Use skill calculations otherwise, if you only have AA applied GiveDoubleAttack chance then use that value as the base.
|
int per_inc = aabonuses.TripleAttackChance + spellbonuses.TripleAttackChance + itembonuses.TripleAttackChance;
|
||||||
if (skill)
|
if (per_inc)
|
||||||
chance = (float(skill+GetLevel()) * (float(100.0f+bonusDA+bonusGiveDA) /100.0f)) /500.0f;
|
chance += chance * per_inc / 100;
|
||||||
else
|
|
||||||
chance = (float(bonusGiveDA) * (float(100.0f+bonusDA)/100.0f) ) /100.0f;
|
|
||||||
|
|
||||||
//Live now uses a static Triple Attack skill (lv 46 = 2% lv 60 = 20%) - We do not have this skill on EMU ATM.
|
return zone->random.Int(1, 1000) <= chance;
|
||||||
//A reasonable forumla would then be TA = 20% * chance
|
|
||||||
//AA's can also give triple attack skill over cap. (ie Burst of Power) NOTE: Skill ID in spell data is 76 (Triple Attack)
|
|
||||||
//Kayen: Need to decide if we can implement triple attack skill before working in over the cap effect.
|
|
||||||
if(tripleAttack) {
|
|
||||||
// Only some Double Attack classes get Triple Attack [This is already checked in client_processes.cpp]
|
|
||||||
int32 triple_bonus = spellbonuses.TripleAttackChance + itembonuses.TripleAttackChance;
|
|
||||||
chance *= 0.2f; //Baseline chance is 20% of your double attack chance.
|
|
||||||
chance *= float(100.0f+triple_bonus)/100.0f; //Apply modifiers.
|
|
||||||
}
|
|
||||||
|
|
||||||
if(zone->random.Roll(chance))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::CheckDoubleRangedAttack() {
|
bool Client::CheckDoubleRangedAttack() {
|
||||||
@ -3465,6 +3450,21 @@ bool Client::CheckDoubleRangedAttack() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Mob::CheckDoubleAttack()
|
||||||
|
{
|
||||||
|
// Not 100% certain pets follow this or if it's just from pets not always
|
||||||
|
// having the same skills as most mobs
|
||||||
|
int chance = GetSkill(SkillDoubleAttack);
|
||||||
|
if (GetLevel() > 35)
|
||||||
|
chance += GetLevel();
|
||||||
|
|
||||||
|
int per_inc = aabonuses.DoubleAttackChance + spellbonuses.DoubleAttackChance + itembonuses.DoubleAttackChance;
|
||||||
|
if (per_inc)
|
||||||
|
chance += chance * per_inc / 100;
|
||||||
|
|
||||||
|
return zone->random.Int(1, 500) <= chance;
|
||||||
|
}
|
||||||
|
|
||||||
void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, const SkillUseTypes skill_used, bool &avoidable, const int8 buffslot, const bool iBuffTic) {
|
void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, const SkillUseTypes skill_used, bool &avoidable, const int8 buffslot, const bool iBuffTic) {
|
||||||
// This method is called with skill_used=ABJURE for Damage Shield damage.
|
// This method is called with skill_used=ABJURE for Damage Shield damage.
|
||||||
bool FromDamageShield = (skill_used == SkillAbjuration);
|
bool FromDamageShield = (skill_used == SkillAbjuration);
|
||||||
@ -3512,14 +3512,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;
|
||||||
@ -3583,6 +3575,9 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
|||||||
|
|
||||||
SetHP(GetHP() - damage);
|
SetHP(GetHP() - damage);
|
||||||
|
|
||||||
|
if (IsClient())
|
||||||
|
this->CastToClient()->SendHPUpdateMarquee();
|
||||||
|
|
||||||
if(HasDied()) {
|
if(HasDied()) {
|
||||||
bool IsSaved = false;
|
bool IsSaved = false;
|
||||||
|
|
||||||
@ -3693,11 +3688,11 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
|||||||
|
|
||||||
//send an HP update if we are hurt
|
//send an HP update if we are hurt
|
||||||
if(GetHP() < GetMaxHP())
|
if(GetHP() < GetMaxHP())
|
||||||
SendHPUpdate(!iBuffTic); // the OP_Damage actually updates the client in these cases, so we skill them
|
SendHPUpdate(!iBuffTic); // the OP_Damage actually updates the client in these cases, so we skip the HP update for them
|
||||||
} //end `if damage was done`
|
} //end `if damage was done`
|
||||||
|
|
||||||
//send damage packet...
|
//send damage packet...
|
||||||
if(!iBuffTic) { //buff ticks do not send damage, instead they just call SendHPUpdate(), which is done below
|
if(!iBuffTic) { //buff ticks do not send damage, instead they just call SendHPUpdate(), which is done above
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
|
||||||
CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
|
CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
|
||||||
a->target = GetID();
|
a->target = GetID();
|
||||||
@ -4413,42 +4408,55 @@ 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];
|
defender->itembonuses.DoubleRiposte;
|
||||||
|
|
||||||
DoubleRipChance = defender->aabonuses.DoubleRiposte +
|
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||||
defender->spellbonuses.DoubleRiposte +
|
Log.Out(Logs::Detail, Logs::Combat,
|
||||||
defender->itembonuses.DoubleRiposte;
|
"Preforming a double riposted from SE_DoubleRiposte (%d percent chance)", DoubleRipChance);
|
||||||
|
|
||||||
//Live AA - Double Riposte
|
|
||||||
if(DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Preforming a double riposed (%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).
|
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[0] + defender->spellbonuses.GiveDoubleRiposte[0] +
|
||||||
//Coded narrowly: Limit to one per client. Limit AA only. [1 = Skill Attack Chance, 2 = Skill]
|
defender->itembonuses.GiveDoubleRiposte[0];
|
||||||
|
|
||||||
|
// Live AA - Double Riposte
|
||||||
|
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||||
|
Log.Out(Logs::Detail, Logs::Combat,
|
||||||
|
"Preforming a double riposted from SE_GiveDoubleRiposte base1 == 0 (%d percent chance)",
|
||||||
|
DoubleRipChance);
|
||||||
|
defender->Attack(this, MainPrimary, true);
|
||||||
|
if (HasDied())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double Riposte effect, allows for a chance to do RIPOSTE with a skill specific special attack (ie Return Kick).
|
||||||
|
// Coded narrowly: Limit to one per client. Limit AA only. [1 = Skill Attack Chance, 2 = Skill]
|
||||||
|
|
||||||
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4640,7 +4648,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;
|
||||||
@ -4659,36 +4667,41 @@ 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) {
|
|
||||||
proc_spell_id = base1;
|
|
||||||
ProcMod = static_cast<float>(base2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (effect == SE_LimitToSkill && base1 <= HIGHEST_SKILL) {
|
for(auto &effect : rank->effects) {
|
||||||
|
effect_id = effect.effect_id;
|
||||||
|
base1 = effect.base1;
|
||||||
|
base2 = effect.base2;
|
||||||
|
slot = effect.slot;
|
||||||
|
|
||||||
if (CanProc && base1 == skill && IsValidSpell(proc_spell_id)) {
|
if(effect_id == SE_SkillProc || effect_id == SE_SkillProcSuccess) {
|
||||||
float final_chance = chance * (ProcMod / 100.0f);
|
proc_spell_id = base1;
|
||||||
|
ProcMod = static_cast<float>(base2);
|
||||||
|
}
|
||||||
|
else if(effect_id == SE_LimitToSkill && base1 <= HIGHEST_SKILL) {
|
||||||
|
|
||||||
if (zone->random.Roll(final_chance)) {
|
if (CanProc && base1 == skill && IsValidSpell(proc_spell_id)) {
|
||||||
ExecWeaponProc(nullptr, proc_spell_id, on);
|
float final_chance = chance * (ProcMod / 100.0f);
|
||||||
CanProc = false;
|
|
||||||
break;
|
if (zone->random.Roll(final_chance)) {
|
||||||
|
ExecWeaponProc(nullptr, proc_spell_id, on);
|
||||||
|
CanProc = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else {
|
proc_spell_id = 0;
|
||||||
proc_spell_id = 0;
|
ProcMod = 0;
|
||||||
ProcMod = 0;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4906,7 +4919,6 @@ void Client::SetAttackTimer()
|
|||||||
attack_timer.SetAtTrigger(4000, true);
|
attack_timer.SetAtTrigger(4000, true);
|
||||||
|
|
||||||
Timer *TimerToUse = nullptr;
|
Timer *TimerToUse = nullptr;
|
||||||
const Item_Struct *PrimaryWeapon = nullptr;
|
|
||||||
|
|
||||||
for (int i = MainRange; i <= MainSecondary; i++) {
|
for (int i = MainRange; i <= MainSecondary; i++) {
|
||||||
//pick a timer
|
//pick a timer
|
||||||
@ -4928,19 +4940,8 @@ void Client::SetAttackTimer()
|
|||||||
|
|
||||||
//special offhand stuff
|
//special offhand stuff
|
||||||
if (i == MainSecondary) {
|
if (i == MainSecondary) {
|
||||||
//if we have a 2H weapon in our main hand, no dual
|
|
||||||
if (PrimaryWeapon != nullptr) {
|
|
||||||
if (PrimaryWeapon->ItemClass == ItemClassCommon
|
|
||||||
&& (PrimaryWeapon->ItemType == ItemType2HSlash
|
|
||||||
|| PrimaryWeapon->ItemType == ItemType2HBlunt
|
|
||||||
|| PrimaryWeapon->ItemType == ItemType2HPiercing)) {
|
|
||||||
attack_dw_timer.Disable();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if we cant dual wield, skip it
|
//if we cant dual wield, skip it
|
||||||
if (!CanThisClassDualWield()) {
|
if (!CanThisClassDualWield() || HasTwoHanderEquipped()) {
|
||||||
attack_dw_timer.Disable();
|
attack_dw_timer.Disable();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -4989,9 +4990,6 @@ void Client::SetAttackTimer()
|
|||||||
if (quiver_haste > 0)
|
if (quiver_haste > 0)
|
||||||
speed *= quiver_haste;
|
speed *= quiver_haste;
|
||||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
||||||
|
|
||||||
if (i == MainPrimary)
|
|
||||||
PrimaryWeapon = ItemToUse;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5029,8 +5027,8 @@ void NPC::SetAttackTimer()
|
|||||||
|
|
||||||
//special offhand stuff
|
//special offhand stuff
|
||||||
if (i == MainSecondary) {
|
if (i == MainSecondary) {
|
||||||
//NPCs get it for free at 13
|
// SPECATK_QUAD is uncheesable
|
||||||
if(GetLevel() < 13) {
|
if(!CanThisClassDualWield() || (HasTwoHanderEquipped() && !GetSpecialAbility(SPECATK_QUAD))) {
|
||||||
attack_dw_timer.Disable();
|
attack_dw_timer.Disable();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -5039,3 +5037,140 @@ 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);
|
||||||
|
|
||||||
|
bool candouble = CanThisClassDoubleAttack();
|
||||||
|
// extra off hand non-sense, can only double with skill of 150 or above
|
||||||
|
// or you have any amount of GiveDoubleAttack
|
||||||
|
if (candouble && hand == MainSecondary)
|
||||||
|
candouble = GetSkill(SkillDoubleAttack) > 149 || (aabonuses.GiveDoubleAttack + spellbonuses.GiveDoubleAttack + itembonuses.GiveDoubleAttack) > 0;
|
||||||
|
|
||||||
|
if (candouble) {
|
||||||
|
CheckIncreaseSkill(SkillDoubleAttack, target, -10);
|
||||||
|
if (CheckDoubleAttack()) {
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
// you can only triple from the main hand
|
||||||
|
if (hand == MainPrimary && CanThisClassTripleAttack()) {
|
||||||
|
CheckIncreaseSkill(SkillTripleAttack, target, -10);
|
||||||
|
if (CheckTripleAttack())
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hand == MainPrimary) {
|
||||||
|
// According to http://www.monkly-business.net/forums/showpost.php?p=312095&postcount=168 a dev told them flurry isn't dependant on triple attack
|
||||||
|
// the parses kind of back that up and all of my parses seemed to be 4 or 5 attacks in the round which would work out to be
|
||||||
|
// doubles or triples with 2 from flurries or triple with 1 or 2 flurries ... Going with the "dev quote" I guess like we've always had it
|
||||||
|
auto flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
||||||
|
if (flurrychance && zone->random.Roll(flurrychance)) {
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
||||||
|
}
|
||||||
|
// I haven't parsed where this guy happens, but it's not part of the normal chain above so this is fine
|
||||||
|
auto extraattackchance = aabonuses.ExtraAttackChance + spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance;
|
||||||
|
if (extraattackchance && HasTwoHanderEquipped() && zone->random.Roll(extraattackchance))
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mob::CheckDualWield()
|
||||||
|
{
|
||||||
|
// Pets /might/ follow a slightly different progression
|
||||||
|
// although it could all be from pets having different skills than most mobs
|
||||||
|
int chance = GetSkill(SkillDualWield);
|
||||||
|
if (GetLevel() > 35)
|
||||||
|
chance += GetLevel();
|
||||||
|
|
||||||
|
chance += aabonuses.Ambidexterity + spellbonuses.Ambidexterity + itembonuses.Ambidexterity;
|
||||||
|
int per_inc = spellbonuses.DualWieldChance + aabonuses.DualWieldChance + itembonuses.DualWieldChance;
|
||||||
|
if (per_inc)
|
||||||
|
chance += chance * per_inc / 100;
|
||||||
|
|
||||||
|
return zone->random.Int(1, 375) <= chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::CheckDualWield()
|
||||||
|
{
|
||||||
|
int chance = GetSkill(SkillDualWield) + GetLevel();
|
||||||
|
|
||||||
|
chance += aabonuses.Ambidexterity + spellbonuses.Ambidexterity + itembonuses.Ambidexterity;
|
||||||
|
int per_inc = spellbonuses.DualWieldChance + aabonuses.DualWieldChance + itembonuses.DualWieldChance;
|
||||||
|
if (per_inc)
|
||||||
|
chance += chance * per_inc / 100;
|
||||||
|
|
||||||
|
return zone->random.Int(1, 375) <= chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts)
|
||||||
|
{
|
||||||
|
if (!target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (RuleB(Combat, UseLiveCombatRounds)) {
|
||||||
|
// A "quad" on live really is just a successful dual wield where both double attack
|
||||||
|
// The mobs that could triple lost the ability to when the triple attack skill was added in
|
||||||
|
Attack(target, MainPrimary, false, false, false, opts);
|
||||||
|
if (CanThisClassDoubleAttack() && CheckDoubleAttack())
|
||||||
|
Attack(target, MainPrimary, false, false, false, opts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsNPC()) {
|
||||||
|
int16 n_atk = CastToNPC()->GetNumberOfAttacks();
|
||||||
|
if (n_atk <= 1) {
|
||||||
|
Attack(target, MainPrimary, false, false, false, opts);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < n_atk; ++i) {
|
||||||
|
Attack(target, MainPrimary, false, false, false, opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Attack(target, MainPrimary, false, false, false, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we use this random value in three comparisons with different
|
||||||
|
// thresholds, and if its truely random, then this should work
|
||||||
|
// out reasonably and will save us compute resources.
|
||||||
|
int32 RandRoll = zone->random.Int(0, 99);
|
||||||
|
if ((CanThisClassDoubleAttack() || GetSpecialAbility(SPECATK_TRIPLE) || GetSpecialAbility(SPECATK_QUAD))
|
||||||
|
// check double attack, this is NOT the same rules that clients use...
|
||||||
|
&&
|
||||||
|
RandRoll < (GetLevel() + NPCDualAttackModifier)) {
|
||||||
|
Attack(target, MainPrimary, false, false, false, opts);
|
||||||
|
// lets see if we can do a triple attack with the main hand
|
||||||
|
// pets are excluded from triple and quads...
|
||||||
|
if ((GetSpecialAbility(SPECATK_TRIPLE) || GetSpecialAbility(SPECATK_QUAD)) && !IsPet() &&
|
||||||
|
RandRoll < (GetLevel() + NPCTripleAttackModifier)) {
|
||||||
|
Attack(target, MainPrimary, false, false, false, opts);
|
||||||
|
// now lets check the quad attack
|
||||||
|
if (GetSpecialAbility(SPECATK_QUAD) && RandRoll < (GetLevel() + NPCQuadAttackModifier)) {
|
||||||
|
Attack(target, MainPrimary, false, false, false, opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts)
|
||||||
|
{
|
||||||
|
if (!target)
|
||||||
|
return;
|
||||||
|
// Mobs will only dual wield w/ the flag or have a secondary weapon
|
||||||
|
// For now, SPECATK_QUAD means innate DW when Combat:UseLiveCombatRounds is true
|
||||||
|
if ((GetSpecialAbility(SPECATK_INNATE_DW) ||
|
||||||
|
(RuleB(Combat, UseLiveCombatRounds) && GetSpecialAbility(SPECATK_QUAD))) ||
|
||||||
|
GetEquipment(MaterialSecondary) != 0) {
|
||||||
|
if (CheckDualWield()) {
|
||||||
|
Attack(target, MainSecondary, false, false, false, opts);
|
||||||
|
if (CanThisClassDoubleAttack() && GetLevel() > 35 && CheckDoubleAttack())
|
||||||
|
Attack(target, MainSecondary, false, false, false, opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
1645
zone/bonuses.cpp
1645
zone/bonuses.cpp
File diff suppressed because it is too large
Load Diff
2069
zone/bot.cpp
2069
zone/bot.cpp
File diff suppressed because it is too large
Load Diff
18
zone/bot.h
18
zone/bot.h
@ -169,7 +169,6 @@ public:
|
|||||||
uint16 BotGetSpellType(int spellslot) { return AIspells[spellslot].type; }
|
uint16 BotGetSpellType(int spellslot) { return AIspells[spellslot].type; }
|
||||||
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
|
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
|
||||||
virtual float GetProcChances(float ProcBonus, uint16 hand);
|
virtual float GetProcChances(float ProcBonus, uint16 hand);
|
||||||
virtual bool AvoidDamage(Mob* other, int32 &damage, bool CanRiposte);
|
|
||||||
virtual int GetMonkHandToHandDamage(void);
|
virtual int GetMonkHandToHandDamage(void);
|
||||||
virtual bool TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse);
|
virtual bool TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse);
|
||||||
virtual void DoRiposte(Mob* defender);
|
virtual void DoRiposte(Mob* defender);
|
||||||
@ -314,11 +313,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,12 +448,8 @@ 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 GetInHealRotation() { return _isInHealRotation; }
|
bool GetInHealRotation() { return _isInHealRotation; }
|
||||||
bool GetHealRotationActive() { return (GetInHealRotation() && _isHealRotationActive); }
|
bool GetHealRotationActive() { return (GetInHealRotation() && _isHealRotationActive); }
|
||||||
bool GetHealRotationUseFastHeals() { return _healRotationUseFastHeals; }
|
bool GetHealRotationUseFastHeals() { return _healRotationUseFastHeals; }
|
||||||
@ -539,7 +535,6 @@ public:
|
|||||||
void SetDisciplineRecastTimer(int timer_index, int32 recast_delay);
|
void SetDisciplineRecastTimer(int timer_index, int32 recast_delay);
|
||||||
void SetHasBeenSummoned(bool s);
|
void SetHasBeenSummoned(bool s);
|
||||||
void SetPreSummonLocation(const glm::vec3& location) { m_PreSummonLocation = location; }
|
void SetPreSummonLocation(const glm::vec3& location) { m_PreSummonLocation = location; }
|
||||||
void SetGroupMessagesOn(bool groupMessagesOn) { _groupMessagesOn = groupMessagesOn; }
|
|
||||||
void SetInHealRotation( bool inRotation ) { _isInHealRotation = inRotation; }
|
void SetInHealRotation( bool inRotation ) { _isInHealRotation = inRotation; }
|
||||||
void SetHealRotationActive( bool isActive ) { _isHealRotationActive = isActive; }
|
void SetHealRotationActive( bool isActive ) { _isHealRotationActive = isActive; }
|
||||||
void SetHealRotationUseFastHeals( bool useFastHeals ) { _healRotationUseFastHeals = useFastHeals; }
|
void SetHealRotationUseFastHeals( bool useFastHeals ) { _healRotationUseFastHeals = useFastHeals; }
|
||||||
@ -552,6 +547,8 @@ public:
|
|||||||
void SetNumHealRotationMembers( uint8 numMembers ) { _numHealRotationMembers = numMembers; }
|
void SetNumHealRotationMembers( uint8 numMembers ) { _numHealRotationMembers = numMembers; }
|
||||||
void SetBardUseOutOfCombatSongs(bool useOutOfCombatSongs) { _bardUseOutOfCombatSongs = useOutOfCombatSongs;}
|
void SetBardUseOutOfCombatSongs(bool useOutOfCombatSongs) { _bardUseOutOfCombatSongs = useOutOfCombatSongs;}
|
||||||
void SetShowHelm(bool showhelm) { _showhelm = showhelm; }
|
void SetShowHelm(bool showhelm) { _showhelm = showhelm; }
|
||||||
|
|
||||||
|
std::string CreateSayLink(Client* botOwner, const char* message, const char* name);
|
||||||
|
|
||||||
// Class Destructors
|
// Class Destructors
|
||||||
virtual ~Bot();
|
virtual ~Bot();
|
||||||
@ -564,7 +561,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);
|
||||||
@ -608,7 +605,6 @@ private:
|
|||||||
bool _hasBeenSummoned;
|
bool _hasBeenSummoned;
|
||||||
glm::vec3 m_PreSummonLocation;
|
glm::vec3 m_PreSummonLocation;
|
||||||
uint8 _spellCastingChances[MaxStances][MaxSpellTypes];
|
uint8 _spellCastingChances[MaxStances][MaxSpellTypes];
|
||||||
bool _groupMessagesOn;
|
|
||||||
bool _isInHealRotation;
|
bool _isInHealRotation;
|
||||||
bool _isHealRotationActive;
|
bool _isHealRotationActive;
|
||||||
bool _healRotationUseFastHeals;
|
bool _healRotationUseFastHeals;
|
||||||
@ -646,12 +642,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);
|
||||||
|
|||||||
@ -75,7 +75,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
|||||||
|
|
||||||
MakeAnyLenString(&gmsg, "Attempting to mez %s.", addMob->GetCleanName());
|
MakeAnyLenString(&gmsg, "Attempting to mez %s.", addMob->GetCleanName());
|
||||||
|
|
||||||
if(gmsg && GetGroupMessagesOn())
|
if(gmsg)
|
||||||
BotGroupSay(this, gmsg);
|
BotGroupSay(this, gmsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,7 +262,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gmsg && GetGroupMessagesOn())
|
if(gmsg)
|
||||||
BotGroupSay(this, gmsg);
|
BotGroupSay(this, gmsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -793,7 +793,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
|||||||
|
|
||||||
MakeAnyLenString(&gmsg, "Attempting to slow %s.", tar->GetCleanName());
|
MakeAnyLenString(&gmsg, "Attempting to slow %s.", tar->GetCleanName());
|
||||||
|
|
||||||
if(gmsg && GetGroupMessagesOn())
|
if(gmsg)
|
||||||
BotGroupSay(this, gmsg);
|
BotGroupSay(this, gmsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
134
zone/client.cpp
134
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;
|
||||||
@ -198,6 +197,7 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
SetTarget(0);
|
SetTarget(0);
|
||||||
auto_attack = false;
|
auto_attack = false;
|
||||||
auto_fire = false;
|
auto_fire = false;
|
||||||
|
runmode = false;
|
||||||
linkdead_timer.Disable();
|
linkdead_timer.Disable();
|
||||||
zonesummon_id = 0;
|
zonesummon_id = 0;
|
||||||
zonesummon_ignorerestrictions = 0;
|
zonesummon_ignorerestrictions = 0;
|
||||||
@ -440,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));
|
||||||
@ -457,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;
|
||||||
@ -524,48 +524,39 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8040,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) {
|
||||||
@ -8638,3 +8579,16 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold,
|
|||||||
QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
|
QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::SendHPUpdateMarquee(){
|
||||||
|
if (!RuleB(Character, MarqueeHPUpdates))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Health Update Marquee Display: Custom*/
|
||||||
|
uint32 health_percentage = (uint32)(this->cur_hp * 100 / this->max_hp);
|
||||||
|
if (health_percentage == 100)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string health_update_notification = StringFormat("Health: %u%%", health_percentage);
|
||||||
|
this->SendMarqueeMessage(15, 510, 0, 3000, 3000, health_update_notification);
|
||||||
|
}
|
||||||
|
|||||||
@ -45,7 +45,6 @@ struct Item_Struct;
|
|||||||
#include "../common/item_struct.h"
|
#include "../common/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
|
||||||
@ -898,8 +888,10 @@ public:
|
|||||||
bool CheckTradeLoreConflict(Client* other);
|
bool CheckTradeLoreConflict(Client* other);
|
||||||
void LinkDead();
|
void LinkDead();
|
||||||
void Insight(uint32 t_id);
|
void Insight(uint32 t_id);
|
||||||
bool CheckDoubleAttack(bool tripleAttack = false);
|
bool CheckDoubleAttack();
|
||||||
|
bool CheckTripleAttack();
|
||||||
bool CheckDoubleRangedAttack();
|
bool CheckDoubleRangedAttack();
|
||||||
|
bool CheckDualWield();
|
||||||
|
|
||||||
//remove charges/multiple objects from inventory:
|
//remove charges/multiple objects from inventory:
|
||||||
//bool DecreaseByType(uint32 type, uint8 amt);
|
//bool DecreaseByType(uint32 type, uint8 amt);
|
||||||
@ -1157,6 +1149,7 @@ public:
|
|||||||
void RemoveAutoXTargets();
|
void RemoveAutoXTargets();
|
||||||
void ShowXTargets(Client *c);
|
void ShowXTargets(Client *c);
|
||||||
bool GroupFollow(Client* inviter);
|
bool GroupFollow(Client* inviter);
|
||||||
|
inline bool GetRunMode() const { return runmode; }
|
||||||
|
|
||||||
void InitializeMercInfo();
|
void InitializeMercInfo();
|
||||||
bool CheckCanSpawnMerc(uint32 template_id);
|
bool CheckCanSpawnMerc(uint32 template_id);
|
||||||
@ -1260,6 +1253,9 @@ public:
|
|||||||
void QuestReward(Mob* target, uint32 copper = 0, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0, uint32 itemid = 0, uint32 exp = 0, bool faction = false);
|
void QuestReward(Mob* target, uint32 copper = 0, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0, uint32 itemid = 0, uint32 exp = 0, bool faction = false);
|
||||||
|
|
||||||
void ResetHPUpdateTimer() { hpupdate_timer.Start(); }
|
void ResetHPUpdateTimer() { hpupdate_timer.Start(); }
|
||||||
|
|
||||||
|
void SendHPUpdateMarquee();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Mob;
|
friend class Mob;
|
||||||
void CalcItemBonuses(StatBonuses* newbon);
|
void CalcItemBonuses(StatBonuses* newbon);
|
||||||
@ -1267,8 +1263,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;
|
||||||
@ -1276,6 +1270,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;
|
||||||
@ -1385,6 +1381,7 @@ private:
|
|||||||
bool AFK;
|
bool AFK;
|
||||||
bool auto_attack;
|
bool auto_attack;
|
||||||
bool auto_fire;
|
bool auto_fire;
|
||||||
|
bool runmode;
|
||||||
uint8 gmspeed;
|
uint8 gmspeed;
|
||||||
bool medding;
|
bool medding;
|
||||||
uint16 horseId;
|
uint16 horseId;
|
||||||
@ -1492,11 +1489,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;
|
||||||
}
|
}
|
||||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
if (!RuleB(Character, UseSpellFileSongCap))
|
||||||
|
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(
|
else {
|
||||||
"SELECT "
|
m_pp.expansions = RuleI(World, ExpansionSettings);
|
||||||
"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++){
|
|
||||||
uint32 id = aa[a]->AA;
|
|
||||||
//watch for invalid AA IDs
|
|
||||||
if (id == aaNone)
|
|
||||||
continue;
|
|
||||||
if (id >= aaHighestID) {
|
|
||||||
aa[a]->AA = aaNone;
|
|
||||||
aa[a]->value = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (aa[a]->value == 0) {
|
|
||||||
aa[a]->AA = aaNone;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (aa[a]->value > HIGHEST_AA_VALUE) {
|
|
||||||
aa[a]->AA = aaNone;
|
|
||||||
aa[a]->value = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aa[a]->value > 1) /* hack in some stuff for sony's new AA method (where each level of each aa.has a seperate ID) */
|
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 */
|
||||||
@ -6056,7 +6008,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app)
|
|||||||
char *escSearchString = new char[129];
|
char *escSearchString = new char[129];
|
||||||
database.DoEscapeString(escSearchString, gmscs->Name, strlen(gmscs->Name));
|
database.DoEscapeString(escSearchString, gmscs->Name, strlen(gmscs->Name));
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT charname, zoneid, x, y, z, time_of_death, rezzed, IsBurried "
|
std::string query = StringFormat("SELECT charname, zoneid, x, y, z, time_of_death, is_rezzed, is_buried "
|
||||||
"FROM character_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i",
|
"FROM character_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i",
|
||||||
escSearchString, maxResults);
|
escSearchString, maxResults);
|
||||||
safe_delete_array(escSearchString);
|
safe_delete_array(escSearchString);
|
||||||
@ -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);
|
||||||
@ -11836,6 +11788,18 @@ void Client::Handle_OP_SetGuildMOTD(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_OP_SetRunMode(const EQApplicationPacket *app)
|
void Client::Handle_OP_SetRunMode(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
|
if (app->size < sizeof(SetRunMode_Struct)) {
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Received invalid sized "
|
||||||
|
"OP_SetRunMode: got %d, expected %d", app->size,
|
||||||
|
sizeof(SetRunMode_Struct));
|
||||||
|
DumpPacket(app);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetRunMode_Struct* rms = (SetRunMode_Struct*)app->pBuffer;
|
||||||
|
if (rms->mode)
|
||||||
|
runmode = true;
|
||||||
|
else
|
||||||
|
runmode = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14216,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))
|
||||||
|
entity_list.AEAttack(this, 30);
|
||||||
CheckIncreaseSkill(SkillDoubleAttack, auto_attack_target, -10);
|
|
||||||
if(CheckDoubleAttack()) {
|
|
||||||
//should we allow rampage on double attack?
|
|
||||||
if(CheckAAEffect(aaEffectRampage)) {
|
|
||||||
entity_list.AEAttack(this, 30);
|
|
||||||
} else {
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//triple attack: rangers, monks, warriors, berserkers over level 60
|
|
||||||
if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
|
|
||||||
&& GetLevel() >= 60) || GetSpecialAbility(SPECATK_TRIPLE))
|
|
||||||
&& CheckDoubleAttack(true))
|
|
||||||
{
|
|
||||||
tripleAttackSuccess = true;
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//quad attack, does this belong here??
|
|
||||||
if(GetSpecialAbility(SPECATK_QUAD) && CheckDoubleAttack(true))
|
|
||||||
{
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Live AA - Flurry, Rapid Strikes ect (Flurry does not require Triple Attack).
|
|
||||||
int16 flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
|
||||||
|
|
||||||
if (auto_attack_target && flurrychance)
|
|
||||||
{
|
|
||||||
if(zone->random.Int(0, 99) < flurrychance)
|
|
||||||
{
|
|
||||||
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
|
|
||||||
|
|
||||||
if (auto_attack_target && ExtraAttackChanceBonus) {
|
|
||||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
|
||||||
if(wpn){
|
|
||||||
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
|
|
||||||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
|
||||||
wpn->GetItem()->ItemType == ItemType2HPiercing )
|
|
||||||
{
|
|
||||||
if(zone->random.Int(0, 99) < ExtraAttackChanceBonus)
|
|
||||||
{
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,32 +428,12 @@ bool Client::Process() {
|
|||||||
//you can't see your target
|
//you can't see your target
|
||||||
}
|
}
|
||||||
else if(auto_attack_target->GetHP() > -10) {
|
else if(auto_attack_target->GetHP() > -10) {
|
||||||
float DualWieldProbability = 0.0f;
|
|
||||||
|
|
||||||
int16 Ambidexterity = aabonuses.Ambidexterity + spellbonuses.Ambidexterity + itembonuses.Ambidexterity;
|
|
||||||
DualWieldProbability = (GetSkill(SkillDualWield) + GetLevel() + Ambidexterity) / 400.0f; // 78.0 max
|
|
||||||
int16 DWBonus = spellbonuses.DualWieldChance + itembonuses.DualWieldChance;
|
|
||||||
DualWieldProbability += DualWieldProbability*float(DWBonus)/ 100.0f;
|
|
||||||
|
|
||||||
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 (CheckDualWield()) {
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -522,9 +441,7 @@ bool Client::Process() {
|
|||||||
if (position_timer.Check()) {
|
if (position_timer.Check()) {
|
||||||
if (IsAIControlled())
|
if (IsAIControlled())
|
||||||
{
|
{
|
||||||
if(IsMoving())
|
if(!IsMoving())
|
||||||
SendPosUpdate(2);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
animation = 0;
|
animation = 0;
|
||||||
m_Delta = glm::vec4(0.0f, 0.0f, 0.0f, m_Delta.w);
|
m_Delta = glm::vec4(0.0f, 0.0f, 0.0f, m_Delta.w);
|
||||||
|
|||||||
284
zone/command.cpp
284
zone/command.cpp
@ -147,7 +147,7 @@ Access Levels:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int command_init(void) {
|
int command_init(void) {
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
|
|
||||||
@ -168,10 +168,10 @@ 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) ||
|
||||||
|
command_add("aug", nullptr, 250, command_augmentitem) ||
|
||||||
command_add("ban", "[name] [reason]- Ban by character name", 150, command_ban) ||
|
command_add("ban", "[name] [reason]- Ban by character name", 150, command_ban) ||
|
||||||
command_add("beard", "- Change the beard of your target", 80, command_beard) ||
|
command_add("beard", "- Change the beard of your target", 80, command_beard) ||
|
||||||
command_add("beardcolor", "- Change the beard color of your target", 80, command_beardcolor) ||
|
command_add("beardcolor", "- Change the beard color of your target", 80, command_beardcolor) ||
|
||||||
@ -218,11 +218,14 @@ int command_init(void) {
|
|||||||
command_add("flagedit", "- Edit zone flags on your target", 100, command_flagedit) ||
|
command_add("flagedit", "- Edit zone flags on your target", 100, command_flagedit) ||
|
||||||
command_add("flags", "- displays the flags of you or your target", 0, command_flags) ||
|
command_add("flags", "- displays the flags of you or your target", 0, command_flags) ||
|
||||||
command_add("flymode", "[0/1/2] - Set your or your player target's flymode to off/on/levitate", 50, command_flymode) ||
|
command_add("flymode", "[0/1/2] - Set your or your player target's flymode to off/on/levitate", 50, command_flymode) ||
|
||||||
|
command_add("fn", nullptr, 100, command_findnpctype) ||
|
||||||
command_add("fov", "- Check wether you're behind or in your target's field of view", 80, command_fov) ||
|
command_add("fov", "- Check wether you're behind or in your target's field of view", 80, command_fov) ||
|
||||||
command_add("freeze", "- Freeze your target", 80, command_freeze) ||
|
command_add("freeze", "- Freeze your target", 80, command_freeze) ||
|
||||||
|
command_add("fs", nullptr, 50, command_findspell) ||
|
||||||
|
command_add("fz", nullptr, 100, command_findzone) ||
|
||||||
command_add("gassign", "[id] - Assign targetted NPC to predefined wandering grid id", 100, command_gassign) ||
|
command_add("gassign", "[id] - Assign targetted NPC to predefined wandering grid id", 100, command_gassign) ||
|
||||||
command_add("gender", "[0/1/2] - Change your or your target's gender to male/female/neuter", 50, command_gender) ||
|
command_add("gender", "[0/1/2] - Change your or your target's gender to male/female/neuter", 50, command_gender) ||
|
||||||
command_add("getplayerburriedcorpsecount", "- Get the target's total number of burried player corpses.", 100, command_getplayerburriedcorpsecount) ||
|
command_add("getplayerburiedcorpsecount", "- Get the target's total number of buried player corpses.", 100, command_getplayerburiedcorpsecount) ||
|
||||||
command_add("getvariable", "[varname] - Get the value of a variable from the database", 200, command_getvariable) ||
|
command_add("getvariable", "[varname] - Get the value of a variable from the database", 200, command_getvariable) ||
|
||||||
command_add("gi", nullptr,200, command_giveitem) ||
|
command_add("gi", nullptr,200, command_giveitem) ||
|
||||||
command_add("ginfo", "- get group info on target.", 20, command_ginfo) ||
|
command_add("ginfo", "- get group info on target.", 20, command_ginfo) ||
|
||||||
@ -275,7 +278,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) ||
|
||||||
@ -324,6 +326,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) ||
|
||||||
@ -336,8 +339,10 @@ 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("rq", nullptr, 150, command_reloadqst) ||
|
||||||
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) ||
|
||||||
command_add("scribespell", "[spellid] - Scribe specified spell in your target's spell book.", 180, command_scribespell) ||
|
command_add("scribespell", "[spellid] - Scribe specified spell in your target's spell book.", 180, command_scribespell) ||
|
||||||
@ -386,7 +391,7 @@ int command_init(void) {
|
|||||||
command_add("spon", "- Sends OP_MemorizeSpell", 80, command_spon) ||
|
command_add("spon", "- Sends OP_MemorizeSpell", 80, command_spon) ||
|
||||||
command_add("stun", "[duration] - Stuns you or your target for duration", 100, command_stun) ||
|
command_add("stun", "[duration] - Stuns you or your target for duration", 100, command_stun) ||
|
||||||
command_add("summon", "[charname] - Summons your player/npc/corpse target, or charname if specified", 80, command_summon) ||
|
command_add("summon", "[charname] - Summons your player/npc/corpse target, or charname if specified", 80, command_summon) ||
|
||||||
command_add("summonburriedplayercorpse", "- Summons the target's oldest burried corpse, if any exist.", 100, command_summonburriedplayercorpse) ||
|
command_add("summonburiedplayercorpse", "- Summons the target's oldest buried corpse, if any exist.", 100, command_summonburiedplayercorpse) ||
|
||||||
command_add("summonitem", "[itemid] [charges] - Summon an item onto your cursor. Charges are optional.", 200, command_summonitem) ||
|
command_add("summonitem", "[itemid] [charges] - Summon an item onto your cursor. Charges are optional.", 200, command_summonitem) ||
|
||||||
command_add("suspend", "[name] [days] [reason] - Suspend by character name and for specificed number of days", 150, command_suspend) ||
|
command_add("suspend", "[name] [days] [reason] - Suspend by character name and for specificed number of days", 150, command_suspend) ||
|
||||||
command_add("task", "(subcommand) - Task system commands", 150, command_task) ||
|
command_add("task", "(subcommand) - Task system commands", 150, command_task) ||
|
||||||
@ -431,7 +436,7 @@ int command_init(void) {
|
|||||||
command_add("zsave", " - Saves zheader to the database", 80, command_zsave) ||
|
command_add("zsave", " - Saves zheader to the database", 80, command_zsave) ||
|
||||||
command_add("zsky", "[skytype] - Change zone sky type", 80, command_zsky) ||
|
command_add("zsky", "[skytype] - Change zone sky type", 80, command_zsky) ||
|
||||||
command_add("zstats", "- Show info about zone header", 80, command_zstats) ||
|
command_add("zstats", "- Show info about zone header", 80, command_zstats) ||
|
||||||
command_add("zunderworld", "[zcoord] - Sets the underworld using zcoord", 80, command_zunderworld) ||
|
command_add("zunderworld", "[zcoord] - Sets the underworld using zcoord", 80, command_zunderworld) ||
|
||||||
command_add("zuwcoords", "[z coord] - Set underworld coord", 80, command_zuwcoords)
|
command_add("zuwcoords", "[z coord] - Set underworld coord", 80, command_zuwcoords)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -641,8 +646,8 @@ void command_logcommand(Client *c, const char *message)
|
|||||||
c->AccountName(),
|
c->AccountName(),
|
||||||
c->AccountID(),
|
c->AccountID(),
|
||||||
admin,c->GetName(),
|
admin,c->GetName(),
|
||||||
c->GetTarget()?c->GetTarget()->GetName():"None",
|
c->GetTarget()?c->GetTarget()->GetName():"None",
|
||||||
"Command",
|
"Command",
|
||||||
message,
|
message,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
@ -675,8 +680,8 @@ 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());
|
||||||
}
|
}
|
||||||
@ -728,7 +733,7 @@ void command_setfaction(Client *c, const Seperator *sep)
|
|||||||
auto npcTypeID = c->GetTarget()->CastToNPC()->GetNPCTypeID();
|
auto npcTypeID = c->GetTarget()->CastToNPC()->GetNPCTypeID();
|
||||||
c->Message(15,"Setting NPC %u to faction %i", npcTypeID, atoi(sep->argplus[1]));
|
c->Message(15,"Setting NPC %u to faction %i", npcTypeID, atoi(sep->argplus[1]));
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE npc_types SET npc_faction_id = %i WHERE id = %i",
|
std::string query = StringFormat("UPDATE npc_types SET npc_faction_id = %i WHERE id = %i",
|
||||||
atoi(sep->argplus[1]), npcTypeID);
|
atoi(sep->argplus[1]), npcTypeID);
|
||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
}
|
}
|
||||||
@ -1486,7 +1491,7 @@ void command_npcstats(Client *c, const Seperator *sep)
|
|||||||
c->Message(0, "Current HP: %i Max HP: %i", c->GetTarget()->GetHP(), c->GetTarget()->GetMaxHP());
|
c->Message(0, "Current HP: %i Max HP: %i", c->GetTarget()->GetHP(), c->GetTarget()->GetMaxHP());
|
||||||
//c->Message(0, "Weapon Item Number: %s", c->GetTarget()->GetWeapNo());
|
//c->Message(0, "Weapon Item Number: %s", c->GetTarget()->GetWeapNo());
|
||||||
c->Message(0, "Gender: %i Size: %f Bodytype: %d", c->GetTarget()->GetGender(), c->GetTarget()->GetSize(), c->GetTarget()->GetBodyType());
|
c->Message(0, "Gender: %i Size: %f Bodytype: %d", c->GetTarget()->GetGender(), c->GetTarget()->GetSize(), c->GetTarget()->GetBodyType());
|
||||||
c->Message(0, "Runspeed: %i Walkspeed: %i", c->GetTarget()->GetRunspeed(), c->GetTarget()->GetWalkspeed());
|
c->Message(0, "Runspeed: %.3f Walkspeed: %.3f", static_cast<float>(0.025f * c->GetTarget()->GetRunspeed()), static_cast<float>(0.025f * c->GetTarget()->GetWalkspeed()));
|
||||||
c->Message(0, "Spawn Group: %i Grid: %i", c->GetTarget()->CastToNPC()->GetSp2(), c->GetTarget()->CastToNPC()->GetGrid());
|
c->Message(0, "Spawn Group: %i Grid: %i", c->GetTarget()->CastToNPC()->GetSp2(), c->GetTarget()->CastToNPC()->GetGrid());
|
||||||
c->Message(0, "EmoteID: %i", c->GetTarget()->CastToNPC()->GetEmoteID());
|
c->Message(0, "EmoteID: %i", c->GetTarget()->CastToNPC()->GetEmoteID());
|
||||||
c->GetTarget()->CastToNPC()->QueryLoot(c);
|
c->GetTarget()->CastToNPC()->QueryLoot(c);
|
||||||
@ -2299,7 +2304,7 @@ void command_setskill(Client *c, const Seperator *sep)
|
|||||||
Log.Out(Logs::General, Logs::Normal, "Set skill request from %s, target:%s skill_id:%i value:%i", c->GetName(), c->GetTarget()->GetName(), atoi(sep->arg[1]), atoi(sep->arg[2]) );
|
Log.Out(Logs::General, Logs::Normal, "Set skill request from %s, target:%s skill_id:%i value:%i", c->GetName(), c->GetTarget()->GetName(), atoi(sep->arg[1]), atoi(sep->arg[2]) );
|
||||||
int skill_num = atoi(sep->arg[1]);
|
int skill_num = atoi(sep->arg[1]);
|
||||||
uint16 skill_value = atoi(sep->arg[2]);
|
uint16 skill_value = atoi(sep->arg[2]);
|
||||||
if(skill_num < HIGHEST_SKILL)
|
if(skill_num <= HIGHEST_SKILL)
|
||||||
c->GetTarget()->CastToClient()->SetSkill((SkillUseTypes)skill_num, skill_value);
|
c->GetTarget()->CastToClient()->SetSkill((SkillUseTypes)skill_num, skill_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2570,7 +2575,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2581,7 +2586,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
MainPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
MainPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2593,7 +2598,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
||||||
@ -2603,7 +2608,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2615,7 +2620,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
MainCursor, 0, item_link.c_str(), 0);
|
MainCursor, 0, item_link.c_str(), 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2627,7 +2632,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i",
|
||||||
MainCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
MainCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = SUB_BEGIN; (cursorDepth == 0) && inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
for (uint8 indexSub = SUB_BEGIN; (cursorDepth == 0) && inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
||||||
@ -2637,7 +2642,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
Inventory::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
Inventory::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2652,7 +2657,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "TributeSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "TributeSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2664,7 +2669,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
||||||
@ -2674,7 +2679,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2685,8 +2690,8 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
||||||
@ -2696,7 +2701,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2709,7 +2714,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
||||||
@ -2719,7 +2724,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2741,7 +2746,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
(EmuConstants::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
(EmuConstants::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
|
||||||
@ -2751,7 +2756,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
item_link = linker.GenerateLink();
|
item_link = linker.GenerateLink();
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
INVALID_INDEX, indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
INVALID_INDEX, indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3749,7 +3754,7 @@ void command_spellinfo(Client *c, const Seperator *sep)
|
|||||||
c->Message(0, " zonetype: %d", s->zonetype);
|
c->Message(0, " zonetype: %d", s->zonetype);
|
||||||
c->Message(0, " EnvironmentType: %d", s->EnvironmentType);
|
c->Message(0, " EnvironmentType: %d", s->EnvironmentType);
|
||||||
c->Message(0, " TimeOfDay: %d", s->TimeOfDay);
|
c->Message(0, " TimeOfDay: %d", s->TimeOfDay);
|
||||||
c->Message(0, " classes[15]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
|
c->Message(0, " classes[15]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
|
||||||
s->classes[0], s->classes[1], s->classes[2], s->classes[3], s->classes[4],
|
s->classes[0], s->classes[1], s->classes[2], s->classes[3], s->classes[4],
|
||||||
s->classes[5], s->classes[6], s->classes[7], s->classes[8], s->classes[9],
|
s->classes[5], s->classes[6], s->classes[7], s->classes[8], s->classes[9],
|
||||||
s->classes[10], s->classes[11], s->classes[12], s->classes[13], s->classes[14]);
|
s->classes[10], s->classes[11], s->classes[12], s->classes[13], s->classes[14]);
|
||||||
@ -3879,7 +3884,7 @@ void command_repop(Client *c, const Seperator *sep)
|
|||||||
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
while (iterator.MoreElements()) {
|
while (iterator.MoreElements()) {
|
||||||
std::string query = StringFormat("DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
|
std::string query = StringFormat("DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
|
||||||
(unsigned long)iterator.GetData()->GetID(),
|
(unsigned long)iterator.GetData()->GetID(),
|
||||||
(unsigned long)zone->GetInstanceID());
|
(unsigned long)zone->GetInstanceID());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
@ -4253,7 +4258,7 @@ void command_spawnfix(Client *c, const Seperator *sep) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE spawn2 SET x = '%f', y = '%f', z = '%f', heading = '%f' WHERE id = '%i'",
|
std::string query = StringFormat("UPDATE spawn2 SET x = '%f', y = '%f', z = '%f', heading = '%f' WHERE id = '%i'",
|
||||||
c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(),s2->GetID());
|
c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(),s2->GetID());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@ -4396,11 +4401,11 @@ void command_time(Client *c, const Seperator *sep)
|
|||||||
c->Message(13, "To set the Time: #time HH [MM]");
|
c->Message(13, "To set the Time: #time HH [MM]");
|
||||||
TimeOfDay_Struct eqTime;
|
TimeOfDay_Struct eqTime;
|
||||||
zone->zone_time.GetCurrentEQTimeOfDay( time(0), &eqTime);
|
zone->zone_time.GetCurrentEQTimeOfDay( time(0), &eqTime);
|
||||||
sprintf(timeMessage,"%02d:%s%d %s (Timezone: %ih %im)",
|
sprintf(timeMessage,"%02d:%s%d %s (Timezone: %ih %im)",
|
||||||
((eqTime.hour - 1) % 12) == 0 ? 12 : ((eqTime.hour - 1) % 12),
|
((eqTime.hour - 1) % 12) == 0 ? 12 : ((eqTime.hour - 1) % 12),
|
||||||
(eqTime.minute < 10) ? "0" : "",
|
(eqTime.minute < 10) ? "0" : "",
|
||||||
eqTime.minute,
|
eqTime.minute,
|
||||||
(eqTime.hour >= 13) ? "pm" : "am",
|
(eqTime.hour >= 13) ? "pm" : "am",
|
||||||
zone->zone_time.getEQTimeZoneHr(),
|
zone->zone_time.getEQTimeZoneHr(),
|
||||||
zone->zone_time.getEQTimeZoneMin()
|
zone->zone_time.getEQTimeZoneMin()
|
||||||
);
|
);
|
||||||
@ -4842,36 +4847,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))
|
||||||
@ -5586,16 +5561,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5754,7 +5736,7 @@ void command_suspend(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE `account` SET `suspendeduntil` = DATE_ADD(NOW(), INTERVAL %i DAY), "
|
std::string query = StringFormat("UPDATE `account` SET `suspendeduntil` = DATE_ADD(NOW(), INTERVAL %i DAY), "
|
||||||
"suspend_reason = '%s' WHERE `id` = %i",
|
"suspend_reason = '%s' WHERE `id` = %i",
|
||||||
duration, EscapeString(message).c_str(), accountID);
|
duration, EscapeString(message).c_str(), accountID);
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
|
|
||||||
@ -6226,21 +6208,21 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(sep->arg[1], "meleetype") == 0) {
|
if (strcasecmp(sep->arg[1], "meleetype") == 0) {
|
||||||
c->Message(15,"NPCID %u now has a primary melee type of %i and a secondary melee type of %i.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3]));
|
c->Message(15,"NPCID %u now has a primary melee type of %i and a secondary melee type of %i.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3]));
|
||||||
std::string query = StringFormat("UPDATE npc_types SET prim_melee_type = %i, sec_melee_type = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), npcTypeID);
|
std::string query = StringFormat("UPDATE npc_types SET prim_melee_type = %i, sec_melee_type = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), npcTypeID);
|
||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(sep->arg[1], "rangedtype") == 0) {
|
if (strcasecmp(sep->arg[1], "rangedtype") == 0) {
|
||||||
c->Message(15,"NPCID %u now has a ranged type of %i.", npcTypeID, atoi(sep->argplus[2]));
|
c->Message(15,"NPCID %u now has a ranged type of %i.", npcTypeID, atoi(sep->argplus[2]));
|
||||||
std::string query = StringFormat("UPDATE npc_types SET rangedtype = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID);
|
std::string query = StringFormat("UPDATE npc_types SET rangedtype = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID);
|
||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(sep->arg[1], "ammoidfile") == 0) {
|
if (strcasecmp(sep->arg[1], "ammoidfile") == 0) {
|
||||||
c->Message(15,"NPCID %u's ammo id file is now %i", npcTypeID, atoi(sep->argplus[2]));
|
c->Message(15,"NPCID %u's ammo id file is now %i", npcTypeID, atoi(sep->argplus[2]));
|
||||||
std::string query = StringFormat("UPDATE npc_types SET ammoidfile = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID);
|
std::string query = StringFormat("UPDATE npc_types SET ammoidfile = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID);
|
||||||
@ -6275,7 +6257,7 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(sep->arg[1], "walkspeed") == 0) {
|
if (strcasecmp(sep->arg[1], "walkspeed") == 0) {
|
||||||
c->Message(15,"NPCID %u now walks at %f", npcTypeID, atof(sep->argplus[2]));
|
c->Message(15,"NPCID %u now walks at %f", npcTypeID, atof(sep->argplus[2]));
|
||||||
std::string query = StringFormat("UPDATE npc_types SET walkspeed = %f WHERE id = %i", atof(sep->argplus[2]), npcTypeID);
|
std::string query = StringFormat("UPDATE npc_types SET walkspeed = %f WHERE id = %i", atof(sep->argplus[2]), npcTypeID);
|
||||||
@ -6429,7 +6411,7 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(sep->arg[1], "Avoidance") == 0) {
|
if (strcasecmp(sep->arg[1], "Avoidance") == 0) {
|
||||||
c->Message(15,"NPCID %u now has %i Avoidance.", npcTypeID, atoi(sep->argplus[2]));
|
c->Message(15,"NPCID %u now has %i Avoidance.", npcTypeID, atoi(sep->argplus[2]));
|
||||||
std::string query = StringFormat("UPDATE npc_types SET avoidance = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID);
|
std::string query = StringFormat("UPDATE npc_types SET avoidance = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID);
|
||||||
@ -6485,7 +6467,7 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(sep->arg[1], "Attackcount") == 0) {
|
if (strcasecmp(sep->arg[1], "Attackcount") == 0) {
|
||||||
c->Message(15,"NPCID %u now has attack_count set to %i", npcTypeID,atoi(sep->arg[2]));
|
c->Message(15,"NPCID %u now has attack_count set to %i", npcTypeID,atoi(sep->arg[2]));
|
||||||
std::string query = StringFormat("UPDATE npc_types SET attack_count = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID);
|
std::string query = StringFormat("UPDATE npc_types SET attack_count = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID);
|
||||||
@ -6522,7 +6504,7 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
"luclin_hairstyle = %i, luclin_beard = %i, "
|
"luclin_hairstyle = %i, luclin_beard = %i, "
|
||||||
"face = %i, drakkin_heritage = %i, "
|
"face = %i, drakkin_heritage = %i, "
|
||||||
"drakkin_tattoo = %i, drakkin_details = %i "
|
"drakkin_tattoo = %i, drakkin_details = %i "
|
||||||
"WHERE id = %i",
|
"WHERE id = %i",
|
||||||
target->GetHairColor(), target->GetBeardColor(),
|
target->GetHairColor(), target->GetBeardColor(),
|
||||||
target->GetHairStyle(), target->GetBeard(),
|
target->GetHairStyle(), target->GetBeard(),
|
||||||
target->GetLuclinFace(), target->GetDrakkinHeritage(),
|
target->GetLuclinFace(), target->GetDrakkinHeritage(),
|
||||||
@ -6608,7 +6590,7 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(sep->arg[1], "slow_mitigation") == 0) {
|
if (strcasecmp(sep->arg[1], "slow_mitigation") == 0) {
|
||||||
c->Message(15, "NPCID %u's slow mitigation limit is now %i.", npcTypeID, atoi(sep->arg[2]));
|
c->Message(15, "NPCID %u's slow mitigation limit is now %i.", npcTypeID, atoi(sep->arg[2]));
|
||||||
std::string query = StringFormat("UPDATE npc_types SET slow_mitigation = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID);
|
std::string query = StringFormat("UPDATE npc_types SET slow_mitigation = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID);
|
||||||
@ -6663,7 +6645,7 @@ void command_qglobal(Client *c, const Seperator *sep) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!strcasecmp(sep->arg[1], "on")) {
|
if(!strcasecmp(sep->arg[1], "on")) {
|
||||||
std::string query = StringFormat("UPDATE npc_types SET qglobal = 1 WHERE id = '%i'",
|
std::string query = StringFormat("UPDATE npc_types SET qglobal = 1 WHERE id = '%i'",
|
||||||
target->GetNPCTypeID());
|
target->GetNPCTypeID());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if(!results.Success()) {
|
if(!results.Success()) {
|
||||||
@ -6676,7 +6658,7 @@ void command_qglobal(Client *c, const Seperator *sep) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!strcasecmp(sep->arg[1], "off")) {
|
if(!strcasecmp(sep->arg[1], "off")) {
|
||||||
std::string query = StringFormat("UPDATE npc_types SET qglobal = 0 WHERE id = '%i'",
|
std::string query = StringFormat("UPDATE npc_types SET qglobal = 0 WHERE id = '%i'",
|
||||||
target->GetNPCTypeID());
|
target->GetNPCTypeID());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if(!results.Success()) {
|
if(!results.Success()) {
|
||||||
@ -7072,13 +7054,13 @@ void command_ginfo(Client *c, const Seperator *sep)
|
|||||||
if(g->membername[r][0] == '\0')
|
if(g->membername[r][0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
c->Message(0, "...Zoned Member: %s, Roles: %s %s %s", g->membername[r],
|
c->Message(0, "...Zoned Member: %s, Roles: %s %s %s", g->membername[r],
|
||||||
(g->MemberRoles[r] & RoleAssist) ? "Assist" : "",
|
(g->MemberRoles[r] & RoleAssist) ? "Assist" : "",
|
||||||
(g->MemberRoles[r] & RoleTank) ? "Tank" : "",
|
(g->MemberRoles[r] & RoleTank) ? "Tank" : "",
|
||||||
(g->MemberRoles[r] & RolePuller) ? "Puller" : "");
|
(g->MemberRoles[r] & RolePuller) ? "Puller" : "");
|
||||||
} else {
|
} else {
|
||||||
c->Message(0, "...In-Zone Member: %s (0x%x) Roles: %s %s %s", g->membername[r], g->members[r],
|
c->Message(0, "...In-Zone Member: %s (0x%x) Roles: %s %s %s", g->membername[r], g->members[r],
|
||||||
(g->MemberRoles[r] & RoleAssist) ? "Assist" : "",
|
(g->MemberRoles[r] & RoleAssist) ? "Assist" : "",
|
||||||
(g->MemberRoles[r] & RoleTank) ? "Tank" : "",
|
(g->MemberRoles[r] & RoleTank) ? "Tank" : "",
|
||||||
(g->MemberRoles[r] & RolePuller) ? "Puller" : "");
|
(g->MemberRoles[r] & RolePuller) ? "Puller" : "");
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -7241,7 +7223,7 @@ void command_flagedit(Client *c, const Seperator *sep) {
|
|||||||
flag_name[127] = '\0';
|
flag_name[127] = '\0';
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE zone SET flag_needed = '%s' "
|
std::string query = StringFormat("UPDATE zone SET flag_needed = '%s' "
|
||||||
"WHERE zoneidnumber = %d AND version = %d",
|
"WHERE zoneidnumber = %d AND version = %d",
|
||||||
flag_name, zoneid, zone->GetInstanceVersion());
|
flag_name, zoneid, zone->GetInstanceVersion());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if(!results.Success()) {
|
if(!results.Success()) {
|
||||||
@ -7268,7 +7250,7 @@ void command_flagedit(Client *c, const Seperator *sep) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE zone SET flag_needed = '' "
|
std::string query = StringFormat("UPDATE zone SET flag_needed = '' "
|
||||||
"WHERE zoneidnumber = %d AND version = %d",
|
"WHERE zoneidnumber = %d AND version = %d",
|
||||||
zoneid, zone->GetInstanceVersion());
|
zoneid, zone->GetInstanceVersion());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if(!results.Success()) {
|
if(!results.Success()) {
|
||||||
@ -7678,56 +7660,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;
|
||||||
@ -7874,7 +7806,7 @@ void command_deletegraveyard(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_summonburriedplayercorpse(Client *c, const Seperator *sep)
|
void command_summonburiedplayercorpse(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
Client *t=c;
|
Client *t=c;
|
||||||
|
|
||||||
@ -7888,12 +7820,12 @@ void command_summonburriedplayercorpse(Client *c, const Seperator *sep)
|
|||||||
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetPosition());
|
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetPosition());
|
||||||
|
|
||||||
if(!PlayerCorpse)
|
if(!PlayerCorpse)
|
||||||
c->Message(0, "Your target doesn't have any burried corpses.");
|
c->Message(0, "Your target doesn't have any buried corpses.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_getplayerburriedcorpsecount(Client *c, const Seperator *sep)
|
void command_getplayerburiedcorpsecount(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
Client *t=c;
|
Client *t=c;
|
||||||
|
|
||||||
@ -7907,9 +7839,9 @@ void command_getplayerburriedcorpsecount(Client *c, const Seperator *sep)
|
|||||||
uint32 CorpseCount = database.GetCharacterBuriedCorpseCount(t->CharacterID());
|
uint32 CorpseCount = database.GetCharacterBuriedCorpseCount(t->CharacterID());
|
||||||
|
|
||||||
if(CorpseCount > 0)
|
if(CorpseCount > 0)
|
||||||
c->Message(0, "Your target has a total of %u burried corpses.", CorpseCount);
|
c->Message(0, "Your target has a total of %u buried corpses.", CorpseCount);
|
||||||
else
|
else
|
||||||
c->Message(0, "Your target doesn't have any burried corpses.");
|
c->Message(0, "Your target doesn't have any buried corpses.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -7950,7 +7882,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
std::string query = StringFormat("INSERT INTO spawngroup "
|
std::string query = StringFormat("INSERT INTO spawngroup "
|
||||||
"(name, spawn_limit, dist, max_x, min_x, max_y, min_y, delay) "
|
"(name, spawn_limit, dist, max_x, min_x, max_y, min_y, delay) "
|
||||||
"VALUES (\"%s\", %i, %f, %f, %f, %f, %f, %i)",
|
"VALUES (\"%s\", %i, %f, %f, %f, %f, %f, %i)",
|
||||||
sep->arg[2],
|
sep->arg[2],
|
||||||
(sep->arg[3]? atoi(sep->arg[3]): 0),
|
(sep->arg[3]? atoi(sep->arg[3]): 0),
|
||||||
(sep->arg[4]? atof(sep->arg[4]): 0),
|
(sep->arg[4]? atof(sep->arg[4]): 0),
|
||||||
@ -7977,7 +7909,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) "
|
std::string query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) "
|
||||||
"VALUES (%i, %i, %i)",
|
"VALUES (%i, %i, %i)",
|
||||||
atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]));
|
atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]));
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@ -7998,7 +7930,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE spawngroup SET dist = '%f', max_x = '%f', min_x = '%f', "
|
std::string query = StringFormat("UPDATE spawngroup SET dist = '%f', max_x = '%f', min_x = '%f', "
|
||||||
"max_y = '%f', min_y = '%f', delay = '%i' WHERE id = '%i'",
|
"max_y = '%f', min_y = '%f', delay = '%i' WHERE id = '%i'",
|
||||||
atof(sep->arg[3]), atof(sep->arg[4]), atof(sep->arg[5]),
|
atof(sep->arg[3]), atof(sep->arg[4]), atof(sep->arg[5]),
|
||||||
atof(sep->arg[6]), atof(sep->arg[7]), atoi(sep->arg[8]),
|
atof(sep->arg[6]), atof(sep->arg[7]), atoi(sep->arg[8]),
|
||||||
atoi(sep->arg[2]));
|
atoi(sep->arg[2]));
|
||||||
@ -8083,7 +8015,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE spawn2 SET x = '%f', y = '%f', z = '%f', heading = '%f' "
|
std::string query = StringFormat("UPDATE spawn2 SET x = '%f', y = '%f', z = '%f', heading = '%f' "
|
||||||
"WHERE id = '%i'",
|
"WHERE id = '%i'",
|
||||||
c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(),s2->GetID());
|
c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(),s2->GetID());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@ -8154,7 +8086,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
int16 version = atoi(sep->arg[2]);
|
int16 version = atoi(sep->arg[2]);
|
||||||
std::string query = StringFormat("UPDATE spawn2 SET version = %i "
|
std::string query = StringFormat("UPDATE spawn2 SET version = %i "
|
||||||
"WHERE spawngroupID = '%i'",
|
"WHERE spawngroupID = '%i'",
|
||||||
version, c->GetTarget()->CastToNPC()->GetSp2());
|
version, c->GetTarget()->CastToNPC()->GetSp2());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@ -10205,7 +10137,7 @@ void command_zopp(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
ItemInst* FakeItemInst = database.CreateItem(FakeItem, charges);
|
ItemInst* FakeItemInst = database.CreateItem(FakeItem, charges);
|
||||||
c->SendItemPacket(slotid, FakeItemInst, packettype);
|
c->SendItemPacket(slotid, FakeItemInst, packettype);
|
||||||
c->Message(0, "Sending zephyr op packet to client - [%s] %s (%u) with %i %s to slot %i.",
|
c->Message(0, "Sending zephyr op packet to client - [%s] %s (%u) with %i %s to slot %i.",
|
||||||
packettype == ItemPacketTrade ? "Trade" : "Summon", FakeItem->Name, itemid, charges,
|
packettype == ItemPacketTrade ? "Trade" : "Summon", FakeItem->Name, itemid, charges,
|
||||||
std::abs(charges == 1) ? "charge" : "charges", slotid);
|
std::abs(charges == 1) ? "charge" : "charges", slotid);
|
||||||
safe_delete(FakeItemInst);
|
safe_delete(FakeItemInst);
|
||||||
@ -10424,7 +10356,7 @@ void command_tune(Client *c, const Seperator *sep)
|
|||||||
ac_override = 0;
|
ac_override = 0;
|
||||||
if (!info_level)
|
if (!info_level)
|
||||||
info_level = 1;
|
info_level = 1;
|
||||||
|
|
||||||
if(!strcasecmp(sep->arg[2], "A"))
|
if(!strcasecmp(sep->arg[2], "A"))
|
||||||
c->Tune_FindATKByPctMitigation(defender, attacker, pct_mitigation, interval, max_loop,ac_override,info_level);
|
c->Tune_FindATKByPctMitigation(defender, attacker, pct_mitigation, interval, max_loop,ac_override,info_level);
|
||||||
else if(!strcasecmp(sep->arg[2], "B"))
|
else if(!strcasecmp(sep->arg[2], "B"))
|
||||||
@ -10459,7 +10391,7 @@ void command_tune(Client *c, const Seperator *sep)
|
|||||||
atk_override = 0;
|
atk_override = 0;
|
||||||
if (!info_level)
|
if (!info_level)
|
||||||
info_level = 1;
|
info_level = 1;
|
||||||
|
|
||||||
if(!strcasecmp(sep->arg[2], "A"))
|
if(!strcasecmp(sep->arg[2], "A"))
|
||||||
c->Tune_FindACByPctMitigation(defender, attacker, pct_mitigation, interval, max_loop,atk_override,info_level);
|
c->Tune_FindACByPctMitigation(defender, attacker, pct_mitigation, interval, max_loop,atk_override,info_level);
|
||||||
else if(!strcasecmp(sep->arg[2], "B"))
|
else if(!strcasecmp(sep->arg[2], "B"))
|
||||||
@ -10501,7 +10433,7 @@ void command_tune(Client *c, const Seperator *sep)
|
|||||||
c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit));
|
c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcasecmp(sep->arg[2], "A"))
|
if(!strcasecmp(sep->arg[2], "A"))
|
||||||
c->Tune_FindAccuaryByHitChance(defender, attacker, hit_chance, interval, max_loop,avoid_override,info_level);
|
c->Tune_FindAccuaryByHitChance(defender, attacker, hit_chance, interval, max_loop,avoid_override,info_level);
|
||||||
else if(!strcasecmp(sep->arg[2], "B"))
|
else if(!strcasecmp(sep->arg[2], "B"))
|
||||||
@ -10543,7 +10475,7 @@ void command_tune(Client *c, const Seperator *sep)
|
|||||||
c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit));
|
c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcasecmp(sep->arg[2], "A"))
|
if(!strcasecmp(sep->arg[2], "A"))
|
||||||
c->Tune_FindAvoidanceByHitChance(defender, attacker, hit_chance, interval, max_loop,acc_override, info_level);
|
c->Tune_FindAvoidanceByHitChance(defender, attacker, hit_chance, interval, max_loop,acc_override, info_level);
|
||||||
else if(!strcasecmp(sep->arg[2], "B"))
|
else if(!strcasecmp(sep->arg[2], "B"))
|
||||||
@ -10569,7 +10501,7 @@ void command_logtest(Client *c, const Seperator *sep){
|
|||||||
for (i = 0; i < atoi(sep->arg[1]); i++){
|
for (i = 0; i < atoi(sep->arg[1]); i++){
|
||||||
Log.Out(Logs::General, Logs::Debug, "[%u] Test #2... Took %f seconds", i, ((float)(std::clock() - t)) / CLOCKS_PER_SEC);
|
Log.Out(Logs::General, Logs::Debug, "[%u] Test #2... Took %f seconds", i, ((float)(std::clock() - t)) / CLOCKS_PER_SEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10625,7 +10557,7 @@ void command_logs(Client *c, const Seperator *sep){
|
|||||||
c->Message(15, "Your Log Settings have been applied");
|
c->Message(15, "Your Log Settings have been applied");
|
||||||
c->Message(15, "Output Method: %s :: Debug Level: %i - Category: %s", sep->arg[2], atoi(sep->arg[4]), Logs::LogCategoryName[atoi(sep->arg[3])]);
|
c->Message(15, "Output Method: %s :: Debug Level: %i - Category: %s", sep->arg[2], atoi(sep->arg[4]), Logs::LogCategoryName[atoi(sep->arg[3])]);
|
||||||
}
|
}
|
||||||
/* We use a general 'is_category_enabled' now, let's update when we update any output settings
|
/* We use a general 'is_category_enabled' now, let's update when we update any output settings
|
||||||
This is used in hot places of code to check if its enabled in any way before triggering logs
|
This is used in hot places of code to check if its enabled in any way before triggering logs
|
||||||
*/
|
*/
|
||||||
if (sep->arg[4] > 0){
|
if (sep->arg[4] > 0){
|
||||||
@ -10653,9 +10585,41 @@ void command_mysqltest(Client *c, const Seperator *sep)
|
|||||||
for (i = 0; i < atoi(sep->arg[1]); i++){
|
for (i = 0; i < atoi(sep->arg[1]); i++){
|
||||||
std::string query = "SELECT * FROM `zone`";
|
std::string query = "SELECT * FROM `zone`";
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_hotfix(Client *c, const Seperator *sep) {
|
void command_hotfix(Client *c, const Seperator *sep) {
|
||||||
|
|||||||
@ -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,13 +275,12 @@ 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);
|
||||||
void command_setgraveyard(Client *c, const Seperator *sep);
|
void command_setgraveyard(Client *c, const Seperator *sep);
|
||||||
void command_getplayerburriedcorpsecount(Client *c, const Seperator *sep);
|
void command_getplayerburiedcorpsecount(Client *c, const Seperator *sep);
|
||||||
void command_summonburriedplayercorpse(Client *c, const Seperator *sep);
|
void command_summonburiedplayercorpse(Client *c, const Seperator *sep);
|
||||||
void command_unscribespell(Client *c, const Seperator *sep);
|
void command_unscribespell(Client *c, const Seperator *sep);
|
||||||
void command_scribespell(Client *c, const Seperator *sep);
|
void command_scribespell(Client *c, const Seperator *sep);
|
||||||
void command_refreshgroup(Client *c, const Seperator *sep);
|
void command_refreshgroup(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);
|
||||||
void command_hotfix(Client *c, const Seperator *sep);
|
void command_hotfix(Client *c, const Seperator *sep);
|
||||||
|
|
||||||
#ifdef EQPROFILE
|
#ifdef EQPROFILE
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -835,7 +835,7 @@ bool Corpse::Process() {
|
|||||||
Save();
|
Save();
|
||||||
player_corpse_depop = true;
|
player_corpse_depop = true;
|
||||||
corpse_db_id = 0;
|
corpse_db_id = 0;
|
||||||
Log.Out(Logs::General, Logs::None, "Tagged %s player corpse has burried.", this->GetName());
|
Log.Out(Logs::General, Logs::None, "Tagged %s player corpse has buried.", this->GetName());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.Out(Logs::General, Logs::Error, "Unable to bury %s player corpse.", this->GetName());
|
Log.Out(Logs::General, Logs::Error, "Unable to bury %s player corpse.", this->GetName());
|
||||||
|
|||||||
@ -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)
|
||||||
) {
|
) {
|
||||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
if (!attacker->IsClient() || attacker->GetClass() == MONK || attacker->GetClass() == RANGER)
|
||||||
|
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||||
|
else
|
||||||
|
attacker->CastToClient()->DoAttackRounds(curmob, Hand, IsFromSpell);
|
||||||
hit++;
|
hit++;
|
||||||
if (count != 0 && hit >= count)
|
if (count != 0 && hit >= count)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1748,18 +1748,18 @@ XS(XS__clear_zone_flag)
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
XS(XS__summonburriedplayercorpse);
|
XS(XS__summonburiedplayercorpse);
|
||||||
XS(XS__summonburriedplayercorpse)
|
XS(XS__summonburiedplayercorpse)
|
||||||
{
|
{
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
if (items != 5)
|
if (items != 5)
|
||||||
Perl_croak(aTHX_ "Usage: summonburriedplayercorpse(char_id,dest_x,dest_y,dest_z,dest_heading)");
|
Perl_croak(aTHX_ "Usage: summonburiedplayercorpse(char_id,dest_x,dest_y,dest_z,dest_heading)");
|
||||||
|
|
||||||
bool RETVAL;
|
bool RETVAL;
|
||||||
uint32 char_id = (int)SvIV(ST(0));
|
uint32 char_id = (int)SvIV(ST(0));
|
||||||
auto position = glm::vec4((float)SvIV(ST(1)), (float)SvIV(ST(2)), (float)SvIV(ST(3)),(float)SvIV(ST(4)));
|
auto position = glm::vec4((float)SvIV(ST(1)), (float)SvIV(ST(2)), (float)SvIV(ST(3)),(float)SvIV(ST(4)));
|
||||||
|
|
||||||
RETVAL = quest_manager.summonburriedplayercorpse(char_id, position);
|
RETVAL = quest_manager.summonburiedplayercorpse(char_id, position);
|
||||||
|
|
||||||
ST(0) = boolSV(RETVAL);
|
ST(0) = boolSV(RETVAL);
|
||||||
sv_2mortal(ST(0));
|
sv_2mortal(ST(0));
|
||||||
@ -1784,19 +1784,19 @@ XS(XS__summonallplayercorpses)
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
XS(XS__getplayerburriedcorpsecount);
|
XS(XS__getplayerburiedcorpsecount);
|
||||||
XS(XS__getplayerburriedcorpsecount)
|
XS(XS__getplayerburiedcorpsecount)
|
||||||
{
|
{
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
if (items != 1)
|
if (items != 1)
|
||||||
Perl_croak(aTHX_ "Usage: getplayerburriedcorpsecount(char_id)");
|
Perl_croak(aTHX_ "Usage: getplayerburiedcorpsecount(char_id)");
|
||||||
|
|
||||||
uint32 RETVAL;
|
uint32 RETVAL;
|
||||||
dXSTARG;
|
dXSTARG;
|
||||||
|
|
||||||
uint32 char_id = (int)SvIV(ST(0));
|
uint32 char_id = (int)SvIV(ST(0));
|
||||||
|
|
||||||
RETVAL = quest_manager.getplayerburriedcorpsecount(char_id);
|
RETVAL = quest_manager.getplayerburiedcorpsecount(char_id);
|
||||||
XSprePUSH; PUSHu((IV)RETVAL);
|
XSprePUSH; PUSHu((IV)RETVAL);
|
||||||
|
|
||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
@ -3712,7 +3712,7 @@ EXTERN_C XS(boot_quest)
|
|||||||
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
|
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
|
||||||
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
|
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
|
||||||
newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
|
newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
|
||||||
newXS(strcpy(buf, "getplayerburriedcorpsecount"), XS__getplayerburriedcorpsecount, file);
|
newXS(strcpy(buf, "getplayerburiedcorpsecount"), XS__getplayerburiedcorpsecount, file);
|
||||||
newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file);
|
newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file);
|
||||||
newXS(strcpy(buf, "givecash"), XS__givecash, file);
|
newXS(strcpy(buf, "givecash"), XS__givecash, file);
|
||||||
newXS(strcpy(buf, "gmmove"), XS__gmmove, file);
|
newXS(strcpy(buf, "gmmove"), XS__gmmove, file);
|
||||||
@ -3802,7 +3802,7 @@ EXTERN_C XS(boot_quest)
|
|||||||
newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file);
|
newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file);
|
||||||
newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file);
|
newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file);
|
||||||
newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file);
|
newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file);
|
||||||
newXS(strcpy(buf, "summonburriedplayercorpse"), XS__summonburriedplayercorpse, file);
|
newXS(strcpy(buf, "summonburiedplayercorpse"), XS__summonburiedplayercorpse, file);
|
||||||
newXS(strcpy(buf, "summonitem"), XS__summonitem, file);
|
newXS(strcpy(buf, "summonitem"), XS__summonitem, file);
|
||||||
newXS(strcpy(buf, "surname"), XS__surname, file);
|
newXS(strcpy(buf, "surname"), XS__surname, file);
|
||||||
newXS(strcpy(buf, "targlobal"), XS__targlobal, file);
|
newXS(strcpy(buf, "targlobal"), XS__targlobal, file);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -535,37 +535,20 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
|
|||||||
if (!target || !caster)
|
if (!target || !caster)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int ret = 0;
|
int hit_count = 0;
|
||||||
std::list<uint32> id_list;
|
auto it = list.begin();
|
||||||
auto iterator = list.begin();
|
while (it != list.end() && hit_count < count) {
|
||||||
while (iterator != list.end())
|
struct_HateList *h = (*it);
|
||||||
{
|
if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster) {
|
||||||
struct_HateList *h = (*iterator);
|
if (caster->CombatRange(h->entity_on_hatelist)) {
|
||||||
++iterator;
|
++hit_count;
|
||||||
if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster)
|
caster->ProcessAttackRounds(h->entity_on_hatelist, opts);
|
||||||
{
|
|
||||||
if (caster->CombatRange(h->entity_on_hatelist))
|
|
||||||
{
|
|
||||||
id_list.push_back(h->entity_on_hatelist->GetID());
|
|
||||||
++ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<uint32>::iterator iter = id_list.begin();
|
return hit_count;
|
||||||
while (iter != id_list.end())
|
|
||||||
{
|
|
||||||
Mob *cur = entity_list.GetMobID((*iter));
|
|
||||||
if (cur)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
caster->Attack(cur, MainPrimary, false, false, false, opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_center)
|
void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_center)
|
||||||
|
|||||||
@ -334,9 +334,11 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
|||||||
eslot = MaterialPrimary;
|
eslot = MaterialPrimary;
|
||||||
if (item2->Damage > 0)
|
if (item2->Damage > 0)
|
||||||
SendAddPlayerState(PlayerState::PrimaryWeaponEquipped);
|
SendAddPlayerState(PlayerState::PrimaryWeaponEquipped);
|
||||||
|
if (item2->ItemType == ItemType2HBlunt || item2->ItemType == ItemType2HSlash || item2->ItemType == ItemType2HPiercing)
|
||||||
|
SetTwoHanderEquipped(true);
|
||||||
}
|
}
|
||||||
else if (foundslot == MainSecondary
|
else if (foundslot == MainSecondary
|
||||||
&& (GetOwner() != nullptr || (GetLevel() >= 13 && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
|
&& (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
|
||||||
(item2->ItemType == ItemType1HSlash || item2->ItemType == ItemType1HBlunt || item2->ItemType == ItemTypeShield ||
|
(item2->ItemType == ItemType1HSlash || item2->ItemType == ItemType1HBlunt || item2->ItemType == ItemTypeShield ||
|
||||||
item2->ItemType == ItemType1HPiercing))
|
item2->ItemType == ItemType1HPiercing))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -166,9 +166,9 @@ public:
|
|||||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3);
|
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3);
|
||||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4);
|
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4);
|
||||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5);
|
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5);
|
||||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||||
bool attuned);
|
bool attuned);
|
||||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||||
bool attuned, int to_slot);
|
bool attuned, int to_slot);
|
||||||
void SetStats(int type, int value);
|
void SetStats(int type, int value);
|
||||||
void IncStats(int type, int value);
|
void IncStats(int type, int value);
|
||||||
@ -233,6 +233,8 @@ public:
|
|||||||
void AddLevelBasedExp(int exp_pct);
|
void AddLevelBasedExp(int exp_pct);
|
||||||
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);
|
||||||
|
|||||||
@ -513,16 +513,16 @@ void lua_toggle_spawn_event(int event_id, bool enable, bool strict, bool reset)
|
|||||||
quest_manager.toggle_spawn_event(event_id, enable, strict, reset);
|
quest_manager.toggle_spawn_event(event_id, enable, strict, reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_summon_burried_player_corpse(uint32 char_id, float x, float y, float z, float h) {
|
void lua_summon_buried_player_corpse(uint32 char_id, float x, float y, float z, float h) {
|
||||||
quest_manager.summonburriedplayercorpse(char_id, glm::vec4(x, y, z, h));
|
quest_manager.summonburiedplayercorpse(char_id, glm::vec4(x, y, z, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_summon_all_player_corpses(uint32 char_id, float x, float y, float z, float h) {
|
void lua_summon_all_player_corpses(uint32 char_id, float x, float y, float z, float h) {
|
||||||
quest_manager.summonallplayercorpses(char_id, glm::vec4(x, y, z, h));
|
quest_manager.summonallplayercorpses(char_id, glm::vec4(x, y, z, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_get_player_burried_corpse_count(uint32 char_id) {
|
int lua_get_player_buried_corpse_count(uint32 char_id) {
|
||||||
return quest_manager.getplayerburriedcorpsecount(char_id);
|
return quest_manager.getplayerburiedcorpsecount(char_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lua_bury_player_corpse(uint32 char_id) {
|
bool lua_bury_player_corpse(uint32 char_id) {
|
||||||
@ -1524,9 +1524,9 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("spawn_condition", &lua_spawn_condition),
|
luabind::def("spawn_condition", &lua_spawn_condition),
|
||||||
luabind::def("get_spawn_condition", &lua_get_spawn_condition),
|
luabind::def("get_spawn_condition", &lua_get_spawn_condition),
|
||||||
luabind::def("toggle_spawn_event", &lua_toggle_spawn_event),
|
luabind::def("toggle_spawn_event", &lua_toggle_spawn_event),
|
||||||
luabind::def("summon_burried_player_corpse", &lua_summon_burried_player_corpse),
|
luabind::def("summon_buried_player_corpse", &lua_summon_buried_player_corpse),
|
||||||
luabind::def("summon_all_player_corpses", &lua_summon_all_player_corpses),
|
luabind::def("summon_all_player_corpses", &lua_summon_all_player_corpses),
|
||||||
luabind::def("get_player_burried_corpse_count", &lua_get_player_burried_corpse_count),
|
luabind::def("get_player_buried_corpse_count", &lua_get_player_buried_corpse_count),
|
||||||
luabind::def("bury_player_corpse", &lua_bury_player_corpse),
|
luabind::def("bury_player_corpse", &lua_bury_player_corpse),
|
||||||
luabind::def("task_selector", &lua_task_selector),
|
luabind::def("task_selector", &lua_task_selector),
|
||||||
luabind::def("task_set_selector", &lua_task_set_selector),
|
luabind::def("task_set_selector", &lua_task_set_selector),
|
||||||
|
|||||||
@ -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)
|
||||||
@ -2216,7 +2234,14 @@ luabind::scope lua_register_special_abilities() {
|
|||||||
luabind::value("destructible_object", static_cast<int>(DESTRUCTIBLE_OBJECT)),
|
luabind::value("destructible_object", static_cast<int>(DESTRUCTIBLE_OBJECT)),
|
||||||
luabind::value("no_harm_from_client", static_cast<int>(NO_HARM_FROM_CLIENT)),
|
luabind::value("no_harm_from_client", static_cast<int>(NO_HARM_FROM_CLIENT)),
|
||||||
luabind::value("always_flee", static_cast<int>(ALWAYS_FLEE)),
|
luabind::value("always_flee", static_cast<int>(ALWAYS_FLEE)),
|
||||||
luabind::value("flee_percent", static_cast<int>(FLEE_PERCENT))
|
luabind::value("flee_percent", static_cast<int>(FLEE_PERCENT)),
|
||||||
|
luabind::value("allow_beneficial", static_cast<int>(ALLOW_BENEFICIAL)),
|
||||||
|
luabind::value("disable_melee", static_cast<int>(DISABLE_MELEE)),
|
||||||
|
luabind::value("npc_chase_distance", static_cast<int>(NPC_CHASE_DISTANCE)),
|
||||||
|
luabind::value("allow_to_tank", static_cast<int>(ALLOW_TO_TANK)),
|
||||||
|
luabind::value("ignore_root_aggro_rules", static_cast<int>(IGNORE_ROOT_AGGRO_RULES)),
|
||||||
|
luabind::value("casting_resist_diff", static_cast<int>(CASTING_RESIST_DIFF)),
|
||||||
|
luabind::value("counter_avoid_damage", static_cast<int>(COUNTER_AVOID_DAMAGE))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
55
zone/mob.cpp
55
zone/mob.cpp
@ -211,6 +211,7 @@ Mob::Mob(const char* in_name,
|
|||||||
trackable = true;
|
trackable = true;
|
||||||
has_shieldequiped = false;
|
has_shieldequiped = false;
|
||||||
has_twohandbluntequiped = false;
|
has_twohandbluntequiped = false;
|
||||||
|
has_twohanderequipped = false;
|
||||||
has_numhits = false;
|
has_numhits = false;
|
||||||
has_MGB = false;
|
has_MGB = false;
|
||||||
has_ProjectIllusion = false;
|
has_ProjectIllusion = false;
|
||||||
@ -307,8 +308,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;
|
||||||
@ -725,7 +726,7 @@ int Mob::_GetFearSpeed() const {
|
|||||||
movemod = -85;
|
movemod = -85;
|
||||||
|
|
||||||
if (IsClient()) {
|
if (IsClient()) {
|
||||||
if (CastToClient()->IsRunning())
|
if (CastToClient()->GetRunMode())
|
||||||
speed_mod = GetBaseRunspeed();
|
speed_mod = GetBaseRunspeed();
|
||||||
else
|
else
|
||||||
speed_mod = GetBaseWalkspeed();
|
speed_mod = GetBaseWalkspeed();
|
||||||
@ -1085,7 +1086,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
|||||||
ns->spawn.max_hp = 100; //this field needs a better name
|
ns->spawn.max_hp = 100; //this field needs a better name
|
||||||
ns->spawn.race = race;
|
ns->spawn.race = race;
|
||||||
ns->spawn.runspeed = runspeed;
|
ns->spawn.runspeed = runspeed;
|
||||||
ns->spawn.walkspeed = runspeed * 0.5f;
|
ns->spawn.walkspeed = walkspeed;
|
||||||
ns->spawn.class_ = class_;
|
ns->spawn.class_ = class_;
|
||||||
ns->spawn.gender = gender;
|
ns->spawn.gender = gender;
|
||||||
ns->spawn.level = level;
|
ns->spawn.level = level;
|
||||||
@ -1142,6 +1143,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));
|
||||||
@ -1354,8 +1359,12 @@ void Mob::SendHPUpdate(bool skip_self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dospam = RuleB(Character, SpamHPUpdates);
|
||||||
// send to self - we need the actual hps here
|
// send to self - we need the actual hps here
|
||||||
if(IsClient() && !skip_self) {
|
if(IsClient() && (!skip_self || dospam)) {
|
||||||
|
|
||||||
|
this->CastToClient()->SendHPUpdateMarquee();
|
||||||
|
|
||||||
EQApplicationPacket* hp_app2 = new EQApplicationPacket(OP_HPUpdate,sizeof(SpawnHPUpdate_Struct));
|
EQApplicationPacket* hp_app2 = new EQApplicationPacket(OP_HPUpdate,sizeof(SpawnHPUpdate_Struct));
|
||||||
SpawnHPUpdate_Struct* ds = (SpawnHPUpdate_Struct*)hp_app2->pBuffer;
|
SpawnHPUpdate_Struct* ds = (SpawnHPUpdate_Struct*)hp_app2->pBuffer;
|
||||||
ds->cur_hp = CastToClient()->GetHP() - itembonuses.HP;
|
ds->cur_hp = CastToClient()->GetHP() - itembonuses.HP;
|
||||||
@ -1364,7 +1373,8 @@ void Mob::SendHPUpdate(bool skip_self)
|
|||||||
CastToClient()->QueuePacket(hp_app2);
|
CastToClient()->QueuePacket(hp_app2);
|
||||||
safe_delete(hp_app2);
|
safe_delete(hp_app2);
|
||||||
}
|
}
|
||||||
ResetHPUpdateTimer(); // delay the timer
|
if (!dospam)
|
||||||
|
ResetHPUpdateTimer(); // delay the timer
|
||||||
}
|
}
|
||||||
|
|
||||||
// this one just warps the mob to the current location
|
// this one just warps the mob to the current location
|
||||||
@ -1385,19 +1395,23 @@ void Mob::SendPosUpdate(uint8 iSendToSelf) {
|
|||||||
MakeSpawnUpdate(spu);
|
MakeSpawnUpdate(spu);
|
||||||
|
|
||||||
if (iSendToSelf == 2) {
|
if (iSendToSelf == 2) {
|
||||||
if (this->IsClient())
|
if (IsClient()) {
|
||||||
this->CastToClient()->FastQueuePacket(&app,false);
|
CastToClient()->FastQueuePacket(&app,false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(move_tic_count == RuleI(Zone, NPCPositonUpdateTicCount))
|
if(move_tic_count == RuleI(Zone, NPCPositonUpdateTicCount))
|
||||||
{
|
{
|
||||||
entity_list.QueueClients(this, app, (iSendToSelf==0), false);
|
entity_list.QueueClients(this, app, (iSendToSelf == 0), false);
|
||||||
move_tic_count = 0;
|
move_tic_count = 0;
|
||||||
}
|
}
|
||||||
else
|
else if(move_tic_count % 2 == 0)
|
||||||
{
|
{
|
||||||
entity_list.QueueCloseClients(this, app, (iSendToSelf==0), 800, nullptr, false);
|
entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), 700, nullptr, false);
|
||||||
|
move_tic_count++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
move_tic_count++;
|
move_tic_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1475,7 +1489,7 @@ void Mob::ShowStats(Client* client)
|
|||||||
if(n->respawn2 != 0)
|
if(n->respawn2 != 0)
|
||||||
spawngroupid = n->respawn2->SpawnGroupID();
|
spawngroupid = n->respawn2->SpawnGroupID();
|
||||||
client->Message(0, " NPCID: %u SpawnGroupID: %u Grid: %i LootTable: %u FactionID: %i SpellsID: %u ", GetNPCTypeID(),spawngroupid, n->GetGrid(), n->GetLoottableID(), n->GetNPCFactionID(), n->GetNPCSpellsID());
|
client->Message(0, " NPCID: %u SpawnGroupID: %u Grid: %i LootTable: %u FactionID: %i SpellsID: %u ", GetNPCTypeID(),spawngroupid, n->GetGrid(), n->GetLoottableID(), n->GetNPCFactionID(), n->GetNPCSpellsID());
|
||||||
client->Message(0, " Accuracy: %i MerchantID: %i EmoteID: %i Runspeed: %u Walkspeed: %u", n->GetAccuracyRating(), n->MerchantType, n->GetEmoteID(), n->GetRunspeed(), n->GetWalkspeed());
|
client->Message(0, " Accuracy: %i MerchantID: %i EmoteID: %i Runspeed: %.3f Walkspeed: %.3f", n->GetAccuracyRating(), n->MerchantType, n->GetEmoteID(), static_cast<float>(0.025f * n->GetRunspeed()), static_cast<float>(0.025f * n->GetWalkspeed()));
|
||||||
n->QueryLoot(client);
|
n->QueryLoot(client);
|
||||||
}
|
}
|
||||||
if (IsAIControlled()) {
|
if (IsAIControlled()) {
|
||||||
@ -2399,6 +2413,14 @@ bool Mob::CanThisClassDoubleAttack(void) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Mob::CanThisClassTripleAttack() const
|
||||||
|
{
|
||||||
|
if (!IsClient())
|
||||||
|
return false; // When they added the real triple attack skill, mobs lost the ability to triple
|
||||||
|
else
|
||||||
|
return CastToClient()->HasSkill(SkillTripleAttack);
|
||||||
|
}
|
||||||
|
|
||||||
bool Mob::IsWarriorClass(void) const
|
bool Mob::IsWarriorClass(void) const
|
||||||
{
|
{
|
||||||
switch(GetClass())
|
switch(GetClass())
|
||||||
@ -3505,9 +3527,11 @@ void Mob::TriggerOnCast(uint32 focus_spell, uint32 spell_id, bool aa_trigger)
|
|||||||
|
|
||||||
uint32 trigger_spell_id = 0;
|
uint32 trigger_spell_id = 0;
|
||||||
|
|
||||||
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);
|
||||||
@ -3763,11 +3787,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;
|
||||||
|
|
||||||
|
|||||||
49
zone/mob.h
49
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>
|
||||||
@ -147,7 +149,7 @@ public:
|
|||||||
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
||||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
||||||
void TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary, int damage = 0);
|
void TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary, int damage = 0);
|
||||||
virtual bool AvoidDamage(Mob* attacker, int32 &damage, bool CanRiposte = true);
|
bool AvoidDamage(Mob* attacker, int32 &damage, int hand);
|
||||||
virtual bool CheckHitChance(Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod = 0);
|
virtual bool CheckHitChance(Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod = 0);
|
||||||
virtual void TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttackOptions *opts = nullptr);
|
virtual void TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttackOptions *opts = nullptr);
|
||||||
void TryPetCriticalHit(Mob *defender, uint16 skill, int32 &damage);
|
void TryPetCriticalHit(Mob *defender, uint16 skill, int32 &damage);
|
||||||
@ -164,6 +166,20 @@ public:
|
|||||||
void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse);
|
void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse);
|
||||||
void CommonBreakInvisible();
|
void CommonBreakInvisible();
|
||||||
bool HasDied();
|
bool HasDied();
|
||||||
|
virtual bool CheckDualWield();
|
||||||
|
void DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr);
|
||||||
|
void DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr);
|
||||||
|
virtual bool CheckDoubleAttack();
|
||||||
|
// inline process for places where we need to do them outside of the AI_Process
|
||||||
|
void ProcessAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr)
|
||||||
|
{
|
||||||
|
if (target) {
|
||||||
|
DoMainHandAttackRounds(target, opts);
|
||||||
|
if (CanThisClassDualWield())
|
||||||
|
DoOffHandAttackRounds(target, opts);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Appearance
|
//Appearance
|
||||||
void SendLevelAppearance();
|
void SendLevelAppearance();
|
||||||
@ -221,10 +237,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,
|
||||||
@ -318,6 +336,8 @@ public:
|
|||||||
inline void SetShieldEquiped(bool val) { has_shieldequiped = val; }
|
inline void SetShieldEquiped(bool val) { has_shieldequiped = val; }
|
||||||
bool HasTwoHandBluntEquiped() const { return has_twohandbluntequiped; }
|
bool HasTwoHandBluntEquiped() const { return has_twohandbluntequiped; }
|
||||||
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
|
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
|
||||||
|
bool HasTwoHanderEquipped() { return has_twohanderequipped; }
|
||||||
|
void SetTwoHanderEquipped(bool val) { has_twohanderequipped = val; }
|
||||||
virtual uint16 GetSkill(SkillUseTypes skill_num) const { return 0; }
|
virtual uint16 GetSkill(SkillUseTypes skill_num) const { return 0; }
|
||||||
virtual uint32 GetEquipment(uint8 material_slot) const { return(0); }
|
virtual uint32 GetEquipment(uint8 material_slot) const { return(0); }
|
||||||
virtual int32 GetEquipmentMaterial(uint8 material_slot) const;
|
virtual int32 GetEquipmentMaterial(uint8 material_slot) const;
|
||||||
@ -365,7 +385,7 @@ public:
|
|||||||
inline Mob* GetTarget() const { return target; }
|
inline Mob* GetTarget() const { return target; }
|
||||||
virtual void SetTarget(Mob* mob);
|
virtual void SetTarget(Mob* mob);
|
||||||
virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float)cur_hp/max_hp*100); }
|
virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float)cur_hp/max_hp*100); }
|
||||||
virtual inline float GetIntHPRatio() const { return max_hp == 0 ? 0 : (cur_hp/max_hp*100); }
|
virtual inline int GetIntHPRatio() const { return max_hp == 0 ? 0 : static_cast<int>(cur_hp * 100 / max_hp); }
|
||||||
inline virtual int32 GetAC() const { return AC + itembonuses.AC + spellbonuses.AC; }
|
inline virtual int32 GetAC() const { return AC + itembonuses.AC + spellbonuses.AC; }
|
||||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK; }
|
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK; }
|
||||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||||
@ -730,6 +750,7 @@ public:
|
|||||||
virtual int GetMonkHandToHandDamage(void);
|
virtual int GetMonkHandToHandDamage(void);
|
||||||
|
|
||||||
bool CanThisClassDoubleAttack(void) const;
|
bool CanThisClassDoubleAttack(void) const;
|
||||||
|
bool CanThisClassTripleAttack() const;
|
||||||
bool CanThisClassDualWield(void) const;
|
bool CanThisClassDualWield(void) const;
|
||||||
bool CanThisClassRiposte(void) const;
|
bool CanThisClassRiposte(void) const;
|
||||||
bool CanThisClassDodge(void) const;
|
bool CanThisClassDodge(void) const;
|
||||||
@ -860,7 +881,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 +976,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 +1002,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 +1177,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;
|
||||||
@ -1191,6 +1224,7 @@ protected:
|
|||||||
bool offhand;
|
bool offhand;
|
||||||
bool has_shieldequiped;
|
bool has_shieldequiped;
|
||||||
bool has_twohandbluntequiped;
|
bool has_twohandbluntequiped;
|
||||||
|
bool has_twohanderequipped;
|
||||||
bool has_numhits;
|
bool has_numhits;
|
||||||
bool has_MGB;
|
bool has_MGB;
|
||||||
bool has_ProjectIllusion;
|
bool has_ProjectIllusion;
|
||||||
@ -1311,6 +1345,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;
|
||||||
|
|||||||
212
zone/mob_ai.cpp
212
zone/mob_ai.cpp
@ -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) {
|
||||||
@ -772,7 +772,10 @@ void Client::AI_Process()
|
|||||||
engaged = true;
|
engaged = true;
|
||||||
} else {
|
} else {
|
||||||
if(AImovement_timer->Check()) {
|
if(AImovement_timer->Check()) {
|
||||||
//animation = GetFearSpeed() * 21;
|
int speed = GetFearSpeed();
|
||||||
|
animation = speed;
|
||||||
|
speed *= 2;
|
||||||
|
SetCurrentSpeed(speed);
|
||||||
// Check if we have reached the last fear point
|
// Check if we have reached the last fear point
|
||||||
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
||||||
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
||||||
@ -780,18 +783,18 @@ void Client::AI_Process()
|
|||||||
CalculateNewFearpoint();
|
CalculateNewFearpoint();
|
||||||
}
|
}
|
||||||
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
||||||
CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true);
|
CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, speed, true);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool WaypointChanged, NodeReached;
|
bool WaypointChanged, NodeReached;
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
||||||
GetFearSpeed(), WaypointChanged, NodeReached);
|
speed, WaypointChanged, NodeReached);
|
||||||
|
|
||||||
if(WaypointChanged)
|
if(WaypointChanged)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
|
|
||||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetFearSpeed());
|
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -824,118 +827,45 @@ void Client::AI_Process()
|
|||||||
|
|
||||||
bool is_combat_range = CombatRange(GetTarget());
|
bool is_combat_range = CombatRange(GetTarget());
|
||||||
|
|
||||||
if(is_combat_range) {
|
if (is_combat_range) {
|
||||||
if(charm_class_attacks_timer.Check()) {
|
if (charm_class_attacks_timer.Check()) {
|
||||||
DoClassAttacks(GetTarget());
|
DoClassAttacks(GetTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AImovement_timer->Check()) {
|
if (AImovement_timer->Check()) {
|
||||||
if(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w)
|
if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) !=
|
||||||
{
|
m_Position.w) {
|
||||||
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
SendPosition();
|
SendPosition();
|
||||||
}
|
}
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
if(GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) {
|
if (GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) {
|
||||||
if(attack_timer.Check()) {
|
if (attack_timer.Check()) {
|
||||||
Attack(GetTarget(), MainPrimary);
|
// Should charmed clients not be procing?
|
||||||
if(GetTarget()) {
|
DoAttackRounds(GetTarget(), MainPrimary);
|
||||||
if(CheckDoubleAttack()) {
|
|
||||||
Attack(GetTarget(), MainPrimary);
|
|
||||||
if(GetTarget()) {
|
|
||||||
bool triple_attack_success = false;
|
|
||||||
if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
|
|
||||||
&& GetLevel() >= 60) || GetSpecialAbility(SPECATK_TRIPLE))
|
|
||||||
&& CheckDoubleAttack(true))
|
|
||||||
{
|
|
||||||
Attack(GetTarget(), MainPrimary, true);
|
|
||||||
triple_attack_success = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GetTarget())
|
|
||||||
{
|
|
||||||
//Live AA - Flurry, Rapid Strikes ect (Flurry does not require Triple Attack).
|
|
||||||
int16 flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
|
||||||
|
|
||||||
if (flurrychance)
|
|
||||||
{
|
|
||||||
if(zone->random.Roll(flurrychance))
|
|
||||||
{
|
|
||||||
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
|
||||||
Attack(GetTarget(), MainPrimary, false);
|
|
||||||
Attack(GetTarget(), MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
|
|
||||||
|
|
||||||
if (ExtraAttackChanceBonus && GetTarget()) {
|
|
||||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
|
||||||
if(wpn){
|
|
||||||
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
|
|
||||||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
|
||||||
wpn->GetItem()->ItemType == ItemType2HPiercing )
|
|
||||||
{
|
|
||||||
if(zone->random.Roll(ExtraAttackChanceBonus))
|
|
||||||
{
|
|
||||||
Attack(GetTarget(), MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetClass() == WARRIOR || GetClass() == BERSERKER)
|
|
||||||
{
|
|
||||||
if(!dead && !berserk && this->GetHPRatio() < 30)
|
|
||||||
{
|
|
||||||
entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_START, GetName());
|
|
||||||
berserk = true;
|
|
||||||
}
|
|
||||||
else if (berserk && this->GetHPRatio() > 30)
|
|
||||||
{
|
|
||||||
entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_END, GetName());
|
|
||||||
berserk = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CanThisClassDualWield() && attack_dw_timer.Check())
|
if (CanThisClassDualWield() && GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) {
|
||||||
{
|
if (attack_dw_timer.Check()) {
|
||||||
if(GetTarget())
|
if (CheckDualWield()) {
|
||||||
{
|
// Should charmed clients not be procing?
|
||||||
float DualWieldProbability = 0.0f;
|
DoAttackRounds(GetTarget(), MainSecondary);
|
||||||
|
|
||||||
int16 Ambidexterity = aabonuses.Ambidexterity + spellbonuses.Ambidexterity + itembonuses.Ambidexterity;
|
|
||||||
DualWieldProbability = (GetSkill(SkillDualWield) + GetLevel() + Ambidexterity) / 400.0f; // 78.0 max
|
|
||||||
int16 DWBonus = spellbonuses.DualWieldChance + itembonuses.DualWieldChance;
|
|
||||||
DualWieldProbability += DualWieldProbability*float(DWBonus)/ 100.0f;
|
|
||||||
|
|
||||||
if(zone->random.Roll(DualWieldProbability))
|
|
||||||
{
|
|
||||||
Attack(GetTarget(), MainSecondary);
|
|
||||||
if(CheckDoubleAttack())
|
|
||||||
{
|
|
||||||
Attack(GetTarget(), MainSecondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!IsRooted())
|
if(!IsRooted())
|
||||||
{
|
{
|
||||||
if(AImovement_timer->Check())
|
if(AImovement_timer->Check())
|
||||||
{
|
{
|
||||||
|
int newspeed = GetRunspeed();
|
||||||
|
animation = newspeed;
|
||||||
|
newspeed *= 2;
|
||||||
|
SetCurrentSpeed(newspeed);
|
||||||
if(!RuleB(Pathing, Aggro) || !zone->pathing)
|
if(!RuleB(Pathing, Aggro) || !zone->pathing)
|
||||||
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed());
|
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), newspeed);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool WaypointChanged, NodeReached;
|
bool WaypointChanged, NodeReached;
|
||||||
@ -945,7 +875,7 @@ void Client::AI_Process()
|
|||||||
if(WaypointChanged)
|
if(WaypointChanged)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
|
|
||||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed());
|
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, newspeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -989,11 +919,12 @@ void Client::AI_Process()
|
|||||||
{
|
{
|
||||||
if(AImovement_timer->Check())
|
if(AImovement_timer->Check())
|
||||||
{
|
{
|
||||||
int speed = GetWalkspeed();
|
int nspeed = (dist >= 5625 ? GetRunspeed() : GetWalkspeed());
|
||||||
if (dist >= 5625)
|
animation = nspeed;
|
||||||
speed = GetRunspeed();
|
nspeed *= 2;
|
||||||
|
SetCurrentSpeed(nspeed);
|
||||||
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
|
||||||
|
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), nspeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1170,43 +1101,9 @@ void Mob::AI_Process() {
|
|||||||
|
|
||||||
//try main hand first
|
//try main hand first
|
||||||
if(attack_timer.Check()) {
|
if(attack_timer.Check()) {
|
||||||
if(IsNPC()) {
|
DoMainHandAttackRounds(target);
|
||||||
int16 n_atk = CastToNPC()->GetNumberOfAttacks();
|
|
||||||
if(n_atk <= 1) {
|
|
||||||
Attack(target, MainPrimary);
|
|
||||||
} else {
|
|
||||||
for(int i = 0; i < n_atk; ++i) {
|
|
||||||
Attack(target, MainPrimary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Attack(target, MainPrimary);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target) {
|
|
||||||
//we use this random value in three comparisons with different
|
|
||||||
//thresholds, and if its truely random, then this should work
|
|
||||||
//out reasonably and will save us compute resources.
|
|
||||||
int32 RandRoll = zone->random.Int(0, 99);
|
|
||||||
if ((CanThisClassDoubleAttack() || GetSpecialAbility(SPECATK_TRIPLE)
|
|
||||||
|| GetSpecialAbility(SPECATK_QUAD))
|
|
||||||
//check double attack, this is NOT the same rules that clients use...
|
|
||||||
&& RandRoll < (GetLevel() + NPCDualAttackModifier)) {
|
|
||||||
Attack(target, MainPrimary);
|
|
||||||
// lets see if we can do a triple attack with the main hand
|
|
||||||
//pets are excluded from triple and quads...
|
|
||||||
if ((GetSpecialAbility(SPECATK_TRIPLE) || GetSpecialAbility(SPECATK_QUAD))
|
|
||||||
&& !IsPet() && RandRoll < (GetLevel() + NPCTripleAttackModifier)) {
|
|
||||||
Attack(target, MainPrimary);
|
|
||||||
// now lets check the quad attack
|
|
||||||
if (GetSpecialAbility(SPECATK_QUAD)
|
|
||||||
&& RandRoll < (GetLevel() + NPCQuadAttackModifier)) {
|
|
||||||
Attack(target, MainPrimary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool specialed = false; // NPCs can only do one of these a round
|
||||||
if (GetSpecialAbility(SPECATK_FLURRY)) {
|
if (GetSpecialAbility(SPECATK_FLURRY)) {
|
||||||
int flurry_chance = GetSpecialAbilityParam(SPECATK_FLURRY, 0);
|
int flurry_chance = GetSpecialAbilityParam(SPECATK_FLURRY, 0);
|
||||||
flurry_chance = flurry_chance > 0 ? flurry_chance : RuleI(Combat, NPCFlurryChance);
|
flurry_chance = flurry_chance > 0 ? flurry_chance : RuleI(Combat, NPCFlurryChance);
|
||||||
@ -1238,6 +1135,7 @@ void Mob::AI_Process() {
|
|||||||
opts.crit_flat = cur;
|
opts.crit_flat = cur;
|
||||||
|
|
||||||
Flurry(&opts);
|
Flurry(&opts);
|
||||||
|
specialed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,7 +1156,7 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSpecialAbility(SPECATK_RAMPAGE))
|
if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed)
|
||||||
{
|
{
|
||||||
int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0);
|
int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0);
|
||||||
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
||||||
@ -1294,10 +1192,11 @@ void Mob::AI_Process() {
|
|||||||
opts.crit_flat = cur;
|
opts.crit_flat = cur;
|
||||||
}
|
}
|
||||||
Rampage(&opts);
|
Rampage(&opts);
|
||||||
|
specialed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSpecialAbility(SPECATK_AREA_RAMPAGE))
|
if (GetSpecialAbility(SPECATK_AREA_RAMPAGE) && !specialed)
|
||||||
{
|
{
|
||||||
int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0);
|
int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0);
|
||||||
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
||||||
@ -1334,30 +1233,14 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AreaRampage(&opts);
|
AreaRampage(&opts);
|
||||||
|
specialed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//now off hand
|
//now off hand
|
||||||
if (attack_dw_timer.Check() && CanThisClassDualWield())
|
if (attack_dw_timer.Check() && CanThisClassDualWield())
|
||||||
{
|
DoOffHandAttackRounds(target);
|
||||||
int myclass = GetClass();
|
|
||||||
//can only dual wield without a weapon if your a monk
|
|
||||||
if(GetSpecialAbility(SPECATK_INNATE_DW) || (GetEquipment(MaterialSecondary) != 0 && GetLevel() > 29) || myclass == MONK || myclass == MONKGM) {
|
|
||||||
float DualWieldProbability = (GetSkill(SkillDualWield) + GetLevel()) / 400.0f;
|
|
||||||
if(zone->random.Roll(DualWieldProbability))
|
|
||||||
{
|
|
||||||
Attack(target, MainSecondary);
|
|
||||||
if (CanThisClassDoubleAttack())
|
|
||||||
{
|
|
||||||
if (zone->random.Roll(GetLevel() + 20))
|
|
||||||
{
|
|
||||||
Attack(target, MainSecondary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//now special attacks (kick, etc)
|
//now special attacks (kick, etc)
|
||||||
if(IsNPC())
|
if(IsNPC())
|
||||||
@ -1494,7 +1377,7 @@ void Mob::AI_Process() {
|
|||||||
int speed = GetWalkspeed();
|
int speed = GetWalkspeed();
|
||||||
if (dist >= 5625)
|
if (dist >= 5625)
|
||||||
speed = GetRunspeed();
|
speed = GetRunspeed();
|
||||||
|
|
||||||
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2095,14 +1978,14 @@ bool Mob::Rampage(ExtraAttackOptions *opts)
|
|||||||
if (m_target == GetTarget())
|
if (m_target == GetTarget())
|
||||||
continue;
|
continue;
|
||||||
if (CombatRange(m_target)) {
|
if (CombatRange(m_target)) {
|
||||||
Attack(m_target, MainPrimary, false, false, false, opts);
|
ProcessAttackRounds(m_target, opts);
|
||||||
index_hit++;
|
index_hit++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RuleB(Combat, RampageHitsTarget) && index_hit < rampage_targets)
|
if (RuleB(Combat, RampageHitsTarget) && index_hit < rampage_targets)
|
||||||
Attack(GetTarget(), MainPrimary, false, false, false, opts);
|
ProcessAttackRounds(GetTarget(), opts);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2120,9 +2003,8 @@ void Mob::AreaRampage(ExtraAttackOptions *opts)
|
|||||||
rampage_targets = rampage_targets > 0 ? rampage_targets : 1;
|
rampage_targets = rampage_targets > 0 ? rampage_targets : 1;
|
||||||
index_hit = hate_list.AreaRampage(this, GetTarget(), rampage_targets, opts);
|
index_hit = hate_list.AreaRampage(this, GetTarget(), rampage_targets, opts);
|
||||||
|
|
||||||
if(index_hit == 0) {
|
if(index_hit == 0)
|
||||||
Attack(GetTarget(), MainPrimary, false, false, false, opts);
|
ProcessAttackRounds(GetTarget(), opts);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Mob::GetLevelCon(uint8 mylevel, uint8 iOtherLevel) {
|
uint32 Mob::GetLevelCon(uint8 mylevel, uint8 iOtherLevel) {
|
||||||
|
|||||||
92
zone/net.cpp
92
zone/net.cpp
@ -28,7 +28,6 @@
|
|||||||
#include "../common/eq_packet_structs.h"
|
#include "../common/eq_packet_structs.h"
|
||||||
#include "../common/mutex.h"
|
#include "../common/mutex.h"
|
||||||
#include "../common/version.h"
|
#include "../common/version.h"
|
||||||
|
|
||||||
#include "../common/packet_dump_file.h"
|
#include "../common/packet_dump_file.h"
|
||||||
#include "../common/opcodemgr.h"
|
#include "../common/opcodemgr.h"
|
||||||
#include "../common/guilds.h"
|
#include "../common/guilds.h"
|
||||||
@ -57,17 +56,14 @@
|
|||||||
#include "titles.h"
|
#include "titles.h"
|
||||||
#include "guild_mgr.h"
|
#include "guild_mgr.h"
|
||||||
#include "tasks.h"
|
#include "tasks.h"
|
||||||
|
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "embparser.h"
|
#include "embparser.h"
|
||||||
#include "lua_parser.h"
|
#include "lua_parser.h"
|
||||||
|
|
||||||
#include "questmgr.h"
|
#include "questmgr.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -96,7 +92,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];
|
||||||
@ -116,28 +111,77 @@ int main(int argc, char** argv) {
|
|||||||
RegisterExecutablePlatform(ExePlatformZone);
|
RegisterExecutablePlatform(ExePlatformZone);
|
||||||
Log.LoadLogSettingsDefaults();
|
Log.LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
const char *zone_name;
|
|
||||||
QServ = new QueryServ;
|
QServ = new QueryServ;
|
||||||
|
|
||||||
if(argc == 3) {
|
Log.Out(Logs::General, Logs::Zone_Server, "Loading server configuration..");
|
||||||
|
if(!ZoneConfig::LoadConfig()) {
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Loading server configuration failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const ZoneConfig *Config = ZoneConfig::get();
|
||||||
|
|
||||||
|
const char *zone_name;
|
||||||
|
uint32 instance_id = 0;
|
||||||
|
std::string z_name;
|
||||||
|
if(argc == 4) {
|
||||||
|
instance_id = atoi(argv[3]);
|
||||||
worldserver.SetLauncherName(argv[2]);
|
worldserver.SetLauncherName(argv[2]);
|
||||||
worldserver.SetLaunchedName(argv[1]);
|
auto zone_port = SplitString(argv[1], ':');
|
||||||
if(strncmp(argv[1], "dynamic_", 8) == 0) {
|
|
||||||
//dynamic zone with a launcher name correlation
|
if(zone_port.size() > 0) {
|
||||||
|
z_name = zone_port[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(zone_port.size() > 1) {
|
||||||
|
std::string p_name = zone_port[1];
|
||||||
|
Config->SetZonePort(atoi(p_name.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
worldserver.SetLaunchedName(z_name.c_str());
|
||||||
|
if(strncmp(z_name.c_str(), "dynamic_", 8) == 0) {
|
||||||
|
zone_name = ".";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zone_name = z_name.c_str();
|
||||||
|
}
|
||||||
|
} else if(argc == 3) {
|
||||||
|
worldserver.SetLauncherName(argv[2]);
|
||||||
|
auto zone_port = SplitString(argv[1], ':');
|
||||||
|
|
||||||
|
if(zone_port.size() > 0) {
|
||||||
|
z_name = zone_port[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(zone_port.size() > 1) {
|
||||||
|
std::string p_name = zone_port[1];
|
||||||
|
Config->SetZonePort(atoi(p_name.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
worldserver.SetLaunchedName(z_name.c_str());
|
||||||
|
if(strncmp(z_name.c_str(), "dynamic_", 8) == 0) {
|
||||||
zone_name = ".";
|
zone_name = ".";
|
||||||
} else {
|
} else {
|
||||||
zone_name = argv[1];
|
zone_name = z_name.c_str();
|
||||||
worldserver.SetLaunchedName(zone_name);
|
|
||||||
}
|
}
|
||||||
} else if (argc == 2) {
|
} else if (argc == 2) {
|
||||||
worldserver.SetLauncherName("NONE");
|
worldserver.SetLauncherName("NONE");
|
||||||
worldserver.SetLaunchedName(argv[1]);
|
auto zone_port = SplitString(argv[1], ':');
|
||||||
if(strncmp(argv[1], "dynamic_", 8) == 0) {
|
|
||||||
//dynamic zone with a launcher name correlation
|
if(zone_port.size() > 0) {
|
||||||
|
z_name = zone_port[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(zone_port.size() > 1) {
|
||||||
|
std::string p_name = zone_port[1];
|
||||||
|
Config->SetZonePort(atoi(p_name.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
worldserver.SetLaunchedName(z_name.c_str());
|
||||||
|
if(strncmp(z_name.c_str(), "dynamic_", 8) == 0) {
|
||||||
zone_name = ".";
|
zone_name = ".";
|
||||||
} else {
|
}
|
||||||
zone_name = argv[1];
|
else {
|
||||||
worldserver.SetLaunchedName(zone_name);
|
zone_name = z_name.c_str();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
zone_name = ".";
|
zone_name = ".";
|
||||||
@ -145,13 +189,6 @@ int main(int argc, char** argv) {
|
|||||||
worldserver.SetLauncherName("NONE");
|
worldserver.SetLauncherName("NONE");
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading server configuration..");
|
|
||||||
if (!ZoneConfig::LoadConfig()) {
|
|
||||||
Log.Out(Logs::General, Logs::Error, "Loading server configuration failed.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
const ZoneConfig *Config = ZoneConfig::get();
|
|
||||||
|
|
||||||
worldserver.SetPassword(Config->SharedKey.c_str());
|
worldserver.SetPassword(Config->SharedKey.c_str());
|
||||||
|
|
||||||
Log.Out(Logs::General, Logs::Zone_Server, "Connecting to MySQL...");
|
Log.Out(Logs::General, Logs::Zone_Server, "Connecting to MySQL...");
|
||||||
@ -257,9 +294,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();
|
||||||
|
|
||||||
@ -324,7 +358,7 @@ int main(int argc, char** argv) {
|
|||||||
#endif
|
#endif
|
||||||
if (!strlen(zone_name) || !strcmp(zone_name,".")) {
|
if (!strlen(zone_name) || !strcmp(zone_name,".")) {
|
||||||
Log.Out(Logs::General, Logs::Zone_Server, "Entering sleep mode");
|
Log.Out(Logs::General, Logs::Zone_Server, "Entering sleep mode");
|
||||||
} else if (!Zone::Bootup(database.GetZoneID(zone_name), 0, true)) { //todo: go above and fix this to allow cmd line instance
|
} else if (!Zone::Bootup(database.GetZoneID(zone_name), instance_id, true)) {
|
||||||
Log.Out(Logs::General, Logs::Error, "Zone Bootup failed :: Zone::Bootup");
|
Log.Out(Logs::General, Logs::Error, "Zone Bootup failed :: Zone::Bootup");
|
||||||
zone = 0;
|
zone = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
23
zone/npc.cpp
23
zone/npc.cpp
@ -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"
|
||||||
@ -279,6 +278,18 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
|||||||
for(r = 0; r <= HIGHEST_SKILL; r++) {
|
for(r = 0; r <= HIGHEST_SKILL; r++) {
|
||||||
skills[r] = database.GetSkillCap(GetClass(),(SkillUseTypes)r,moblevel);
|
skills[r] = database.GetSkillCap(GetClass(),(SkillUseTypes)r,moblevel);
|
||||||
}
|
}
|
||||||
|
// some overrides -- really we need to be able to set skills for mobs in the DB
|
||||||
|
// There are some known low level SHM/BST pets that do not follow this, which supports
|
||||||
|
// the theory of needing to be able to set skills for each mob separately
|
||||||
|
if (moblevel > 50) {
|
||||||
|
skills[SkillDoubleAttack] = 250;
|
||||||
|
skills[SkillDualWield] = 250;
|
||||||
|
} else if (moblevel > 3) {
|
||||||
|
skills[SkillDoubleAttack] = moblevel * 5;
|
||||||
|
skills[SkillDualWield] = skills[SkillDoubleAttack];
|
||||||
|
} else {
|
||||||
|
skills[SkillDoubleAttack] = moblevel * 5;
|
||||||
|
}
|
||||||
|
|
||||||
if(d->trap_template > 0)
|
if(d->trap_template > 0)
|
||||||
{
|
{
|
||||||
@ -1929,7 +1940,15 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
|
|||||||
else if(id == "pr") { PR = atoi(val.c_str()); return; }
|
else if(id == "pr") { PR = atoi(val.c_str()); return; }
|
||||||
else if(id == "dr") { DR = atoi(val.c_str()); return; }
|
else if(id == "dr") { DR = atoi(val.c_str()); return; }
|
||||||
else if(id == "PhR") { PhR = atoi(val.c_str()); return; }
|
else if(id == "PhR") { PhR = atoi(val.c_str()); return; }
|
||||||
else if(id == "runspeed") { runspeed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
else if(id == "runspeed") {
|
||||||
|
runspeed = (float)atof(val.c_str());
|
||||||
|
base_runspeed = (int)((float)runspeed * 40.0f);
|
||||||
|
base_walkspeed = base_runspeed * 100 / 265;
|
||||||
|
walkspeed = ((float)base_walkspeed) * 0.025f;
|
||||||
|
base_fearspeed = base_runspeed * 100 / 127;
|
||||||
|
fearspeed = ((float)base_fearspeed) * 0.025f;
|
||||||
|
CalcBonuses(); return;
|
||||||
|
}
|
||||||
else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; }
|
else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; }
|
||||||
else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; }
|
else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; }
|
||||||
else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
||||||
|
|||||||
@ -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,12 +6360,12 @@ 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;
|
Mob * THIS;
|
||||||
uint32 RETVAL;
|
uint32 RETVAL;
|
||||||
dXSTARG;
|
dXSTARG;
|
||||||
uint32 aa_id = (uint32)SvUV(ST(1));
|
uint32 rank_id = (uint32)SvUV(ST(1));
|
||||||
|
|
||||||
if (sv_derived_from(ST(0), "Mob")) {
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
@ -6376,12 +6376,68 @@ 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->GetAA(rank_id);
|
||||||
XSprePUSH; PUSHu((UV)RETVAL);
|
XSprePUSH; PUSHu((UV)RETVAL);
|
||||||
}
|
}
|
||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_GetAAByAAID); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Mob_GetAAByAAID)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if(items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::GetAAByAAID(THIS, aa_id)");
|
||||||
|
{
|
||||||
|
Mob * THIS;
|
||||||
|
uint32 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
uint32 aa_id = (uint32)SvUV(ST(1));
|
||||||
|
|
||||||
|
if(sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob *, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
if(THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetAAByAAID(aa_id);
|
||||||
|
XSprePUSH; PUSHu((UV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_SetAA); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Mob_SetAA)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if(items < 3 || items > 4)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::SetAA(THIS, aa_id, points, [charges])");
|
||||||
|
{
|
||||||
|
Mob * THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
int aa_id = (int)SvIV(ST(1));
|
||||||
|
int points = (int)SvIV(ST(2));
|
||||||
|
int charges = (items == 4) ? (int)SvIV(ST(3)) : 0;
|
||||||
|
|
||||||
|
if(sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob *, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
if(THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->SetAA(aa_id, points, charges);
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_Mob_DivineAura); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_Mob_DivineAura); /* 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, "$$");
|
||||||
|
|||||||
@ -874,7 +874,7 @@ bool QuestManager::isdisctome(int item_id) {
|
|||||||
void QuestManager::safemove() {
|
void QuestManager::safemove() {
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
if (initiator && initiator->IsClient())
|
if (initiator && initiator->IsClient())
|
||||||
initiator->GoToSafeCoords(zone->GetZoneID(), 0);
|
initiator->GoToSafeCoords(zone->GetZoneID(), zone->GetInstanceID());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestManager::rain(int weather) {
|
void QuestManager::rain(int weather) {
|
||||||
@ -1774,7 +1774,7 @@ void QuestManager::sethp(int hpperc) {
|
|||||||
owner->Damage(owner, newhp, SPELL_UNKNOWN, SkillHandtoHand, false, 0, false);
|
owner->Damage(owner, newhp, SPELL_UNKNOWN, SkillHandtoHand, false, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QuestManager::summonburriedplayercorpse(uint32 char_id, const glm::vec4& position) {
|
bool QuestManager::summonburiedplayercorpse(uint32 char_id, const glm::vec4& position) {
|
||||||
bool Result = false;
|
bool Result = false;
|
||||||
|
|
||||||
if(char_id <= 0)
|
if(char_id <= 0)
|
||||||
@ -1798,7 +1798,7 @@ bool QuestManager::summonallplayercorpses(uint32 char_id, const glm::vec4& posit
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 QuestManager::getplayerburriedcorpsecount(uint32 char_id) {
|
uint32 QuestManager::getplayerburiedcorpsecount(uint32 char_id) {
|
||||||
uint32 Result = 0;
|
uint32 Result = 0;
|
||||||
|
|
||||||
if(char_id > 0) {
|
if(char_id > 0) {
|
||||||
|
|||||||
@ -159,9 +159,9 @@ public:
|
|||||||
void set_zone_flag(int zone_id);
|
void set_zone_flag(int zone_id);
|
||||||
void clear_zone_flag(int zone_id);
|
void clear_zone_flag(int zone_id);
|
||||||
void sethp(int hpperc);
|
void sethp(int hpperc);
|
||||||
bool summonburriedplayercorpse(uint32 char_id, const glm::vec4& position);
|
bool summonburiedplayercorpse(uint32 char_id, const glm::vec4& position);
|
||||||
bool summonallplayercorpses(uint32 char_id, const glm::vec4& position);
|
bool summonallplayercorpses(uint32 char_id, const glm::vec4& position);
|
||||||
uint32 getplayerburriedcorpsecount(uint32 char_id);
|
uint32 getplayerburiedcorpsecount(uint32 char_id);
|
||||||
bool buryplayercorpse(uint32 char_id);
|
bool buryplayercorpse(uint32 char_id);
|
||||||
void forcedooropen(uint32 doorid, bool altmode);
|
void forcedooropen(uint32 doorid, bool altmode);
|
||||||
void forcedoorclose(uint32 doorid, bool altmode);
|
void forcedoorclose(uint32 doorid, bool altmode);
|
||||||
|
|||||||
@ -130,49 +130,41 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
|||||||
|
|
||||||
min_damage += min_damage * GetMeleeMinDamageMod_SE(skill) / 100;
|
min_damage += min_damage * GetMeleeMinDamageMod_SE(skill) / 100;
|
||||||
|
|
||||||
if(HitChance && !who->CheckHitChance(this, skill, MainPrimary))
|
int hand = MainPrimary; // Avoid checks hand for throwing/archery exclusion, primary should work for most
|
||||||
max_damage = 0;
|
if (skill == SkillThrowing || skill == SkillArchery)
|
||||||
|
hand = MainRange;
|
||||||
else{
|
if (who->AvoidDamage(this, max_damage, hand)) {
|
||||||
bool CanRiposte = true;
|
if (max_damage == -3)
|
||||||
if(skill == SkillThrowing || skill == SkillArchery) // changed from '&&'
|
DoRiposte(who);
|
||||||
CanRiposte = false;
|
} else {
|
||||||
|
if (HitChance || who->CheckHitChance(this, skill, MainPrimary)) {
|
||||||
if (CanAvoid)
|
who->MeleeMitigation(this, max_damage, min_damage);
|
||||||
who->AvoidDamage(this, max_damage, CanRiposte);
|
|
||||||
|
|
||||||
who->MeleeMitigation(this, max_damage, min_damage);
|
|
||||||
|
|
||||||
if(max_damage > 0)
|
|
||||||
CommonOutgoingHitSuccess(who, max_damage, skill);
|
CommonOutgoingHitSuccess(who, max_damage, skill);
|
||||||
|
} else {
|
||||||
|
max_damage = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
if (max_damage > 0 && HasSkillProcSuccess())
|
if (max_damage > 0 && HasSkillProcSuccess())
|
||||||
TrySkillProc(who, skill, ReuseTime*1000, true);
|
TrySkillProc(who, skill, ReuseTime*1000, true);
|
||||||
|
|
||||||
if(max_damage == -3 && !who->HasDied())
|
|
||||||
DoRiposte(who);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -544,7 +536,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
|
|||||||
|
|
||||||
RogueBackstab(other,false,ReuseTime);
|
RogueBackstab(other,false,ReuseTime);
|
||||||
if (level > 54) {
|
if (level > 54) {
|
||||||
if(IsClient() && CastToClient()->CheckDoubleAttack(false))
|
if(IsClient() && CastToClient()->CheckDoubleAttack())
|
||||||
{
|
{
|
||||||
if(other->GetHP() > 0)
|
if(other->GetHP() > 0)
|
||||||
RogueBackstab(other,false,ReuseTime);
|
RogueBackstab(other,false,ReuseTime);
|
||||||
@ -566,7 +558,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
|
|||||||
if (level > 54) {
|
if (level > 54) {
|
||||||
|
|
||||||
// Check for double attack with main hand assuming maxed DA Skill (MS)
|
// Check for double attack with main hand assuming maxed DA Skill (MS)
|
||||||
if(IsClient() && CastToClient()->CheckDoubleAttack(false))
|
if(IsClient() && CastToClient()->CheckDoubleAttack())
|
||||||
if(other->GetHP() > 0)
|
if(other->GetHP() > 0)
|
||||||
RogueBackstab(other,true, ReuseTime);
|
RogueBackstab(other,true, ReuseTime);
|
||||||
|
|
||||||
@ -975,7 +967,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!HeadShot)
|
if (!HeadShot)
|
||||||
other->AvoidDamage(this, TotalDmg, false);
|
other->AvoidDamage(this, TotalDmg, MainRange);
|
||||||
|
|
||||||
other->MeleeMitigation(this, TotalDmg, minDmg);
|
other->MeleeMitigation(this, TotalDmg, minDmg);
|
||||||
if(TotalDmg > 0){
|
if(TotalDmg > 0){
|
||||||
@ -1308,7 +1300,7 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha
|
|||||||
|
|
||||||
TotalDmg += TotalDmg * damage_mod / 100;
|
TotalDmg += TotalDmg * damage_mod / 100;
|
||||||
|
|
||||||
other->AvoidDamage(this, TotalDmg, false);
|
other->AvoidDamage(this, TotalDmg, MainRange);
|
||||||
other->MeleeMitigation(this, TotalDmg, MinDmg);
|
other->MeleeMitigation(this, TotalDmg, MinDmg);
|
||||||
|
|
||||||
if (TotalDmg > 0)
|
if (TotalDmg > 0)
|
||||||
@ -1542,7 +1534,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
|||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Item DMG %d. Max Damage %d. Hit for damage %d", WDmg, MaxDmg, TotalDmg);
|
Log.Out(Logs::Detail, Logs::Combat, "Item DMG %d. Max Damage %d. Hit for damage %d", WDmg, MaxDmg, TotalDmg);
|
||||||
if (!Assassinate_Dmg)
|
if (!Assassinate_Dmg)
|
||||||
other->AvoidDamage(this, TotalDmg, false); //CanRiposte=false - Can not riposte throw attacks.
|
other->AvoidDamage(this, TotalDmg, MainRange);
|
||||||
|
|
||||||
other->MeleeMitigation(this, TotalDmg, minDmg);
|
other->MeleeMitigation(this, TotalDmg, minDmg);
|
||||||
if(TotalDmg > 0)
|
if(TotalDmg > 0)
|
||||||
@ -2414,27 +2406,26 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
else
|
else
|
||||||
damage = zone->random.Int(min_hit, max_hit);
|
damage = zone->random.Int(min_hit, max_hit);
|
||||||
|
|
||||||
if(!other->CheckHitChance(this, skillinuse, Hand, chance_mod)) {
|
if (other->AvoidDamage(this, damage, CanRiposte ? MainRange : MainPrimary)) { // MainRange excludes ripo, primary doesn't have any extra behavior
|
||||||
damage = 0;
|
if (damage == -3) {
|
||||||
|
DoRiposte(other);
|
||||||
|
if (HasDied())
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
other->AvoidDamage(this, damage, CanRiposte);
|
if (other->CheckHitChance(this, skillinuse, Hand, chance_mod)) {
|
||||||
other->MeleeMitigation(this, damage, min_hit);
|
other->MeleeMitigation(this, damage, min_hit);
|
||||||
if(damage > 0)
|
|
||||||
CommonOutgoingHitSuccess(other, damage, skillinuse);
|
CommonOutgoingHitSuccess(other, damage, skillinuse);
|
||||||
|
} else {
|
||||||
|
damage = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damage == -3) {
|
|
||||||
DoRiposte(other);
|
|
||||||
if (HasDied())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
damage = -5;
|
damage = -5;
|
||||||
|
|
||||||
other->AddToHateList(this, hate);
|
|
||||||
|
|
||||||
bool CanSkillProc = true;
|
bool CanSkillProc = true;
|
||||||
if (skillinuse == SkillOffense){ //Hack to allow damage to display.
|
if (skillinuse == SkillOffense){ //Hack to allow damage to display.
|
||||||
skillinuse = SkillTigerClaw; //'strike' your opponent - Arbitrary choice for message.
|
skillinuse = SkillTigerClaw; //'strike' your opponent - Arbitrary choice for message.
|
||||||
@ -2442,19 +2433,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);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -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() ||
|
||||||
@ -443,31 +443,10 @@ void NPC::NextGuardPosition() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// we need this for charmed NPCs
|
|
||||||
void Mob::SaveSpawnSpot() {
|
|
||||||
spawn_x = x_pos;
|
|
||||||
spawn_y = y_pos;
|
|
||||||
spawn_z = z_pos;
|
|
||||||
spawn_heading = heading;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*float Mob::CalculateDistanceToNextWaypoint() {
|
|
||||||
return CalculateDistance(cur_wp_x, cur_wp_y, cur_wp_z);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
float Mob::CalculateDistance(float x, float y, float z) {
|
float Mob::CalculateDistance(float x, float y, float z) {
|
||||||
return (float)sqrtf( ((m_Position.x-x)*(m_Position.x-x)) + ((m_Position.y-y)*(m_Position.y-y)) + ((m_Position.z-z)*(m_Position.z-z)) );
|
return (float)sqrtf( ((m_Position.x-x)*(m_Position.x-x)) + ((m_Position.y-y)*(m_Position.y-y)) + ((m_Position.z-z)*(m_Position.z-z)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
uint8 NPC::CalculateHeadingToNextWaypoint() {
|
|
||||||
return CalculateHeadingToTarget(cur_wp_x, cur_wp_y);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
float Mob::CalculateHeadingToTarget(float in_x, float in_y) {
|
float Mob::CalculateHeadingToTarget(float in_x, float in_y) {
|
||||||
float angle;
|
float angle;
|
||||||
|
|
||||||
@ -521,7 +500,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;
|
||||||
@ -597,7 +576,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
pRunAnimSpeed = speed;
|
pRunAnimSpeed = speed;
|
||||||
if(IsClient())
|
if(IsClient())
|
||||||
{
|
{
|
||||||
animation = speed;
|
animation = speed / 2;
|
||||||
}
|
}
|
||||||
//pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO);
|
//pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO);
|
||||||
//speed *= NPC_SPEED_MULTIPLIER;
|
//speed *= NPC_SPEED_MULTIPLIER;
|
||||||
@ -611,7 +590,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
tar_vector = (float)speed / mag;
|
tar_vector = (float)speed / mag;
|
||||||
|
|
||||||
// mob move fix
|
// mob move fix
|
||||||
int numsteps = (int) ( mag * 16.0f / (float)speed);
|
int numsteps = (int) ( mag * 16.0f / (float)speed + 0.5f);
|
||||||
|
|
||||||
|
|
||||||
// mob move fix
|
// mob move fix
|
||||||
@ -621,9 +600,9 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
if (numsteps>1)
|
if (numsteps>1)
|
||||||
{
|
{
|
||||||
tar_vector=1.0f ;
|
tar_vector=1.0f ;
|
||||||
m_TargetV.x = 1.25f * m_TargetV.x/(float)numsteps;
|
m_TargetV.x = m_TargetV.x/(float)numsteps;
|
||||||
m_TargetV.y = 1.25f * m_TargetV.y/(float)numsteps;
|
m_TargetV.y = m_TargetV.y/(float)numsteps;
|
||||||
m_TargetV.z = 1.25f *m_TargetV.z/(float)numsteps;
|
m_TargetV.z = m_TargetV.z/(float)numsteps;
|
||||||
|
|
||||||
float new_x = m_Position.x + m_TargetV.x;
|
float new_x = m_Position.x + m_TargetV.x;
|
||||||
float new_y = m_Position.y + m_TargetV.y;
|
float new_y = m_Position.y + m_TargetV.y;
|
||||||
@ -636,7 +615,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
m_Position.y = new_y;
|
m_Position.y = new_y;
|
||||||
m_Position.z = new_z;
|
m_Position.z = new_z;
|
||||||
m_Position.w = CalculateHeadingToTarget(x, y);
|
m_Position.w = CalculateHeadingToTarget(x, y);
|
||||||
tar_ndx = 22 - numsteps;
|
tar_ndx = 20 - numsteps;
|
||||||
Log.Out(Logs::Detail, Logs::AI, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.x, m_Position.y, m_Position.z, numsteps);
|
Log.Out(Logs::Detail, Logs::AI, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.x, m_Position.y, m_Position.z, numsteps);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -656,6 +635,11 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
tar_vector/=16.0f;
|
tar_vector/=16.0f;
|
||||||
|
float dur = Timer::GetCurrentTime() - pLastChange;
|
||||||
|
if(dur < 1.0f) {
|
||||||
|
dur = 1.0f;
|
||||||
|
}
|
||||||
|
tar_vector = (tar_vector * AImovement_duration) / 100.0f;
|
||||||
|
|
||||||
float new_x = m_Position.x + m_TargetV.x*tar_vector;
|
float new_x = m_Position.x + m_TargetV.x*tar_vector;
|
||||||
float new_y = m_Position.y + m_TargetV.y*tar_vector;
|
float new_y = m_Position.y + m_TargetV.y*tar_vector;
|
||||||
@ -717,8 +701,6 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// force an update now
|
|
||||||
move_tic_count = RuleI(Zone, NPCPositonUpdateTicCount);
|
|
||||||
SendPosUpdate();
|
SendPosUpdate();
|
||||||
SetAppearance(eaStanding, false);
|
SetAppearance(eaStanding, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1931,10 +1931,10 @@ bool WorldServer::SendChannelMessage(Client* from, const char* to, uint8 chan_nu
|
|||||||
|
|
||||||
bool WorldServer::SendEmoteMessage(const char* to, uint32 to_guilddbid, uint32 type, const char* message, ...) {
|
bool WorldServer::SendEmoteMessage(const char* to, uint32 to_guilddbid, uint32 type, const char* message, ...) {
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
char buffer[256];
|
char buffer[4096] = { 0 };
|
||||||
|
|
||||||
va_start(argptr, message);
|
va_start(argptr, message);
|
||||||
vsnprintf(buffer, 256, message, argptr);
|
vsnprintf(buffer, sizeof(buffer) - 1, message, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
return SendEmoteMessage(to, to_guilddbid, 0, type, buffer);
|
return SendEmoteMessage(to, to_guilddbid, 0, type, buffer);
|
||||||
@ -1942,10 +1942,10 @@ bool WorldServer::SendEmoteMessage(const char* to, uint32 to_guilddbid, uint32 t
|
|||||||
|
|
||||||
bool WorldServer::SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...) {
|
bool WorldServer::SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...) {
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
char buffer[256];
|
char buffer[4096] = { 0 };
|
||||||
|
|
||||||
va_start(argptr, message);
|
va_start(argptr, message);
|
||||||
vsnprintf(buffer, 256, message, argptr);
|
vsnprintf(buffer, sizeof(buffer) - 1, message, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
if (!Connected() && to == 0) {
|
if (!Connected() && to == 0) {
|
||||||
|
|||||||
@ -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