mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
merge upstream
This commit is contained in:
commit
cd9ca65587
@ -1,7 +1,70 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 01/08/2015 ==
|
||||
Trevius: Added some extra checks and clean-up related to Groups and Mercenaries.
|
||||
|
||||
== 01/07/2015 ==
|
||||
Uleat: Excluded text link body from message scrambling in Client::GarbleMessage()
|
||||
Trevius: Mercenaries now load directly from tables only. The vwMercNpcTypes view is no longer required and can be deleted.
|
||||
Trevius: Query fix for group_leaders table. This may resolve some crashes/bugs related to Mercs/Bots and Groups.
|
||||
|
||||
== 01/06/2015 ==
|
||||
Trevius: Changed the pet command #defines to be based on RoF2 list of pet commands and added decodes to Titanium, SoF and SoD.
|
||||
Trevius: (RoF+) The /pet focus on/off and /pet hold on/off commands are now functional.
|
||||
Trevius: Added defines for all remaining pet commands and some support for them as well.
|
||||
|
||||
== 01/05/2015 ==
|
||||
Uleat: Fixed (added translators for) item/text links. Only 'OP_ChannelMessage' and 'OP_SpecialMesg' are currently handled..more text channels will be added as the need arises.
|
||||
|
||||
== 01/03/2015 ==
|
||||
Trevius: (RoF2) /shield (shielding) and /key (key ring) are both now functional after opcode updates.
|
||||
|
||||
== 01/02/2015 ==
|
||||
Trevius: (RoF2) *Hopefully* Fixed looting incorrect items from NPCs. Please report any issues!
|
||||
Trevius: (RoF2) Now able to loot items past the 10th slot on NPC corpses.
|
||||
Trevius: Attuned Items can now be auto-looted and will equip properly.
|
||||
Trevius: Mercenaries and Bots will no longer take a share from /split or /autosplit.
|
||||
|
||||
== 12/30/2014 ==
|
||||
Trevius: (RoF2) Aug Type 21 no longer shows the "Buy Now" button in the aug slot of items.
|
||||
Trevius: (RoF2) Identified the "Copied" item flag with the help of Uleat.
|
||||
|
||||
== 12/29/2014 ==
|
||||
Trevius: (RoF2) Identified a few Item Fields and resolved an issue with cloth armor not accepting certain augments that they should.
|
||||
Akkadius: Updated $client->UpdateTaskActivity to have optional argument ignore_quest_update IE: Client::UpdateTaskActivity(THIS, TaskID, ActivityID, Count, [ignore_quest_update])
|
||||
Akkadius: Also updated internal UpdateTaskActivity methods to optionally ignore quest based task updates to prevent feedback
|
||||
|
||||
== 12/28/2014 ==
|
||||
Uleat: Implemented class Client::TextLink as a replacement for the dozens of individual link formatters.
|
||||
|
||||
== 12/27/2014 ==
|
||||
Akkadius: Add option to automatic database upgrade script 5) Download latest Opcodes from Github
|
||||
Trevius: (RoF2) Fixed dropping items on the ground so they go to ground level instead of camera height.
|
||||
Trevius: Show Helm Option should be functional again.
|
||||
Kayen: Implemened npc special ability (43) CASTING_RESIST_DIFF which sets innate resist modifier on
|
||||
ALL spells used by that NPC. Ie. 43,1,-200 will set a -200 innate resist diff, so if your npc cast
|
||||
a spell that has a -10 resist modifier the final resist diff would be -210.
|
||||
|
||||
== 12/25/2014 ==
|
||||
Uleat: Updated 'links' code for all clients
|
||||
|
||||
== 12/24/2014 ==
|
||||
Trevius: (RoF+) Added herosforgemodel field to the npc_types table.
|
||||
Trevius: (RoF2) Updated item links from #npcstat command output.
|
||||
Trevius: (RoF+) Implemented Hero's Forge Armor for NPCs. Set the herosforgemodel field in npc_types table to the model (example: 84 for full set, or 12107 for robe).
|
||||
Trevius: (RoF+) Hero's Forge Armor now overrides NPC texture settings. To display Hero's Forge Armor Helms, set helmtexture field to anything other than 0.
|
||||
|
||||
== 12/23/2014 ==
|
||||
Uleat: Tidied up some ItemInst* declarations and added some nullptr checks.
|
||||
Trevius: (RoF+) Added support for Hero's Forge Robe Models. Set herosforgemodel field in items table to exact model such as 11607, 11707, etc.
|
||||
|
||||
== 12/22/2014 ==
|
||||
Trevius: (RoF2) Fixed Tracking.
|
||||
Trevius: (RoF+) Added a work-around for the cursor buffer issue.
|
||||
|
||||
== 12/21/2014 ==
|
||||
Trevius: (RoF2) Fixed Extended Targets Window by correcting opcodes.
|
||||
Trevius: (RoF/RoF2) Fixed Guild Rank in the Player Profile, which prevents the guild rank message on login/zone.
|
||||
|
||||
== 12/20/2014 ==
|
||||
Akkadius: Updated #cvs to display RoF2 Client Stream count
|
||||
|
||||
@ -33,22 +33,22 @@ int main(int argc, char **argv) {
|
||||
RegisterExecutablePlatform(ExePlatformClientExport);
|
||||
set_exception_handler();
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "Client Files Export Utility");
|
||||
LogFile->write(EQEmuLog::Status, "Client Files Export Utility");
|
||||
if(!EQEmuConfig::LoadConfig()) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to load configuration file.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to load configuration file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EQEmuConfig *config = EQEmuConfig::get();
|
||||
if(!load_log_settings(config->LogSettingsFile.c_str())) {
|
||||
LogFile->write(EQEMuLog::Error, "Warning: unable to read %s.", config->LogSettingsFile.c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Warning: unable to read %s.", config->LogSettingsFile.c_str());
|
||||
}
|
||||
|
||||
SharedDatabase database;
|
||||
LogFile->write(EQEMuLog::Status, "Connecting to database...");
|
||||
LogFile->write(EQEmuLog::Status, "Connecting to database...");
|
||||
if(!database.Connect(config->DatabaseHost.c_str(), config->DatabaseUsername.c_str(),
|
||||
config->DatabasePassword.c_str(), config->DatabaseDB.c_str(), config->DatabasePort)) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to connect to the database, cannot continue without a "
|
||||
LogFile->write(EQEmuLog::Error, "Unable to connect to the database, cannot continue without a "
|
||||
"database connection");
|
||||
return 1;
|
||||
}
|
||||
@ -61,11 +61,11 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
void ExportSpells(SharedDatabase *db) {
|
||||
LogFile->write(EQEMuLog::Status, "Exporting Spells...");
|
||||
LogFile->write(EQEmuLog::Status, "Exporting Spells...");
|
||||
|
||||
FILE *f = fopen("export/spells_us.txt", "w");
|
||||
if(!f) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to open export/spells_us.txt to write, skipping.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to open export/spells_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ void ExportSpells(SharedDatabase *db) {
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
}
|
||||
} else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ExportSpells query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ExportSpells query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
@ -103,7 +103,7 @@ bool SkillUsable(SharedDatabase *db, int skill_id, int class_id) {
|
||||
class_id, skill_id);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in skill_usable query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in skill_usable query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) {
|
||||
class_id, skill_id, level);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in get_skill query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in get_skill query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -135,11 +135,11 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) {
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase *db) {
|
||||
LogFile->write(EQEMuLog::Status, "Exporting Skill Caps...");
|
||||
LogFile->write(EQEmuLog::Status, "Exporting Skill Caps...");
|
||||
|
||||
FILE *f = fopen("export/SkillCaps.txt", "w");
|
||||
if(!f) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -164,11 +164,11 @@ void ExportSkillCaps(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ExportBaseData(SharedDatabase *db) {
|
||||
LogFile->write(EQEMuLog::Status, "Exporting Base Data...");
|
||||
LogFile->write(EQEmuLog::Status, "Exporting Base Data...");
|
||||
|
||||
FILE *f = fopen("export/BaseData.txt", "w");
|
||||
if(!f) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to open export/BaseData.txt to write, skipping.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to open export/BaseData.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ void ExportBaseData(SharedDatabase *db) {
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
}
|
||||
} else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ExportBaseData query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ExportBaseData query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
@ -32,22 +32,22 @@ int main(int argc, char **argv) {
|
||||
RegisterExecutablePlatform(ExePlatformClientImport);
|
||||
set_exception_handler();
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "Client Files Import Utility");
|
||||
LogFile->write(EQEmuLog::Status, "Client Files Import Utility");
|
||||
if(!EQEmuConfig::LoadConfig()) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to load configuration file.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to load configuration file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EQEmuConfig *config = EQEmuConfig::get();
|
||||
if(!load_log_settings(config->LogSettingsFile.c_str())) {
|
||||
LogFile->write(EQEMuLog::Error, "Warning: unable to read %s.", config->LogSettingsFile.c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Warning: unable to read %s.", config->LogSettingsFile.c_str());
|
||||
}
|
||||
|
||||
SharedDatabase database;
|
||||
LogFile->write(EQEMuLog::Status, "Connecting to database...");
|
||||
LogFile->write(EQEmuLog::Status, "Connecting to database...");
|
||||
if(!database.Connect(config->DatabaseHost.c_str(), config->DatabaseUsername.c_str(),
|
||||
config->DatabasePassword.c_str(), config->DatabaseDB.c_str(), config->DatabasePort)) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to connect to the database, cannot continue without a "
|
||||
LogFile->write(EQEmuLog::Error, "Unable to connect to the database, cannot continue without a "
|
||||
"database connection");
|
||||
return 1;
|
||||
}
|
||||
@ -64,7 +64,7 @@ int GetSpellColumns(SharedDatabase *db) {
|
||||
const std::string query = "DESCRIBE spells_new";
|
||||
auto results = db->QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetSpellColumns query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in GetSpellColumns query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -72,10 +72,10 @@ int GetSpellColumns(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ImportSpells(SharedDatabase *db) {
|
||||
LogFile->write(EQEMuLog::Status, "Importing Spells...");
|
||||
LogFile->write(EQEmuLog::Status, "Importing Spells...");
|
||||
FILE *f = fopen("import/spells_us.txt", "r");
|
||||
if(!f) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to open import/spells_us.txt to read, skipping.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to open import/spells_us.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -138,23 +138,23 @@ void ImportSpells(SharedDatabase *db) {
|
||||
|
||||
spells_imported++;
|
||||
if(spells_imported % 1000 == 0) {
|
||||
LogFile->write(EQEMuLog::Status, "%d spells imported.", spells_imported);
|
||||
LogFile->write(EQEmuLog::Status, "%d spells imported.", spells_imported);
|
||||
}
|
||||
}
|
||||
|
||||
if(spells_imported % 1000 != 0) {
|
||||
LogFile->write(EQEMuLog::Status, "%d spells imported.", spells_imported);
|
||||
LogFile->write(EQEmuLog::Status, "%d spells imported.", spells_imported);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ImportSkillCaps(SharedDatabase *db) {
|
||||
LogFile->write(EQEMuLog::Status, "Importing Skill Caps...");
|
||||
LogFile->write(EQEmuLog::Status, "Importing Skill Caps...");
|
||||
|
||||
FILE *f = fopen("import/SkillCaps.txt", "r");
|
||||
if(!f) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to open import/SkillCaps.txt to read, skipping.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to open import/SkillCaps.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -186,11 +186,11 @@ void ImportSkillCaps(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ImportBaseData(SharedDatabase *db) {
|
||||
LogFile->write(EQEMuLog::Status, "Importing Base Data...");
|
||||
LogFile->write(EQEmuLog::Status, "Importing Base Data...");
|
||||
|
||||
FILE *f = fopen("import/BaseData.txt", "r");
|
||||
if(!f) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to open import/BaseData.txt to read, skipping.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to open import/BaseData.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
LogFile->write(EQEMuLog::Crash, buffer);
|
||||
LogFile->write(EQEmuLog::Crash, buffer);
|
||||
StackWalker::OnOutput(szText);
|
||||
}
|
||||
};
|
||||
@ -34,67 +34,67 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_ACCESS_VIOLATION");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_ACCESS_VIOLATION");
|
||||
break;
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
|
||||
break;
|
||||
case EXCEPTION_BREAKPOINT:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_BREAKPOINT");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_BREAKPOINT");
|
||||
break;
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_DATATYPE_MISALIGNMENT");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_DATATYPE_MISALIGNMENT");
|
||||
break;
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_DENORMAL_OPERAND");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_FLT_DENORMAL_OPERAND");
|
||||
break;
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_DIVIDE_BY_ZERO");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_FLT_DIVIDE_BY_ZERO");
|
||||
break;
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_INEXACT_RESULT");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_FLT_INEXACT_RESULT");
|
||||
break;
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_INVALID_OPERATION");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_FLT_INVALID_OPERATION");
|
||||
break;
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_OVERFLOW");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_FLT_OVERFLOW");
|
||||
break;
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_STACK_CHECK");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_FLT_STACK_CHECK");
|
||||
break;
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_UNDERFLOW");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_FLT_UNDERFLOW");
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_ILLEGAL_INSTRUCTION");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_ILLEGAL_INSTRUCTION");
|
||||
break;
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_IN_PAGE_ERROR");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_IN_PAGE_ERROR");
|
||||
break;
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_INT_DIVIDE_BY_ZERO");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_INT_DIVIDE_BY_ZERO");
|
||||
break;
|
||||
case EXCEPTION_INT_OVERFLOW:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_INT_OVERFLOW");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_INT_OVERFLOW");
|
||||
break;
|
||||
case EXCEPTION_INVALID_DISPOSITION:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_INVALID_DISPOSITION");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_INVALID_DISPOSITION");
|
||||
break;
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_NONCONTINUABLE_EXCEPTION");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_NONCONTINUABLE_EXCEPTION");
|
||||
break;
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_PRIV_INSTRUCTION");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_PRIV_INSTRUCTION");
|
||||
break;
|
||||
case EXCEPTION_SINGLE_STEP:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_SINGLE_STEP");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_SINGLE_STEP");
|
||||
break;
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
LogFile->write(EQEMuLog::Crash, "EXCEPTION_STACK_OVERFLOW");
|
||||
LogFile->write(EQEmuLog::Crash, "EXCEPTION_STACK_OVERFLOW");
|
||||
break;
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Crash, "Unknown Exception");
|
||||
LogFile->write(EQEmuLog::Crash, "Unknown Exception");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -84,12 +84,12 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c
|
||||
uint32 errnum= 0;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
if (!Open(host, user, passwd, database, port, &errnum, errbuf)) {
|
||||
LogFile->write(EQEMuLog::Error, "Failed to connect to database: Error: %s", errbuf);
|
||||
LogFile->write(EQEmuLog::Error, "Failed to connect to database: Error: %s", errbuf);
|
||||
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Status, "Using database '%s' at %s:%d",database,host,port);
|
||||
LogFile->write(EQEmuLog::Status, "Using database '%s' at %s:%d",database,host,port);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -706,7 +706,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
|
||||
charid = GetCharacterID(pp->name);
|
||||
|
||||
if(!charid) {
|
||||
LogFile->write(EQEMuLog::Error, "StoreCharacter: no character id");
|
||||
LogFile->write(EQEmuLog::Error, "StoreCharacter: no character id");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -736,10 +736,10 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
|
||||
auto results = QueryDatabase(invquery);
|
||||
|
||||
if (!results.RowsAffected())
|
||||
LogFile->write(EQEMuLog::Error, "StoreCharacter inventory failed. Query '%s' %s", invquery.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "StoreCharacter inventory failed. Query '%s' %s", invquery.c_str(), results.ErrorMessage().c_str());
|
||||
#if EQDEBUG >= 9
|
||||
else
|
||||
LogFile->write(EQEMuLog::Debug, "StoreCharacter inventory succeeded. Query '%s'", invquery.c_str());
|
||||
LogFile->write(EQEmuLog::Debug, "StoreCharacter inventory succeeded. Query '%s'", invquery.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -805,7 +805,7 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
|
||||
std::string query = StringFormat("SELECT `account_id` FROM `character_data` WHERE `id` = %i LIMIT 1", char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetAccountIDByChar query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in GetAccountIDByChar query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3162,28 +3162,28 @@ void Database::SetLFP(uint32 CharID, bool LFP) {
|
||||
std::string query = StringFormat("UPDATE `character_data` SET `lfp` = %i WHERE `id` = %i",LFP, CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Database::SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon) {
|
||||
std::string query = StringFormat("update `character_data` SET `lfp` = %i, `lfg` = %i, `firstlogon` = %i WHERE `id` = %i",LFP, LFG, firstlogon, CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Database::SetLFG(uint32 CharID, bool LFG) {
|
||||
std::string query = StringFormat("update `character_data` SET `lfg` = %i WHERE `id` = %i",LFG, CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Database::SetFirstLogon(uint32 CharID, uint8 firstlogon) {
|
||||
std::string query = StringFormat( "UPDATE `character_data` SET `firstlogon` = %i WHERE `id` = %i",firstlogon, CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error updating firstlogon for character %i : %s", CharID, results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error updating firstlogon for character %i : %s", CharID, results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Database::AddReport(std::string who, std::string against, std::string lines) {
|
||||
@ -3195,7 +3195,7 @@ void Database::AddReport(std::string who, std::string against, std::string lines
|
||||
safe_delete_array(escape_str);
|
||||
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error adding a report for %s: %s", who.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error adding a report for %s: %s", who.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc) {
|
||||
@ -3206,7 +3206,7 @@ void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ism
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
@ -3216,7 +3216,7 @@ void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ism
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error adding character to group id: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error adding character to group id: %s", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Database::ClearAllGroups(void)
|
||||
@ -3255,13 +3255,13 @@ uint32 Database::GetGroupID(const char* name){
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error getting group id: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error getting group id: %s", results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Debug, "Character not in a group: %s", name);
|
||||
LogFile->write(EQEmuLog::Debug, "Character not in a group: %s", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3303,12 +3303,12 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) {
|
||||
return;
|
||||
}
|
||||
|
||||
query = StringFormat("INSERT INTO group_leaders(gid, leadername, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%u, '%s', '', '', '', '', '', '', '0')",
|
||||
query = StringFormat("REPLACE INTO group_leaders(gid, leadername, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%u, '%s', '', '', '', '', '', '', '0')",
|
||||
gid, EscapeString(name).c_str());
|
||||
result = QueryDatabase(query);
|
||||
|
||||
if(!result.Success()) {
|
||||
LogFile->write(EQEMuLog::Debug, "Error in Database::SetGroupLeaderName: %s", result.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Debug, "Error in Database::SetGroupLeaderName: %s", result.ErrorMessage().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -4048,7 +4048,7 @@ void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &ch
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetCharactersInInstace query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in GetCharactersInInstace query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
167
common/debug.cpp
167
common/debug.cpp
@ -9,6 +9,31 @@
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
|
||||
#include <conio.h>
|
||||
#include <iostream>
|
||||
#include <dos.h>
|
||||
|
||||
namespace ConsoleColor {
|
||||
enum Colors {
|
||||
Black = 0,
|
||||
Blue = 1,
|
||||
Green = 2,
|
||||
Cyan = 3,
|
||||
Red = 4,
|
||||
Magenta = 5,
|
||||
Brown = 6,
|
||||
LightGray = 7,
|
||||
DarkGray = 8,
|
||||
LightBlue = 9,
|
||||
LightGreen = 10,
|
||||
LightCyan = 11,
|
||||
LightRed = 12,
|
||||
LightMagenta = 13,
|
||||
Yellow = 14,
|
||||
White = 15,
|
||||
};
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -25,13 +50,13 @@
|
||||
#endif
|
||||
|
||||
static volatile bool logFileValid = false;
|
||||
static EQEMuLog realLogFile;
|
||||
EQEMuLog *LogFile = &realLogFile;
|
||||
static EQEmuLog realLogFile;
|
||||
EQEmuLog *LogFile = &realLogFile;
|
||||
|
||||
static const char* FileNames[EQEMuLog::MaxLogID] = { "logs/eqemu", "logs/eqemu", "logs/eqemu_error", "logs/eqemu_debug", "logs/eqemu_quest", "logs/eqemu_commands", "logs/crash" };
|
||||
static const char* LogNames[EQEMuLog::MaxLogID] = { "Status", "Normal", "Error", "Debug", "Quest", "Command", "Crash" };
|
||||
static const char* FileNames[EQEmuLog::MaxLogID] = { "logs/eqemu", "logs/eqemu", "logs/eqemu_error", "logs/eqemu_debug", "logs/eqemu_quest", "logs/eqemu_commands", "logs/crash" };
|
||||
static const char* LogNames[EQEmuLog::MaxLogID] = { "Status", "Normal", "Error", "Debug", "Quest", "Command", "Crash" };
|
||||
|
||||
EQEMuLog::EQEMuLog()
|
||||
EQEmuLog::EQEmuLog()
|
||||
{
|
||||
for (int i = 0; i < MaxLogID; i++) {
|
||||
fp[i] = 0;
|
||||
@ -39,17 +64,17 @@ EQEMuLog::EQEMuLog()
|
||||
logCallbackBuf[i] = nullptr;
|
||||
logCallbackPva[i] = nullptr;
|
||||
}
|
||||
pLogStatus[EQEMuLog::LogIDs::Status] = LOG_LEVEL_STATUS;
|
||||
pLogStatus[EQEMuLog::LogIDs::Normal] = LOG_LEVEL_NORMAL;
|
||||
pLogStatus[EQEMuLog::LogIDs::Error] = LOG_LEVEL_ERROR;
|
||||
pLogStatus[EQEMuLog::LogIDs::Debug] = LOG_LEVEL_DEBUG;
|
||||
pLogStatus[EQEMuLog::LogIDs::Quest] = LOG_LEVEL_QUEST;
|
||||
pLogStatus[EQEMuLog::LogIDs::Commands] = LOG_LEVEL_COMMANDS;
|
||||
pLogStatus[EQEMuLog::LogIDs::Crash] = LOG_LEVEL_CRASH;
|
||||
pLogStatus[EQEmuLog::LogIDs::Status] = LOG_LEVEL_STATUS;
|
||||
pLogStatus[EQEmuLog::LogIDs::Normal] = LOG_LEVEL_NORMAL;
|
||||
pLogStatus[EQEmuLog::LogIDs::Error] = LOG_LEVEL_ERROR;
|
||||
pLogStatus[EQEmuLog::LogIDs::Debug] = LOG_LEVEL_DEBUG;
|
||||
pLogStatus[EQEmuLog::LogIDs::Quest] = LOG_LEVEL_QUEST;
|
||||
pLogStatus[EQEmuLog::LogIDs::Commands] = LOG_LEVEL_COMMANDS;
|
||||
pLogStatus[EQEmuLog::LogIDs::Crash] = LOG_LEVEL_CRASH;
|
||||
logFileValid = true;
|
||||
}
|
||||
|
||||
EQEMuLog::~EQEMuLog()
|
||||
EQEmuLog::~EQEmuLog()
|
||||
{
|
||||
logFileValid = false;
|
||||
for (int i = 0; i < MaxLogID; i++) {
|
||||
@ -60,7 +85,7 @@ EQEMuLog::~EQEMuLog()
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEMuLog::open(LogIDs id)
|
||||
bool EQEmuLog::open(LogIDs id)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return false;
|
||||
@ -112,7 +137,7 @@ bool EQEMuLog::open(LogIDs id)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEMuLog::write(LogIDs id, const char *fmt, ...)
|
||||
bool EQEmuLog::write(LogIDs id, const char *fmt, ...)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return false;
|
||||
@ -156,15 +181,45 @@ bool EQEMuLog::write(LogIDs id, const char *fmt, ...)
|
||||
if (pLogStatus[id] & 8) {
|
||||
fprintf(stderr, "[%s] ", LogNames[id]);
|
||||
vfprintf( stderr, fmt, argptr );
|
||||
} else {
|
||||
}
|
||||
/* This is what's outputted to console */
|
||||
else {
|
||||
|
||||
#ifdef _WINDOWS
|
||||
HANDLE console_handle;
|
||||
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
CONSOLE_FONT_INFOEX info = { 0 };
|
||||
info.cbSize = sizeof(info);
|
||||
info.dwFontSize.Y = 12; // leave X as zero
|
||||
info.FontWeight = FW_NORMAL;
|
||||
wcscpy(info.FaceName, L"Lucida Console");
|
||||
SetCurrentConsoleFontEx(console_handle, NULL, &info);
|
||||
|
||||
if (id == EQEmuLog::LogIDs::Status){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::Yellow); }
|
||||
if (id == EQEmuLog::LogIDs::Error){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightRed); }
|
||||
if (id == EQEmuLog::LogIDs::Normal){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightGreen); }
|
||||
if (id == EQEmuLog::LogIDs::Debug){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::Yellow); }
|
||||
if (id == EQEmuLog::LogIDs::Quest){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightCyan); }
|
||||
if (id == EQEmuLog::LogIDs::Commands){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightMagenta); }
|
||||
if (id == EQEmuLog::LogIDs::Crash){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightRed); }
|
||||
#endif
|
||||
|
||||
fprintf(stdout, "[%s] ", LogNames[id]);
|
||||
vfprintf( stdout, fmt, argptr );
|
||||
|
||||
#ifdef _WINDOWS
|
||||
/* Always set back to white*/
|
||||
SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::White);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
va_end(argptr);
|
||||
if (dofile) {
|
||||
fprintf(fp[id], "\n");
|
||||
}
|
||||
|
||||
/* Print Lind Endings */
|
||||
if (pLogStatus[id] & 2) {
|
||||
if (pLogStatus[id] & 8) {
|
||||
fprintf(stderr, "\n");
|
||||
@ -181,7 +236,7 @@ bool EQEMuLog::write(LogIDs id, const char *fmt, ...)
|
||||
}
|
||||
|
||||
//write with Prefix and a VA_list
|
||||
bool EQEMuLog::writePVA(LogIDs id, const char *prefix, const char *fmt, va_list argptr)
|
||||
bool EQEmuLog::writePVA(LogIDs id, const char *prefix, const char *fmt, va_list argptr)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return false;
|
||||
@ -223,9 +278,38 @@ bool EQEMuLog::writePVA(LogIDs id, const char *prefix, const char *fmt, va_list
|
||||
if (pLogStatus[id] & 8) {
|
||||
fprintf(stderr, "[%s] %s", LogNames[id], prefix);
|
||||
vfprintf( stderr, fmt, argptr );
|
||||
} else {
|
||||
}
|
||||
/* Console Output */
|
||||
else {
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
HANDLE console_handle;
|
||||
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
CONSOLE_FONT_INFOEX info = { 0 };
|
||||
info.cbSize = sizeof(info);
|
||||
info.dwFontSize.Y = 12; // leave X as zero
|
||||
info.FontWeight = FW_NORMAL;
|
||||
wcscpy(info.FaceName, L"Lucida Console");
|
||||
SetCurrentConsoleFontEx(console_handle, NULL, &info);
|
||||
|
||||
if (id == EQEmuLog::LogIDs::Status){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::Yellow); }
|
||||
if (id == EQEmuLog::LogIDs::Error){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightRed); }
|
||||
if (id == EQEmuLog::LogIDs::Normal){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightGreen); }
|
||||
if (id == EQEmuLog::LogIDs::Debug){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::Yellow); }
|
||||
if (id == EQEmuLog::LogIDs::Quest){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightCyan); }
|
||||
if (id == EQEmuLog::LogIDs::Commands){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightMagenta); }
|
||||
if (id == EQEmuLog::LogIDs::Crash){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightRed); }
|
||||
#endif
|
||||
|
||||
fprintf(stdout, "[%s] %s", LogNames[id], prefix);
|
||||
vfprintf( stdout, fmt, argptr );
|
||||
vfprintf(stdout, fmt, argptr);
|
||||
|
||||
#ifdef _WINDOWS
|
||||
/* Always set back to white*/
|
||||
SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::White);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
va_end(argptr);
|
||||
@ -245,7 +329,7 @@ bool EQEMuLog::writePVA(LogIDs id, const char *prefix, const char *fmt, va_list
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEMuLog::writebuf(LogIDs id, const char *buf, uint8 size, uint32 count)
|
||||
bool EQEmuLog::writebuf(LogIDs id, const char *buf, uint8 size, uint32 count)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return false;
|
||||
@ -288,9 +372,36 @@ bool EQEMuLog::writebuf(LogIDs id, const char *buf, uint8 size, uint32 count)
|
||||
fwrite(buf, size, count, stderr);
|
||||
fprintf(stderr, "\n");
|
||||
} else {
|
||||
#ifdef _WINDOWS
|
||||
HANDLE console_handle;
|
||||
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
CONSOLE_FONT_INFOEX info = { 0 };
|
||||
info.cbSize = sizeof(info);
|
||||
info.dwFontSize.Y = 12; // leave X as zero
|
||||
info.FontWeight = FW_NORMAL;
|
||||
wcscpy(info.FaceName, L"Lucida Console");
|
||||
SetCurrentConsoleFontEx(console_handle, NULL, &info);
|
||||
|
||||
if (id == EQEmuLog::LogIDs::Status){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::Yellow); }
|
||||
if (id == EQEmuLog::LogIDs::Error){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightRed); }
|
||||
if (id == EQEmuLog::LogIDs::Normal){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightGreen); }
|
||||
if (id == EQEmuLog::LogIDs::Debug){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightGreen); }
|
||||
if (id == EQEmuLog::LogIDs::Quest){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightCyan); }
|
||||
if (id == EQEmuLog::LogIDs::Commands){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightMagenta); }
|
||||
if (id == EQEmuLog::LogIDs::Crash){ SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::LightRed); }
|
||||
#endif
|
||||
|
||||
fprintf(stdout, "[%s] ", LogNames[id]);
|
||||
fwrite(buf, size, count, stdout);
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
#ifdef _WINDOWS
|
||||
/* Always set back to white*/
|
||||
SetConsoleTextAttribute(console_handle, ConsoleColor::Colors::White);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (dofile) {
|
||||
@ -299,7 +410,7 @@ bool EQEMuLog::writebuf(LogIDs id, const char *buf, uint8 size, uint32 count)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEMuLog::writeNTS(LogIDs id, bool dofile, const char *fmt, ...)
|
||||
bool EQEmuLog::writeNTS(LogIDs id, bool dofile, const char *fmt, ...)
|
||||
{
|
||||
va_list argptr, tmpargptr;
|
||||
va_start(argptr, fmt);
|
||||
@ -318,7 +429,7 @@ bool EQEMuLog::writeNTS(LogIDs id, bool dofile, const char *fmt, ...)
|
||||
return true;
|
||||
};
|
||||
|
||||
bool EQEMuLog::Dump(LogIDs id, uint8* data, uint32 size, uint32 cols, uint32 skip)
|
||||
bool EQEmuLog::Dump(LogIDs id, uint8* data, uint32 size, uint32 cols, uint32 skip)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
#if EQDEBUG >= 10
|
||||
@ -386,7 +497,7 @@ bool EQEMuLog::Dump(LogIDs id, uint8* data, uint32 size, uint32 cols, uint32 ski
|
||||
return true;
|
||||
}
|
||||
|
||||
void EQEMuLog::SetCallback(LogIDs id, msgCallbackFmt proc)
|
||||
void EQEmuLog::SetCallback(LogIDs id, msgCallbackFmt proc)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return;
|
||||
@ -397,7 +508,7 @@ void EQEMuLog::SetCallback(LogIDs id, msgCallbackFmt proc)
|
||||
logCallbackFmt[id] = proc;
|
||||
}
|
||||
|
||||
void EQEMuLog::SetCallback(LogIDs id, msgCallbackBuf proc)
|
||||
void EQEmuLog::SetCallback(LogIDs id, msgCallbackBuf proc)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return;
|
||||
@ -408,7 +519,7 @@ void EQEMuLog::SetCallback(LogIDs id, msgCallbackBuf proc)
|
||||
logCallbackBuf[id] = proc;
|
||||
}
|
||||
|
||||
void EQEMuLog::SetCallback(LogIDs id, msgCallbackPva proc)
|
||||
void EQEmuLog::SetCallback(LogIDs id, msgCallbackPva proc)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return;
|
||||
@ -419,7 +530,7 @@ void EQEMuLog::SetCallback(LogIDs id, msgCallbackPva proc)
|
||||
logCallbackPva[id] = proc;
|
||||
}
|
||||
|
||||
void EQEMuLog::SetAllCallbacks(msgCallbackFmt proc)
|
||||
void EQEmuLog::SetAllCallbacks(msgCallbackFmt proc)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return;
|
||||
@ -430,7 +541,7 @@ void EQEMuLog::SetAllCallbacks(msgCallbackFmt proc)
|
||||
}
|
||||
}
|
||||
|
||||
void EQEMuLog::SetAllCallbacks(msgCallbackBuf proc)
|
||||
void EQEmuLog::SetAllCallbacks(msgCallbackBuf proc)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return;
|
||||
@ -441,7 +552,7 @@ void EQEMuLog::SetAllCallbacks(msgCallbackBuf proc)
|
||||
}
|
||||
}
|
||||
|
||||
void EQEMuLog::SetAllCallbacks(msgCallbackPva proc)
|
||||
void EQEmuLog::SetAllCallbacks(msgCallbackPva proc)
|
||||
{
|
||||
if (!logFileValid) {
|
||||
return;
|
||||
|
||||
@ -74,10 +74,10 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
class EQEMuLog {
|
||||
class EQEmuLog {
|
||||
public:
|
||||
EQEMuLog();
|
||||
~EQEMuLog();
|
||||
EQEmuLog();
|
||||
~EQEmuLog();
|
||||
|
||||
enum LogIDs {
|
||||
Status = 0, /* This must stay the first entry in this list */
|
||||
@ -128,7 +128,7 @@ private:
|
||||
msgCallbackPva logCallbackPva[MaxLogID];
|
||||
};
|
||||
|
||||
extern EQEMuLog* LogFile;
|
||||
extern EQEmuLog* LogFile;
|
||||
|
||||
#ifdef _EQDEBUG
|
||||
class PerformanceMonitor {
|
||||
|
||||
@ -149,6 +149,8 @@ public:
|
||||
static const uint32 BANDOLIER_SIZE = Titanium::consts::BANDOLIER_SIZE; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = Titanium::consts::POTION_BELT_SIZE;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
||||
|
||||
// legacy-related functions
|
||||
//static int ServerToPerlSlot(int slot); // encode
|
||||
//static int PerlToServerSlot(int slot); // decode
|
||||
|
||||
@ -1509,7 +1509,8 @@ enum ItemPacketType
|
||||
ItemPacketTributeItem = 0x6C,
|
||||
ItemPacketMerchant = 0x64,
|
||||
ItemPacketWorldContainer = 0x6B,
|
||||
ItemPacketCharmUpdate = 0x6E
|
||||
ItemPacketCharmUpdate = 0x6E,
|
||||
ItemPacketInvalid = 0xFF
|
||||
};
|
||||
struct ItemPacket_Struct
|
||||
{
|
||||
@ -3015,14 +3016,14 @@ struct ClientError_Struct
|
||||
};
|
||||
|
||||
struct Track_Struct {
|
||||
uint16 entityid;
|
||||
uint16 padding002;
|
||||
uint32 entityid;
|
||||
float distance;
|
||||
// Fields for SoD and later
|
||||
uint8 level;
|
||||
uint8 NPC;
|
||||
uint8 GroupMember;
|
||||
uint8 is_npc;
|
||||
char name[64];
|
||||
uint8 is_pet;
|
||||
uint8 is_merc;
|
||||
};
|
||||
|
||||
struct Tracking_Struct {
|
||||
@ -5268,6 +5269,23 @@ struct ClientMarqueeMessage_Struct {
|
||||
|
||||
typedef std::list<ServerLootItem_Struct*> ItemList;
|
||||
|
||||
struct TextLinkBody_Struct {
|
||||
// Current server mask: EQClientRoF2
|
||||
uint8 unknown_1; /* %1X */
|
||||
uint32 item_id; /* %05X */
|
||||
uint32 augment_1; /* %05X */
|
||||
uint32 augment_2; /* %05X */
|
||||
uint32 augment_3; /* %05X */
|
||||
uint32 augment_4; /* %05X */
|
||||
uint32 augment_5; /* %05X */
|
||||
uint32 augment_6; /* %05X */
|
||||
uint8 is_evolving; /* %1X */
|
||||
uint32 evolve_group; /* %05X */
|
||||
uint8 evolve_level; /* %02X */
|
||||
uint32 ornament_icon; /* %05X */
|
||||
int hash; /* %08X */
|
||||
};
|
||||
|
||||
// Restore structure packing to default
|
||||
#pragma pack()
|
||||
|
||||
|
||||
@ -987,7 +987,7 @@ EQRawApplicationPacket *p=nullptr;
|
||||
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
|
||||
#if EQDEBUG >= 4
|
||||
if(emu_op == OP_Unknown) {
|
||||
LogFile->write(EQEMuLog::Debug, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode);
|
||||
LogFile->write(EQEmuLog::Debug, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode);
|
||||
}
|
||||
#endif
|
||||
p->SetOpcode(emu_op);
|
||||
|
||||
@ -140,7 +140,7 @@ bool EQTime::saveFile(const char *filename)
|
||||
of.open(filename);
|
||||
if(!of)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename);
|
||||
LogFile->write(EQEmuLog::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename);
|
||||
return false;
|
||||
}
|
||||
//Enable for debugging
|
||||
@ -164,14 +164,14 @@ bool EQTime::loadFile(const char *filename)
|
||||
in.open(filename);
|
||||
if(!in)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Could not load EQTime file %s", filename);
|
||||
LogFile->write(EQEmuLog::Error, "Could not load EQTime file %s", filename);
|
||||
return false;
|
||||
}
|
||||
in >> version;
|
||||
in.ignore(80, '\n');
|
||||
if(version != EQT_VERSION)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "'%s' is NOT a valid EQTime file. File version is %i, EQTime version is %i", filename, version, EQT_VERSION);
|
||||
LogFile->write(EQEmuLog::Error, "'%s' is NOT a valid EQTime file. File version is %i, EQTime version is %i", filename, version, EQT_VERSION);
|
||||
return false;
|
||||
}
|
||||
//in >> eqTime.start_eqtime.day;
|
||||
|
||||
@ -337,7 +337,7 @@ uint32 BaseGuildManager::_GetFreeGuildID() {
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in _GetFreeGuildID query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in _GetFreeGuildID query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -89,6 +89,17 @@ ItemInst* ItemInstQueue::pop()
|
||||
return inst;
|
||||
}
|
||||
|
||||
// Remove item from back of queue
|
||||
ItemInst* ItemInstQueue::pop_back()
|
||||
{
|
||||
if (m_list.size() == 0)
|
||||
return nullptr;
|
||||
|
||||
ItemInst* inst = m_list.back();
|
||||
m_list.pop_back();
|
||||
return inst;
|
||||
}
|
||||
|
||||
// Look at item at front of queue
|
||||
ItemInst* ItemInstQueue::peek_front() const
|
||||
{
|
||||
@ -259,6 +270,11 @@ int16 Inventory::PushCursor(const ItemInst& inst)
|
||||
return MainCursor;
|
||||
}
|
||||
|
||||
ItemInst* Inventory::GetCursorItem()
|
||||
{
|
||||
return m_cursor.peek_front();
|
||||
}
|
||||
|
||||
// Swap items in inventory
|
||||
bool Inventory::SwapItem(int16 slot_a, int16 slot_b)
|
||||
{
|
||||
@ -1135,7 +1151,7 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
|
||||
}
|
||||
|
||||
if (result == INVALID_INDEX) {
|
||||
LogFile->write(EQEMuLog::Error, "Inventory::_PutItem: Invalid slot_id specified (%i)", slot_id);
|
||||
LogFile->write(EQEmuLog::Error, "Inventory::_PutItem: Invalid slot_id specified (%i)", slot_id);
|
||||
Inventory::MarkDirty(inst); // Slot not found, clean up
|
||||
}
|
||||
|
||||
@ -1170,13 +1186,13 @@ int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, ui
|
||||
|
||||
for (itb = inst->_begin(); itb != inst->_end(); ++itb) {
|
||||
ItemInst* baginst = itb->second;
|
||||
if (baginst->GetID() == item_id) {
|
||||
if (baginst && baginst->GetID() == item_id) {
|
||||
quantity_found += (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges();
|
||||
if (quantity_found >= quantity)
|
||||
return Inventory::CalcSlotId(it->first, itb->first);
|
||||
}
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
if (baginst->GetAugmentItemID(i) == item_id && quantity <= 1)
|
||||
if (baginst && baginst->GetAugmentItemID(i) == item_id && quantity <= 1)
|
||||
return legacy::SLOT_AUGMENT; // Only one augment per slot.
|
||||
}
|
||||
}
|
||||
@ -1214,13 +1230,13 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
|
||||
|
||||
for (itb = inst->_begin(); itb != inst->_end(); ++itb) {
|
||||
ItemInst* baginst = itb->second;
|
||||
if (baginst->GetID() == item_id) {
|
||||
if (baginst && baginst->GetID() == item_id) {
|
||||
quantity_found += (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges();
|
||||
if (quantity_found >= quantity)
|
||||
return Inventory::CalcSlotId(MainCursor, itb->first);
|
||||
}
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
if (baginst->GetAugmentItemID(i) == item_id && quantity <= 1)
|
||||
if (baginst && baginst->GetAugmentItemID(i) == item_id && quantity <= 1)
|
||||
return legacy::SLOT_AUGMENT; // Only one augment per slot.
|
||||
}
|
||||
|
||||
@ -1314,7 +1330,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
|
||||
if (inst->GetItem()->LoreGroup == loregroup)
|
||||
return it->first;
|
||||
|
||||
ItemInst* Aug;
|
||||
ItemInst* Aug = nullptr;
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
Aug = inst->GetAugment(i);
|
||||
if (Aug && Aug->GetItem()->LoreGroup == loregroup)
|
||||
@ -1329,7 +1345,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
|
||||
if (baginst && baginst->IsType(ItemClassCommon) && baginst->GetItem()->LoreGroup == loregroup)
|
||||
return Inventory::CalcSlotId(it->first, itb->first);
|
||||
|
||||
ItemInst* Aug2;
|
||||
ItemInst* Aug2 = nullptr;
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
Aug2 = baginst->GetAugment(i);
|
||||
if (Aug2 && Aug2->GetItem()->LoreGroup == loregroup)
|
||||
@ -1357,7 +1373,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
if (inst->GetItem()->LoreGroup == loregroup)
|
||||
return MainCursor;
|
||||
|
||||
ItemInst* Aug;
|
||||
ItemInst* Aug = nullptr;
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
Aug = inst->GetAugment(i);
|
||||
if (Aug && Aug->GetItem()->LoreGroup == loregroup)
|
||||
@ -1373,7 +1389,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
return Inventory::CalcSlotId(MainCursor, itb->first);
|
||||
|
||||
|
||||
ItemInst* Aug2;
|
||||
ItemInst* Aug2 = nullptr;
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
Aug2 = baginst->GetAugment(i);
|
||||
if (Aug2 && Aug2->GetItem()->LoreGroup == loregroup)
|
||||
@ -1703,6 +1719,8 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent)
|
||||
end = m_contents.end();
|
||||
for (; cur != end;) {
|
||||
ItemInst* inst = cur->second;
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
del = cur;
|
||||
++cur;
|
||||
|
||||
@ -93,6 +93,7 @@ public:
|
||||
void push(ItemInst* inst);
|
||||
void push_front(ItemInst* inst);
|
||||
ItemInst* pop();
|
||||
ItemInst* pop_back();
|
||||
ItemInst* peek_front() const;
|
||||
inline int size() { return static_cast<int>(m_list.size()); }
|
||||
|
||||
@ -152,6 +153,9 @@ public:
|
||||
// Add item to cursor queue
|
||||
int16 PushCursor(const ItemInst& inst);
|
||||
|
||||
// Get cursor item in front of queue
|
||||
ItemInst* GetCursorItem();
|
||||
|
||||
// Swap items in inventory
|
||||
bool SwapItem(int16 slot_a, int16 slot_b);
|
||||
|
||||
|
||||
@ -35,6 +35,6 @@ void log_message(LogType type, const char *fmt, ...) {
|
||||
void log_messageVA(LogType type, const char *fmt, va_list args) {
|
||||
std::string prefix_buffer = StringFormat("[%s] ", log_type_info[type].name);
|
||||
|
||||
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args);
|
||||
LogFile->writePVA(EQEmuLog::Debug, prefix_buffer.c_str(), fmt, args);
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,12 @@ namespace RoF
|
||||
static inline uint32 RoFToServerMainInvSlot(structs::MainInvItemSlotStruct RoFSlot);
|
||||
static inline uint32 RoFToServerCorpseSlot(uint32 RoFCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@ -488,7 +494,13 @@ namespace RoF
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToRoFTextLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
@ -501,7 +513,7 @@ namespace RoF
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->skill_in_language);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->message);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
@ -2315,7 +2327,7 @@ namespace RoF
|
||||
outapp->WriteUInt8(emu->gm);
|
||||
|
||||
outapp->WriteUInt32(emu->guild_id);
|
||||
outapp->WriteUInt8(0); // Unknown - observed 1 in a live packet.
|
||||
outapp->WriteUInt8(emu->guildrank); // guildrank
|
||||
outapp->WriteUInt32(0); // Unknown - observed 1 in a live packet.
|
||||
outapp->WriteUInt8(0); // Unknown - observed 1 in a live packet.
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
@ -2576,7 +2588,7 @@ namespace RoF
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
@ -2643,7 +2655,7 @@ namespace RoF
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_ReadBook)
|
||||
@ -2900,7 +2912,7 @@ namespace RoF
|
||||
{
|
||||
eq->entries[i] = emu->entries[i];
|
||||
}
|
||||
eq->entries[21] = 0;
|
||||
eq->entries[21] = 1;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -3096,6 +3108,44 @@ namespace RoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToRoFTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@ -3294,9 +3344,9 @@ namespace RoF
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->entityid);
|
||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, emu->distance);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->level);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_npc);
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->name);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->GroupMember);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_merc);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
@ -4041,7 +4091,13 @@ namespace RoF
|
||||
|
||||
uint32 Skill = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
RoFToServerTextLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
@ -4050,7 +4106,7 @@ namespace RoF
|
||||
emu->language = Language;
|
||||
emu->chan_num = Channel;
|
||||
emu->skill_in_language = Skill;
|
||||
strcpy(emu->message, InBuffer);
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
@ -4456,47 +4512,8 @@ namespace RoF
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x00:
|
||||
emu->command = 0x04; // Health
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x10; // Leader
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x07; // Attack
|
||||
break;
|
||||
case 0x04:
|
||||
emu->command = 0x08; // Follow
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // Guard
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x09; // Sit. Needs work. This appears to be a toggle between Sit/Stand now.
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0b; // Taunt
|
||||
break;
|
||||
case 0x0f:
|
||||
emu->command = 0x0c; // Hold
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x1b; // Hold on
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x1c; // Hold off
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x01; // Back
|
||||
break;
|
||||
case 0x1d:
|
||||
emu->command = 0x02; // Leave/Go Away
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
IN(command);
|
||||
emu->unknown = eq->unknown04;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@ -4854,27 +4871,8 @@ namespace RoF
|
||||
ss.write((const char*)&evotop, sizeof(RoF::structs::EvolvingItem));
|
||||
}
|
||||
//ORNAMENT IDFILE / ICON
|
||||
uint16 ornaIcon = 0;
|
||||
int32 heroModel = 0;
|
||||
/*
|
||||
if (inst->GetOrnamentationAug(ornamentationAugtype))
|
||||
{
|
||||
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
//Mainhand
|
||||
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
//Offhand
|
||||
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
//Icon
|
||||
ornaIcon = aug_weap->Icon;
|
||||
if (aug_weap->HerosForgeModel > 0)
|
||||
{
|
||||
heroModel = (aug_weap->HerosForgeModel * 100) + Inventory::CalcMaterialFromSlot(slot_id_in);
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
uint32 ornaIcon = 0;
|
||||
uint32 heroModel = 0;
|
||||
|
||||
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon())
|
||||
{
|
||||
@ -4896,8 +4894,6 @@ namespace RoF
|
||||
|
||||
RoF::structs::ItemSerializationHeaderFinish hdrf;
|
||||
hdrf.ornamentIcon = ornaIcon;
|
||||
hdrf.unknown061 = 0;
|
||||
hdrf.unknown062 = 0;
|
||||
hdrf.unknowna1 = 0xffffffff;
|
||||
hdrf.ornamentHeroModel = heroModel;
|
||||
hdrf.unknown063 = 0;
|
||||
@ -5506,7 +5502,6 @@ namespace RoF
|
||||
|
||||
static inline uint32 ServerToRoFCorpseSlot(uint32 ServerCorpse)
|
||||
{
|
||||
//uint32 RoFCorpse;
|
||||
return (ServerCorpse + 1);
|
||||
}
|
||||
|
||||
@ -5647,8 +5642,80 @@ namespace RoF
|
||||
|
||||
static inline uint32 RoFToServerCorpseSlot(uint32 RoFCorpse)
|
||||
{
|
||||
//uint32 ServerCorpse;
|
||||
return (RoFCorpse - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
rofTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||
// Diff: ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 41).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(43).c_str());
|
||||
|
||||
rofTextLink.push_back(delimiter);
|
||||
rofTextLink.append(new_segment.c_str());
|
||||
rofTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
rofTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (rofTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = rofTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(rofTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 42 47 (Source)
|
||||
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 41).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(41).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace RoF
|
||||
|
||||
@ -21,18 +21,24 @@ namespace RoF2
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth);
|
||||
char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth, ItemPacketType packet_type);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot);
|
||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot, ItemPacketType PacketType = ItemPacketInvalid);
|
||||
static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 ServerSlot);
|
||||
static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse);
|
||||
|
||||
// client to server inventory location converters
|
||||
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot);
|
||||
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot, ItemPacketType PacketType = ItemPacketInvalid);
|
||||
static inline uint32 RoF2ToServerMainInvSlot(structs::MainInvItemSlotStruct RoF2Slot);
|
||||
static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@ -116,6 +122,72 @@ namespace RoF2
|
||||
#include "ss_define.h"
|
||||
|
||||
// ENCODE methods
|
||||
|
||||
|
||||
// RoF2 Specific Encodes Begin
|
||||
ENCODE(OP_SendMembershipDetails)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Membership_Details_Struct);
|
||||
SETUP_DIRECT_ENCODE(Membership_Details_Struct, structs::Membership_Details_Struct);
|
||||
|
||||
eq->membership_setting_count = 72;
|
||||
for (uint32 i = 0; i < emu->membership_setting_count; ++i) // 66
|
||||
{
|
||||
OUT(settings[i].setting_index);
|
||||
OUT(settings[i].setting_id);
|
||||
OUT(settings[i].setting_value);
|
||||
}
|
||||
// Last 6 new settings fields are all 0s on Live as of 12/29/14
|
||||
|
||||
eq->race_entry_count = emu->race_entry_count;
|
||||
for (uint32 i = 0; i < emu->race_entry_count; ++i) // 15
|
||||
{
|
||||
OUT(membership_races[i].purchase_id);
|
||||
OUT(membership_races[i].bitwise_entry);
|
||||
}
|
||||
|
||||
eq->class_entry_count = emu->class_entry_count;
|
||||
for (uint32 i = 0; i < emu->class_entry_count; ++i) // 15
|
||||
{
|
||||
OUT(membership_classes[i].purchase_id);
|
||||
OUT(membership_classes[i].bitwise_entry);
|
||||
}
|
||||
|
||||
eq->exit_url_length = emu->exit_url_length;
|
||||
eq->exit_url_length2 = emu->exit_url_length2;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SendMembership)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Membership_Struct);
|
||||
SETUP_DIRECT_ENCODE(Membership_Struct, structs::Membership_Struct);
|
||||
|
||||
eq->membership = emu->membership;
|
||||
eq->races = emu->races;
|
||||
eq->classes = emu->classes;
|
||||
eq->entrysize = 25; //emu->entrysize;
|
||||
|
||||
for (uint32 i = 0; i < emu->entrysize; ++i) // 21
|
||||
{
|
||||
OUT(entries[i]);
|
||||
}
|
||||
// Last 4 new entries are 0s on Live Silver as of 12/29/14
|
||||
// Setting them each to 1 for now.
|
||||
// This removes the "Buy Now" button from aug type 21 slots on items.
|
||||
for (uint32 i = 21; i < 25; ++i) // 4
|
||||
{
|
||||
eq->entries[i] = 1;
|
||||
}
|
||||
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
// RoF2 Specific Encodes End
|
||||
|
||||
|
||||
ENCODE(OP_Action)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Action_Struct);
|
||||
@ -488,7 +560,13 @@ namespace RoF2
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToRoF2TextLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
@ -501,7 +579,7 @@ namespace RoF2
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->skill_in_language);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->message);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
@ -556,7 +634,7 @@ namespace RoF2
|
||||
|
||||
uint32 Length = 0;
|
||||
|
||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory);
|
||||
|
||||
if (Serialized) {
|
||||
|
||||
@ -1370,7 +1448,7 @@ namespace RoF2
|
||||
InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
|
||||
|
||||
uint32 length;
|
||||
char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0);
|
||||
char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType);
|
||||
|
||||
if (!serialized) {
|
||||
_log(NET__STRUCTS, "Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
@ -1676,8 +1754,15 @@ namespace RoF2
|
||||
eq->FogDensity = emu->fog_density;
|
||||
|
||||
/*fill in some unknowns with observed values, hopefully it will help */
|
||||
eq->unknown569 = 0;
|
||||
eq->unknown571 = 0;
|
||||
eq->unknown572 = 4;
|
||||
eq->unknown576 = 2;
|
||||
eq->unknown580 = 0;
|
||||
|
||||
eq->unknown800 = -1;
|
||||
eq->unknown844 = 600;
|
||||
eq->unknown848 = 2008; // Guild Lobby observed value
|
||||
eq->unknown880 = 50;
|
||||
eq->unknown884 = 10;
|
||||
eq->unknown888 = 1;
|
||||
@ -1987,17 +2072,17 @@ namespace RoF2
|
||||
outapp->WriteUInt32(emu->drakkin_tattoo);
|
||||
outapp->WriteUInt32(emu->drakkin_details);
|
||||
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt8(0); // Unknown 0
|
||||
outapp->WriteUInt8(0xff); // Unknown 0xff
|
||||
outapp->WriteUInt8(1); // Unknown 1
|
||||
outapp->WriteUInt8(0xff); // Unknown 0xff
|
||||
outapp->WriteUInt8(1); // Unknown 1
|
||||
|
||||
outapp->WriteFloat(5.0f); // Height ?
|
||||
outapp->WriteFloat(5.0f); // Height
|
||||
|
||||
outapp->WriteFloat(3.0f); // Unknown
|
||||
outapp->WriteFloat(2.5f); // Unknown
|
||||
outapp->WriteFloat(5.5f); // Unknown
|
||||
outapp->WriteFloat(3.0f); // Unknown 3.0
|
||||
outapp->WriteFloat(2.5f); // Unknown 2.5
|
||||
outapp->WriteFloat(5.5f); // Unknown 5.5
|
||||
|
||||
outapp->WriteUInt32(0); // Primary ?
|
||||
outapp->WriteUInt32(0); // Secondary ?
|
||||
@ -2316,14 +2401,14 @@ namespace RoF2
|
||||
outapp->WriteUInt8(emu->gm);
|
||||
outapp->WriteUInt32(emu->guild_id);
|
||||
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt8(emu->guildrank); // guildrank
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
|
||||
outapp->WriteUInt64(emu->exp); // int32 in client
|
||||
|
||||
outapp->WriteUInt8(0); // Unknown - Seen 5 on Live
|
||||
outapp->WriteUInt8(5); // Unknown - Seen 5 on Live - Eye Height?
|
||||
|
||||
outapp->WriteUInt32(emu->platinum_bank);
|
||||
outapp->WriteUInt32(emu->gold_bank);
|
||||
@ -2587,7 +2672,7 @@ namespace RoF2
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
@ -2654,7 +2739,7 @@ namespace RoF2
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_ReadBook)
|
||||
@ -2898,24 +2983,6 @@ namespace RoF2
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SendMembership)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Membership_Struct);
|
||||
SETUP_DIRECT_ENCODE(Membership_Struct, structs::Membership_Struct);
|
||||
|
||||
eq->membership = emu->membership;
|
||||
eq->races = emu->races;
|
||||
eq->classes = emu->classes;
|
||||
eq->entrysize = 22;
|
||||
for (int i = 0; i<21; i++)
|
||||
{
|
||||
eq->entries[i] = emu->entries[i];
|
||||
}
|
||||
eq->entries[21] = 0;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SendZonepoints)
|
||||
{
|
||||
SETUP_VAR_ENCODE(ZonePoints);
|
||||
@ -3107,6 +3174,44 @@ namespace RoF2
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToRoF2TextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@ -3289,7 +3394,7 @@ namespace RoF2
|
||||
int PacketSize = 2;
|
||||
|
||||
for (int i = 0; i < EntryCount; ++i, ++emu)
|
||||
PacketSize += (12 + strlen(emu->name));
|
||||
PacketSize += (13 + strlen(emu->name));
|
||||
|
||||
emu = (Track_Struct *)__emu_buffer;
|
||||
|
||||
@ -3305,9 +3410,10 @@ namespace RoF2
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->entityid);
|
||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, emu->distance);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->level);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_npc);
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->name);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->GroupMember);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_pet);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_merc);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
@ -3734,7 +3840,7 @@ namespace RoF2
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->drakkin_tattoo);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->drakkin_details);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->equip_chest2); // unknown8
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->equip_chest2);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown9
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown10
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->helm); // unknown11
|
||||
@ -4057,7 +4163,13 @@ namespace RoF2
|
||||
|
||||
uint32 Skill = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
RoF2ToServerTextLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
@ -4066,7 +4178,7 @@ namespace RoF2
|
||||
emu->language = Language;
|
||||
emu->chan_num = Channel;
|
||||
emu->skill_in_language = Skill;
|
||||
strcpy(emu->message, InBuffer);
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
@ -4471,47 +4583,8 @@ namespace RoF2
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x00:
|
||||
emu->command = 0x04; // Health
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x10; // Leader
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x07; // Attack
|
||||
break;
|
||||
case 0x04:
|
||||
emu->command = 0x08; // Follow
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // Guard
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x09; // Sit. Needs work. This appears to be a toggle between Sit/Stand now.
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0b; // Taunt
|
||||
break;
|
||||
case 0x0f:
|
||||
emu->command = 0x0c; // Hold
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x1b; // Hold on
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x1c; // Hold off
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x01; // Back
|
||||
break;
|
||||
case 0x1d:
|
||||
emu->command = 0x02; // Leave/Go Away
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
IN(command);
|
||||
emu->unknown = eq->unknown04;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@ -4811,7 +4884,7 @@ namespace RoF2
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth)
|
||||
char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth, ItemPacketType packet_type)
|
||||
{
|
||||
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
uint8 null_term = 0;
|
||||
@ -4835,15 +4908,14 @@ namespace RoF2
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
hdr.unknown004 = 0;
|
||||
|
||||
structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in);
|
||||
structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in, packet_type);
|
||||
|
||||
hdr.slot_type = (merchant_slot == 0) ? slot_id.SlotType : 9; // 9 is merchant 20 is reclaim items?
|
||||
hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot;
|
||||
hdr.sub_slot = (merchant_slot == 0) ? slot_id.SubSlot : 0xffff;
|
||||
hdr.unknown013 = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff;
|
||||
hdr.aug_slot = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff;
|
||||
hdr.price = inst->GetPrice();
|
||||
hdr.merchant_slot = (merchant_slot == 0) ? 1 : inst->GetMerchantCount();
|
||||
//hdr.merchant_slot = (merchant_slot == 0) ? 1 : 0xffffffff;
|
||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||
hdr.unknown028 = 0;
|
||||
@ -4869,28 +4941,9 @@ namespace RoF2
|
||||
ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem));
|
||||
}
|
||||
//ORNAMENT IDFILE / ICON
|
||||
uint16 ornaIcon = 0;
|
||||
int32 heroModel = 0;
|
||||
/*
|
||||
if (inst->GetOrnamentationAug(ornamentationAugtype))
|
||||
{
|
||||
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
//Mainhand
|
||||
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
//Offhand
|
||||
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
//Icon
|
||||
ornaIcon = aug_weap->Icon;
|
||||
if (aug_weap->HerosForgeModel > 0)
|
||||
{
|
||||
heroModel = (aug_weap->HerosForgeModel * 100) + Inventory::CalcMaterialFromSlot(slot_id_in);
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
|
||||
uint32 ornaIcon = 0;
|
||||
uint32 heroModel = 0;
|
||||
|
||||
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon())
|
||||
{
|
||||
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
|
||||
@ -4911,12 +4964,10 @@ namespace RoF2
|
||||
|
||||
RoF2::structs::ItemSerializationHeaderFinish hdrf;
|
||||
hdrf.ornamentIcon = ornaIcon;
|
||||
hdrf.unknown061 = 0;
|
||||
hdrf.unknown062 = 0;
|
||||
hdrf.unknowna1 = 0xffffffff;
|
||||
hdrf.ornamentHeroModel = heroModel;
|
||||
hdrf.unknown063 = 0;
|
||||
hdrf.unknowna3 = 0;
|
||||
hdrf.Copied = 0;
|
||||
hdrf.unknowna4 = 0xffffffff;
|
||||
hdrf.unknowna5 = 0;
|
||||
hdrf.ItemClass = item->ItemClass;
|
||||
@ -5066,7 +5117,7 @@ namespace RoF2
|
||||
memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
|
||||
|
||||
isbs.augtype = item->AugType;
|
||||
isbs.augdistiller = 65535;
|
||||
isbs.augrestrict2 = -1;
|
||||
isbs.augrestrict = item->AugRestrict;
|
||||
|
||||
for (int x = AUG_BEGIN; x < consts::ITEM_COMMON_SIZE; x++)
|
||||
@ -5310,9 +5361,21 @@ namespace RoF2
|
||||
iqbs.HealAmt = item->HealAmt;
|
||||
iqbs.SpellDmg = item->SpellDmg;
|
||||
iqbs.clairvoyance = item->Clairvoyance;
|
||||
iqbs.unknown28 = 0;
|
||||
iqbs.unknown30 = 0;
|
||||
iqbs.unknown37a = 0;
|
||||
|
||||
//unknown18; //Power Source Capacity or evolve filename?
|
||||
//evolve_string; // Some String, but being evolution related is just a guess
|
||||
|
||||
iqbs.Heirloom = 0;
|
||||
iqbs.Placeable = 0;
|
||||
|
||||
iqbs.unknown28 = -1;
|
||||
iqbs.unknown30 = -1;
|
||||
|
||||
iqbs.NoZone = 0;
|
||||
iqbs.NoGround = 0;
|
||||
iqbs.unknown37a = 0; // (guessed position) New to RoF2
|
||||
iqbs.unknown38 = 0;
|
||||
|
||||
iqbs.unknown39 = 1;
|
||||
|
||||
iqbs.subitem_count = 0;
|
||||
@ -5350,7 +5413,7 @@ namespace RoF2
|
||||
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
||||
*/
|
||||
|
||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
|
||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1, packet_type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5376,7 +5439,7 @@ namespace RoF2
|
||||
return item_serial;
|
||||
}
|
||||
|
||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot)
|
||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot, ItemPacketType PacketType)
|
||||
{
|
||||
structs::ItemSlotStruct RoF2Slot;
|
||||
RoF2Slot.SlotType = INVALID_INDEX;
|
||||
@ -5389,13 +5452,21 @@ namespace RoF2
|
||||
uint32 TempSlot = 0;
|
||||
|
||||
if (ServerSlot < 56 || ServerSlot == MainPowerSource) { // Main Inventory and Cursor
|
||||
RoF2Slot.SlotType = maps::MapPossessions;
|
||||
RoF2Slot.MainSlot = ServerSlot;
|
||||
|
||||
if (PacketType == ItemPacketLoot)
|
||||
{
|
||||
RoF2Slot.SlotType = maps::MapCorpse;
|
||||
RoF2Slot.MainSlot = ServerSlot - EmuConstants::CORPSE_BEGIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
RoF2Slot.SlotType = maps::MapPossessions;
|
||||
RoF2Slot.MainSlot = ServerSlot;
|
||||
}
|
||||
|
||||
if (ServerSlot == MainPowerSource)
|
||||
RoF2Slot.MainSlot = slots::MainPowerSource;
|
||||
|
||||
else if (ServerSlot >= MainCursor) // Cursor and Extended Corpse Inventory
|
||||
else if (ServerSlot >= MainCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory
|
||||
RoF2Slot.MainSlot += 3;
|
||||
|
||||
else if (ServerSlot >= MainAmmo) // (> 20)
|
||||
@ -5522,11 +5593,10 @@ namespace RoF2
|
||||
|
||||
static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse)
|
||||
{
|
||||
//uint32 RoF2Corpse;
|
||||
return (ServerCorpse + 1);
|
||||
return (ServerCorpse - EmuConstants::CORPSE_BEGIN + 1);
|
||||
}
|
||||
|
||||
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot)
|
||||
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot, ItemPacketType PacketType)
|
||||
{
|
||||
uint32 ServerSlot = INVALID_INDEX;
|
||||
uint32 TempSlot = 0;
|
||||
@ -5621,6 +5691,10 @@ namespace RoF2
|
||||
ServerSlot = INVALID_INDEX;
|
||||
}
|
||||
|
||||
else if (RoF2Slot.SlotType == maps::MapCorpse) {
|
||||
ServerSlot = RoF2Slot.MainSlot + EmuConstants::CORPSE_BEGIN;
|
||||
}
|
||||
|
||||
_log(NET__ERROR, "Convert RoF2 Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", RoF2Slot.SlotType, RoF2Slot.Unknown02, RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01, ServerSlot);
|
||||
|
||||
return ServerSlot;
|
||||
@ -5663,8 +5737,71 @@ namespace RoF2
|
||||
|
||||
static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse)
|
||||
{
|
||||
//uint32 ServerCorpse;
|
||||
return (RoF2Corpse - 1);
|
||||
return (RoF2Corpse + EmuConstants::CORPSE_BEGIN - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
rof2TextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff:
|
||||
|
||||
new_segment.append(segments[segment_iter]);
|
||||
|
||||
rof2TextLink.push_back(delimiter);
|
||||
rof2TextLink.append(new_segment.c_str());
|
||||
rof2TextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
rof2TextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (rof2TextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = rof2TextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(rof2TextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff:
|
||||
|
||||
new_segment.append(segments[segment_iter]);
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace RoF2
|
||||
|
||||
@ -181,6 +181,8 @@ namespace RoF2 {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
// out-going packets that require an ENCODE translation:
|
||||
// Begin RoF2 Encodes
|
||||
|
||||
E(OP_SendMembershipDetails)
|
||||
|
||||
// incoming packets that require a DECODE translation:
|
||||
// Begin RoF2 Decodes
|
||||
|
||||
@ -93,6 +95,7 @@ E(OP_SkillUpdate)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_TaskDescription)
|
||||
|
||||
@ -243,11 +243,11 @@ struct Membership_Setting_Struct
|
||||
struct Membership_Details_Struct
|
||||
{
|
||||
/*0000*/ uint32 membership_setting_count; // Seen 66
|
||||
/*0016*/ Membership_Setting_Struct settings[66];
|
||||
/*0016*/ Membership_Setting_Struct settings[72]; // 864 Bytes
|
||||
/*0012*/ uint32 race_entry_count; // Seen 15
|
||||
/*1044*/ Membership_Entry_Struct membership_races[15];
|
||||
/*1044*/ Membership_Entry_Struct membership_races[15]; // 120 Bytes
|
||||
/*0012*/ uint32 class_entry_count; // Seen 15
|
||||
/*1044*/ Membership_Entry_Struct membership_classes[15];
|
||||
/*1044*/ Membership_Entry_Struct membership_classes[15]; // 120 Bytes
|
||||
/*1044*/ uint32 exit_url_length; // Length of the exit_url string (0 for none)
|
||||
/*1048*/ //char exit_url[42]; // Upgrade to Silver or Gold Membership URL
|
||||
/*1048*/ uint32 exit_url_length2; // Length of the exit_url2 string (0 for none)
|
||||
@ -260,7 +260,7 @@ struct Membership_Struct
|
||||
/*004*/ uint32 races; // Seen ff ff 01 00
|
||||
/*008*/ uint32 classes; // Seen ff ff 01 01
|
||||
/*012*/ uint32 entrysize; // Seen 22
|
||||
/*016*/ int32 entries[22]; // Most -1, 1, and 0 for Gold Status
|
||||
/*016*/ int32 entries[25]; // Most -1, 1, and 0 for Gold Status
|
||||
/*104*/
|
||||
};
|
||||
|
||||
@ -537,9 +537,13 @@ struct NewZone_Struct {
|
||||
/*0525*/ uint8 rain_duration[4];
|
||||
/*0529*/ uint8 snow_chance[4];
|
||||
/*0533*/ uint8 snow_duration[4];
|
||||
/*0537*/ uint8 unknown537[33];
|
||||
/*0537*/ uint8 unknown537[32]; // Seen all 0xff
|
||||
/*0569*/ uint8 unknown569; // Unknown - Seen 0
|
||||
/*0570*/ uint8 sky; // Sky Type
|
||||
/*0571*/ uint8 unknown571[13]; // ***Placeholder
|
||||
/*0571*/ uint8 unknown571; // Unknown - Seen 0
|
||||
/*0572*/ uint32 unknown572; // Unknown - Seen 4 in Guild Lobby
|
||||
/*0576*/ uint32 unknown576; // Unknown - Seen 2 in Guild Lobby
|
||||
/*0580*/ uint32 unknown580; // Unknown - Seen 0 in Guild Lobby
|
||||
/*0584*/ float zone_exp_multiplier; // Experience Multiplier
|
||||
/*0588*/ float safe_y; // Zone Safe Y
|
||||
/*0592*/ float safe_x; // Zone Safe X
|
||||
@ -554,7 +558,7 @@ struct NewZone_Struct {
|
||||
/*0800*/ int32 unknown800; //seen -1
|
||||
/*0804*/ char unknown804[40]; //
|
||||
/*0844*/ int32 unknown844; //seen 600
|
||||
/*0848*/ int32 unknown848;
|
||||
/*0848*/ int32 unknown848; //seen 2008
|
||||
/*0852*/ uint16 zone_id;
|
||||
/*0854*/ uint16 zone_instance;
|
||||
/*0856*/ char unknown856[20];
|
||||
@ -581,7 +585,7 @@ struct NewZone_Struct {
|
||||
/*0932*/ int32 unknown932; // Seen -1
|
||||
/*0936*/ int32 unknown936; // Seen -1
|
||||
/*0940*/ uint32 unknown940; // Seen 0
|
||||
/*0944*/ float unknown944; // Seen 1.0
|
||||
/*0944*/ float unknown944; // Seen 1.0 in PoK, and 0.25 in Guild Lobby
|
||||
/*0948*/ uint32 unknown948; // Seen 0 - New on Live as of Dec 15 2014
|
||||
/*0952*/ uint32 unknown952; // Seen 100 - New on Live as of Dec 15 2014
|
||||
/*0956*/
|
||||
@ -880,6 +884,12 @@ struct Disciplines_Struct {
|
||||
};
|
||||
|
||||
|
||||
struct DisciplineTimer_Struct
|
||||
{
|
||||
/*00*/ uint32 TimerID;
|
||||
/*04*/ uint32 Duration;
|
||||
/*08*/ uint32 Unknown08;
|
||||
};
|
||||
|
||||
struct Tribute_Struct {
|
||||
uint32 tribute;
|
||||
@ -1219,64 +1229,17 @@ union
|
||||
|
||||
/*
|
||||
///////////////////// - Haven't identified the below fields in the PP yet
|
||||
uint8 pvp; // 1=pvp, 0=not pvp
|
||||
uint8 anon; // 2=roleplay, 1=anon, 0=not anon
|
||||
uint8 gm; // 0=no, 1=yes (guessing!)
|
||||
uint32 guild_id; // guildid
|
||||
uint8 guildrank; // 0=member, 1=officer, 2=guildleader -1=no guild
|
||||
uint32 guildbanker;
|
||||
uint32 available_slots;
|
||||
uint32 endurance; // Current endurance
|
||||
uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; // Refresh time (millis) - 4 bytes Each * 16 = 64 bytes
|
||||
uint32 abilitySlotRefresh;
|
||||
///////////////////////
|
||||
|
||||
uint32 platinum_bank; // Platinum Pieces in Bank
|
||||
uint32 gold_bank; // Gold Pieces in Bank
|
||||
uint32 silver_bank; // Silver Pieces in Bank
|
||||
uint32 copper_bank; // Copper Pieces in Bank
|
||||
uint32 platinum_shared; // Shared platinum pieces
|
||||
|
||||
uint32 autosplit; // 0 = off, 1 = on
|
||||
|
||||
char groupMembers[MAX_GROUP_MEMBERS][64];// 384 all the members in group, including self
|
||||
char groupLeader[64]; // Leader of the group ?
|
||||
uint32 entityid;
|
||||
|
||||
uint32 leadAAActive; // 0 = leader AA off, 1 = leader AA on
|
||||
int32 ldon_points_guk; // Earned GUK points
|
||||
int32 ldon_points_mir; // Earned MIR points
|
||||
int32 ldon_points_mmc; // Earned MMC points
|
||||
int32 ldon_points_ruj; // Earned RUJ points
|
||||
int32 ldon_points_tak; // Earned TAK points
|
||||
int32 ldon_points_available;// Available LDON points
|
||||
float tribute_time_remaining;// Time remaining on tribute (millisecs)
|
||||
uint32 career_tribute_points;// Total favor points for this char
|
||||
uint32 tribute_points; // Current tribute points
|
||||
uint32 tribute_active; // 0 = off, 1=on
|
||||
Tribute_Struct tributes[MAX_PLAYER_TRIBUTES]; // [40] Current tribute loadout
|
||||
double group_leadership_exp; // Current group lead exp points
|
||||
double raid_leadership_exp; // Current raid lead AA exp points
|
||||
uint32 group_leadership_points; // Unspent group lead AA points
|
||||
uint32 raid_leadership_points; // Unspent raid lead AA points
|
||||
LeadershipAA_Struct leader_abilities; // [128]Leader AA ranks 19332
|
||||
|
||||
uint32 PVPKills;
|
||||
uint32 PVPDeaths;
|
||||
uint32 PVPCurrentPoints;
|
||||
uint32 PVPCareerPoints;
|
||||
uint32 PVPBestKillStreak;
|
||||
uint32 PVPWorstDeathStreak;
|
||||
uint32 PVPCurrentKillStreak;
|
||||
PVPStatsEntry_Struct PVPLastKill; // size 88
|
||||
PVPStatsEntry_Struct PVPLastDeath; // size 88
|
||||
uint32 PVPNumberOfKillsInLast24Hours;
|
||||
PVPStatsEntry_Struct PVPRecentKills[50]; // size 4400 - 88 each
|
||||
uint32 expAA; // Exp earned in current AA point
|
||||
uint32 currentRadCrystals; // Current count of radiant crystals
|
||||
uint32 careerRadCrystals; // Total count of radiant crystals ever
|
||||
uint32 currentEbonCrystals; // Current count of ebon crystals
|
||||
uint32 careerEbonCrystals; // Total count of ebon crystals ever
|
||||
*/
|
||||
|
||||
};
|
||||
@ -1886,8 +1849,8 @@ struct LootingItem_Struct {
|
||||
/*000*/ uint32 lootee;
|
||||
/*004*/ uint32 looter;
|
||||
/*008*/ uint16 slot_id;
|
||||
/*010*/ uint16 unknown10;
|
||||
/*012*/ uint32 auto_loot;
|
||||
/*010*/ uint16 unknown10; // slot_id is probably uint32
|
||||
/*012*/ int32 auto_loot;
|
||||
/*016*/ uint32 unknown16;
|
||||
/*020*/
|
||||
};
|
||||
@ -2892,7 +2855,8 @@ struct Resurrect_Struct
|
||||
/*160*/ char corpse_name[64];
|
||||
/*224*/ uint32 action;
|
||||
/*228*/ uint32 unknown228;
|
||||
/*232*/
|
||||
/*232*/ uint32 unknown232;
|
||||
/*236*/
|
||||
};
|
||||
|
||||
struct SetRunMode_Struct {
|
||||
@ -3111,29 +3075,24 @@ struct MobHealth
|
||||
};
|
||||
|
||||
struct Track_Struct {
|
||||
uint16 entityid;
|
||||
uint16 y;
|
||||
uint16 x;
|
||||
uint16 z;
|
||||
uint32 entityid;
|
||||
float distance;
|
||||
// Fields for SoD and later
|
||||
uint8 level;
|
||||
uint8 is_npc;
|
||||
char name[64];
|
||||
uint8 is_pet;
|
||||
uint8 is_merc;
|
||||
};
|
||||
|
||||
struct Tracking_Struct {
|
||||
uint16 entry_count;
|
||||
Track_Struct Entrys[0];
|
||||
};
|
||||
|
||||
// Looks like new tracking structures - Opcode: 0x57a7
|
||||
struct Tracking_Struct_New {
|
||||
uint16 totalcount; // Total Count of mobs within tracking range
|
||||
Track_Struct Entrys[0];
|
||||
};
|
||||
|
||||
struct Track_Struct_New {
|
||||
uint16 entityid; // Entity ID
|
||||
uint16 unknown002; // 00 00
|
||||
uint32 unknown004; //
|
||||
uint8 level; // level of mob
|
||||
uint8 unknown009; // 01 maybe type of mob? player/npc?
|
||||
char name[1]; // name of mob
|
||||
struct TrackTarget_Struct
|
||||
{
|
||||
uint32 EntityID;
|
||||
};
|
||||
|
||||
|
||||
@ -4399,7 +4358,7 @@ struct ItemSerializationHeader
|
||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||
/*026*/ uint16 main_slot;
|
||||
/*028*/ uint16 sub_slot;
|
||||
/*030*/ uint16 unknown013; // 0xffff
|
||||
/*030*/ uint16 aug_slot; // 0xffff
|
||||
/*032*/ uint32 price;
|
||||
/*036*/ uint32 merchant_slot; //1 if not a merchant item
|
||||
/*040*/ uint32 scaled_value; //0
|
||||
@ -4428,17 +4387,14 @@ struct EvolvingItem {
|
||||
|
||||
struct ItemSerializationHeaderFinish
|
||||
{
|
||||
/*079*/ uint16 ornamentIcon;
|
||||
/*081*/ uint8 unknown061; // 0 - Add Evolving Item struct if this isn't set to 0?
|
||||
/*082*/ uint8 unknown062; // 0
|
||||
/*083*/ int32 unknowna1; // 0xffffffff
|
||||
/*087*/ uint32 ornamentHeroModel; // 0
|
||||
/*091*/ uint8 unknown063; // 0
|
||||
/*092*/ uint32 unknowna3; // 0
|
||||
/*096*/ int32 unknowna4; // 0xffffffff
|
||||
/*100*/ uint32 unknowna5; // 0
|
||||
/*104*/ uint8 ItemClass; //0, 1, or 2
|
||||
/*105*/
|
||||
uint32 ornamentIcon;
|
||||
int32 unknowna1; // 0xffffffff
|
||||
uint32 ornamentHeroModel;
|
||||
int32 unknown063; // 0
|
||||
uint8 Copied; // Copied Flag - Possibly for items copied during server transfer?
|
||||
int32 unknowna4; // 0xffffffff
|
||||
int32 unknowna5; // 0
|
||||
uint8 ItemClass; //0, 1, or 2
|
||||
};
|
||||
|
||||
struct ItemBodyStruct
|
||||
@ -4542,7 +4498,7 @@ struct ItemSecondaryBodyStruct
|
||||
// swapped augrestrict and augdistiller positions
|
||||
// (this swap does show the proper augment restrictions in Item Information window now)
|
||||
// unsure what the purpose of augdistiller is at this time -U 3/17/2014
|
||||
uint32 augdistiller; // New to December 10th 2012 client - NEW
|
||||
int32 augrestrict2; // New to December 10th 2012 client - Hidden Aug Restriction
|
||||
uint32 augrestrict;
|
||||
AugSlotStruct augslots[6];
|
||||
|
||||
@ -4647,7 +4603,7 @@ struct ItemQuaternaryBodyStruct
|
||||
uint8 quest_item;
|
||||
uint32 Power; // Enables "Power" percentage field used by Power Sources
|
||||
uint32 Purity;
|
||||
uint8 unknown16; // RoF2
|
||||
uint8 unknown16; // RoF
|
||||
uint32 BackstabDmg;
|
||||
uint32 DSMitigation;
|
||||
int32 HeroicStr;
|
||||
@ -4669,15 +4625,19 @@ struct ItemQuaternaryBodyStruct
|
||||
uint8 unknown18; //Power Source Capacity or evolve filename?
|
||||
uint32 evolve_string; // Some String, but being evolution related is just a guess
|
||||
uint8 unknown19;
|
||||
uint32 unknown20; // Bard Stuff?
|
||||
//uint32 unknown21;
|
||||
uint8 unknown22;
|
||||
uint16 unknown20;
|
||||
uint8 unknown21;
|
||||
uint8 Heirloom; // Heirloom Flag
|
||||
uint8 Placeable; // Placeable Flag
|
||||
uint8 unknown22b;
|
||||
uint8 unknown22c;
|
||||
uint8 unknown22d;
|
||||
uint32 unknown23;
|
||||
uint32 unknown24;
|
||||
uint32 unknown25;
|
||||
float unknown26;
|
||||
float unknown27;
|
||||
uint32 unknown_RoF26; // 0 New to March 21 2012 client
|
||||
uint32 unknown_RoF_6; // 0 New to March 21 2012 client
|
||||
uint32 unknown28; // 0xffffffff
|
||||
uint16 unknown29;
|
||||
uint32 unknown30; // 0xffffffff
|
||||
@ -4688,9 +4648,15 @@ struct ItemQuaternaryBodyStruct
|
||||
uint32 unknown35;
|
||||
uint32 unknown36;
|
||||
uint32 unknown37;
|
||||
uint32 unknown_RoF27;
|
||||
uint32 unknown_RoF28;
|
||||
uint8 unknown37a; // (guessed position) New to RoF2
|
||||
uint8 NoZone; // No Zone Flag - Item will disappear upon zoning?
|
||||
uint8 unknown_RoF_7b; // Maybe Uint32 ?
|
||||
uint8 unknown_RoF_7c;
|
||||
uint8 unknown_RoF_7d;
|
||||
uint8 unknown_RoF_8a;
|
||||
uint8 NoGround; // No Ground Flag - Item cannot be dropped on the ground?
|
||||
uint8 unknown_RoF_8c;
|
||||
uint8 unknown_RoF_8d;
|
||||
uint8 unknown37a; // New to RoF2 - Probably variable length string
|
||||
uint8 unknown38; // 0
|
||||
uint8 unknown39; // 1
|
||||
uint32 subitem_count;
|
||||
|
||||
@ -180,6 +180,8 @@ namespace RoF {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 55;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@ -84,6 +84,7 @@ E(OP_SkillUpdate)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_TaskDescription)
|
||||
|
||||
@ -3103,32 +3103,25 @@ struct MobHealth
|
||||
};
|
||||
|
||||
struct Track_Struct {
|
||||
uint16 entityid;
|
||||
uint16 y;
|
||||
uint16 x;
|
||||
uint16 z;
|
||||
uint32 entityid;
|
||||
float distance;
|
||||
// Fields for SoD and later
|
||||
uint8 level;
|
||||
uint8 is_npc;
|
||||
char name[64];
|
||||
uint8 is_merc;
|
||||
};
|
||||
|
||||
struct Tracking_Struct {
|
||||
uint16 entry_count;
|
||||
Track_Struct Entrys[0];
|
||||
};
|
||||
|
||||
// Looks like new tracking structures - Opcode: 0x57a7
|
||||
struct Tracking_Struct_New {
|
||||
uint16 totalcount; // Total Count of mobs within tracking range
|
||||
Track_Struct Entrys[0];
|
||||
struct TrackTarget_Struct
|
||||
{
|
||||
uint32 EntityID;
|
||||
};
|
||||
|
||||
struct Track_Struct_New {
|
||||
uint16 entityid; // Entity ID
|
||||
uint16 unknown002; // 00 00
|
||||
uint32 unknown004; //
|
||||
uint8 level; // level of mob
|
||||
uint8 unknown009; // 01 maybe type of mob? player/npc?
|
||||
char name[1]; // name of mob
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** ZoneServerInfo_Struct
|
||||
** Zone server information
|
||||
@ -4420,9 +4413,7 @@ struct EvolvingItem {
|
||||
|
||||
struct ItemSerializationHeaderFinish
|
||||
{
|
||||
/*079*/ uint16 ornamentIcon;
|
||||
/*081*/ uint8 unknown061; // 0 - Add Evolving Item struct if this isn't set to 0?
|
||||
/*082*/ uint8 unknown062; // 0
|
||||
/*079*/ uint32 ornamentIcon;
|
||||
/*083*/ int32 unknowna1; // 0xffffffff
|
||||
/*087*/ uint32 ornamentHeroModel; // 0
|
||||
/*091*/ uint8 unknown063; // 0
|
||||
|
||||
@ -31,6 +31,12 @@ namespace SoD
|
||||
static inline uint32 SoDToServerSlot(uint32 SoDSlot);
|
||||
static inline uint32 SoDToServerCorpseSlot(uint32 SoDCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@ -296,6 +302,35 @@ namespace SoD
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ChannelMessage)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToSoDTextLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
memcpy(OutBuffer, __emu_buffer, sizeof(ChannelMessage_Struct));
|
||||
|
||||
OutBuffer += sizeof(ChannelMessage_Struct);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_CharInventory)
|
||||
{
|
||||
//consume the packet
|
||||
@ -1638,7 +1673,7 @@ namespace SoD
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
@ -1705,7 +1740,7 @@ namespace SoD
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_ReadBook)
|
||||
@ -1963,6 +1998,44 @@ namespace SoD
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToSoDTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@ -2058,9 +2131,9 @@ namespace SoD
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->entityid);
|
||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, emu->distance);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->level);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_npc);
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->name);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->GroupMember);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_merc);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
@ -2729,6 +2802,25 @@ namespace SoD
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ChannelMessage)
|
||||
{
|
||||
unsigned char *__eq_buffer = __packet->pBuffer;
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
SoDToServerTextLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
memcpy(emu, __eq_buffer, sizeof(ChannelMessage_Struct));
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
|
||||
DECODE(OP_CharacterCreate)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CharCreate_Struct);
|
||||
@ -3007,6 +3099,89 @@ namespace SoD
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // /pet stop
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
OUT(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_RaidInvite)
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
@ -3683,5 +3858,81 @@ namespace SoD
|
||||
//uint32 ServerCorpse;
|
||||
return (SoDCorpse - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
sodTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append(segments[segment_iter].substr(36, 5).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(43).c_str());
|
||||
|
||||
sodTextLink.push_back(delimiter);
|
||||
sodTextLink.append(new_segment.c_str());
|
||||
sodTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
sodTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (sodTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = sodTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(sodTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(31, 5).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(36).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace SoD
|
||||
|
||||
@ -177,6 +177,8 @@ namespace SoD {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@ -8,6 +8,7 @@ E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_Buff)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
@ -57,6 +58,7 @@ E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_Track)
|
||||
@ -81,6 +83,7 @@ D(OP_BazaarSearch)
|
||||
D(OP_Buff)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
@ -101,6 +104,7 @@ D(OP_ItemVerifyRequest)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
|
||||
@ -4409,7 +4409,6 @@ struct MercenaryAssign_Struct {
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
|
||||
}; //end namespace structs
|
||||
}; //end namespace SoD
|
||||
|
||||
|
||||
@ -31,6 +31,12 @@ namespace SoF
|
||||
static inline uint32 SoFToServerSlot(uint32 SoFSlot);
|
||||
static inline uint32 SoFToServerCorpseSlot(uint32 SoFCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@ -278,6 +284,35 @@ namespace SoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ChannelMessage)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToSoFTextLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
memcpy(OutBuffer, __emu_buffer, sizeof(ChannelMessage_Struct));
|
||||
|
||||
OutBuffer += sizeof(ChannelMessage_Struct);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_CharInventory)
|
||||
{
|
||||
//consume the packet
|
||||
@ -1296,7 +1331,7 @@ namespace SoF
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
@ -1363,7 +1398,7 @@ namespace SoF
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_ReadBook)
|
||||
@ -1609,6 +1644,44 @@ namespace SoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToSoFTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@ -1645,7 +1718,7 @@ namespace SoF
|
||||
for (int i = 0; i < EntryCount; ++i, ++eq, ++emu)
|
||||
{
|
||||
OUT(entityid);
|
||||
OUT(padding002);
|
||||
//OUT(padding002);
|
||||
OUT(distance);
|
||||
}
|
||||
|
||||
@ -2129,6 +2202,25 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ChannelMessage)
|
||||
{
|
||||
unsigned char *__eq_buffer = __packet->pBuffer;
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
SoFToServerTextLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
memcpy(emu, __eq_buffer, sizeof(ChannelMessage_Struct));
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
|
||||
DECODE(OP_CharacterCreate)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CharCreate_Struct);
|
||||
@ -2345,6 +2437,89 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // Stop?
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
OUT(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_RaidInvite)
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
@ -3005,5 +3180,81 @@ namespace SoF
|
||||
//uint32 ServerCorpse;
|
||||
return (SoFCorpse - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
sofTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append(segments[segment_iter].substr(36, 5).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(43).c_str());
|
||||
|
||||
sofTextLink.push_back(delimiter);
|
||||
sofTextLink.append(new_segment.c_str());
|
||||
sofTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
sofTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (sofTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = sofTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(sofTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(31, 5).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(36).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace SoF
|
||||
|
||||
@ -177,6 +177,8 @@ namespace SoF {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@ -8,6 +8,7 @@ E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_Buff)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
@ -50,6 +51,7 @@ E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
@ -70,6 +72,7 @@ D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_Buff)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
@ -85,6 +88,7 @@ D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
|
||||
@ -2624,8 +2624,8 @@ struct MobHealth
|
||||
};
|
||||
|
||||
struct Track_Struct {
|
||||
uint16 entityid;
|
||||
uint16 padding002;
|
||||
uint32 entityid;
|
||||
//uint16 padding002;
|
||||
float distance;
|
||||
};
|
||||
|
||||
@ -4115,18 +4115,7 @@ struct AltCurrencySellItem_Struct {
|
||||
/*010*/ uint32 cost;
|
||||
};
|
||||
|
||||
|
||||
}; //end namespace structs
|
||||
}; //end namespace SoF
|
||||
|
||||
#endif /*SoF_STRUCTS_H_*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "../races.h"
|
||||
|
||||
#include "../eq_packet_structs.h"
|
||||
#include "../misc_functions.h"
|
||||
#include "../string_util.h"
|
||||
#include "../item.h"
|
||||
#include "titanium_structs.h"
|
||||
@ -28,6 +29,12 @@ namespace Titanium
|
||||
static inline uint32 TitaniumToServerSlot(int16 TitaniumSlot);
|
||||
static inline uint32 TitaniumToServerCorpseSlot(int16 TitaniumCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@ -220,6 +227,35 @@ namespace Titanium
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ChannelMessage)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToTitaniumTextLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
memcpy(OutBuffer, __emu_buffer, sizeof(ChannelMessage_Struct));
|
||||
|
||||
OutBuffer += sizeof(ChannelMessage_Struct);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_CharInventory)
|
||||
{
|
||||
//consume the packet
|
||||
@ -1070,6 +1106,44 @@ namespace Titanium
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToTitaniumTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Track)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
@ -1094,7 +1168,7 @@ namespace Titanium
|
||||
for (int i = 0; i < EntryCount; ++i, ++eq, ++emu)
|
||||
{
|
||||
OUT(entityid);
|
||||
OUT(padding002);
|
||||
//OUT(padding002);
|
||||
OUT(distance);
|
||||
}
|
||||
|
||||
@ -1371,6 +1445,25 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ChannelMessage)
|
||||
{
|
||||
unsigned char *__eq_buffer = __packet->pBuffer;
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
TitaniumToServerTextLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
memcpy(emu, __eq_buffer, sizeof(ChannelMessage_Struct));
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
|
||||
DECODE(OP_CharacterCreate)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CharCreate_Struct);
|
||||
@ -1538,6 +1631,89 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // Stop?
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
OUT(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ReadBook)
|
||||
{
|
||||
// no apparent slot translation needed -U
|
||||
@ -1763,5 +1939,83 @@ namespace Titanium
|
||||
//uint32 ServerCorpse;
|
||||
return TitaniumCorpse;
|
||||
}
|
||||
|
||||
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
titaniumTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||
// Diff: ^^^^^ ^ ^^^^^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append(segments[segment_iter].substr(36, 5).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(48).c_str());
|
||||
|
||||
titaniumTextLink.push_back(delimiter);
|
||||
titaniumTextLink.append(new_segment.c_str());
|
||||
titaniumTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
titaniumTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (titaniumTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = titaniumTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(titaniumTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 (Source)
|
||||
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^ ^^^^^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(31, 5).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(36, 1).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(37).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace Titanium
|
||||
|
||||
@ -176,6 +176,8 @@ namespace Titanium {
|
||||
static const uint32 BANDOLIERS_COUNT = 4; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 4;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 45;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@ -4,6 +4,7 @@ E(OP_AdventureMerchantSell)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
@ -35,6 +36,7 @@ E(OP_RespondAA)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
@ -49,6 +51,7 @@ D(OP_AdventureMerchantSell)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_Consume)
|
||||
D(OP_DeleteItem)
|
||||
@ -59,6 +62,7 @@ D(OP_ItemLinkClick)
|
||||
D(OP_LFGuild)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_ReadBook)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
|
||||
@ -2319,8 +2319,8 @@ struct MobHealth
|
||||
};
|
||||
|
||||
struct Track_Struct {
|
||||
uint16 entityid;
|
||||
uint16 padding002;
|
||||
uint32 entityid;
|
||||
//uint16 padding002;
|
||||
float distance;
|
||||
};
|
||||
|
||||
@ -3332,16 +3332,4 @@ struct LFGuild_GuildToggle_Struct
|
||||
}; //end namespace structs
|
||||
}; //end namespace Titanium
|
||||
|
||||
|
||||
|
||||
#endif /*Titanium_STRUCTS_H_*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -31,6 +31,12 @@ namespace Underfoot
|
||||
static inline uint32 UnderfootToServerSlot(uint32 UnderfootSlot);
|
||||
static inline uint32 UnderfootToServerCorpseSlot(uint32 UnderfootCorpse);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToUnderfootTextLink(std::string& underfootTextLink, const std::string& serverTextLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void UnderfootToServerTextLink(std::string& serverTextLink, const std::string& underfootTextLink);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@ -432,7 +438,12 @@ namespace Underfoot
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToUnderfootTextLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
@ -446,7 +457,7 @@ namespace Underfoot
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->skill_in_language);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->message);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown
|
||||
@ -1924,7 +1935,7 @@ namespace Underfoot
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
@ -1991,7 +2002,7 @@ namespace Underfoot
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_ReadBook)
|
||||
@ -2298,6 +2309,44 @@ namespace Underfoot
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
ServerToUnderfootTextLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = 25 + strlen(emu->sayer) + new_message.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Stun)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Stun_Struct);
|
||||
@ -2348,9 +2397,9 @@ namespace Underfoot
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->entityid);
|
||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, emu->distance);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->level);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_npc);
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->name);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->GroupMember);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->is_merc);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
@ -3036,7 +3085,13 @@ namespace Underfoot
|
||||
|
||||
uint32 Skill = VARSTRUCT_DECODE_TYPE(uint32, InBuffer);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
UnderfootToServerTextLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
ChannelMessage_Struct *emu = (ChannelMessage_Struct *)__packet->pBuffer;
|
||||
|
||||
@ -3045,7 +3100,7 @@ namespace Underfoot
|
||||
emu->language = Language;
|
||||
emu->chan_num = Channel;
|
||||
emu->skill_in_language = Skill;
|
||||
strcpy(emu->message, InBuffer);
|
||||
strcpy(emu->message, new_message.c_str());
|
||||
|
||||
delete[] __eq_buffer;
|
||||
}
|
||||
@ -3364,57 +3419,8 @@ namespace Underfoot
|
||||
DECODE_LENGTH_EXACT(structs::PetCommand_Struct);
|
||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x00:
|
||||
emu->command = 0x04; // Health
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x10; // Leader
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x07; // Attack
|
||||
break;
|
||||
case 0x04:
|
||||
emu->command = 0x08; // Follow
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // Guard
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x09; // Sit. Needs work. This appears to be a toggle between Sit/Stand now.
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0b; // Taunt
|
||||
break;
|
||||
case 0x0f:
|
||||
emu->command = 0x0c; // Hold
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x1b; // Hold on
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x1c; // Hold off
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x01; // Back
|
||||
break;
|
||||
case 0x1d:
|
||||
emu->command = 0x02; // Leave/Go Away
|
||||
break;
|
||||
case 0x15:
|
||||
emu->command = 0x12; // No Cast - /command
|
||||
break;
|
||||
case 0x16:
|
||||
emu->command = 0x12; // No Cast - Pet Window
|
||||
break;
|
||||
case 0x18:
|
||||
emu->command = 0x13; // Focus - Pet Window
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
}
|
||||
OUT(unknown);
|
||||
IN(command);
|
||||
IN(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@ -4155,5 +4161,81 @@ namespace Underfoot
|
||||
//uint32 ServerCorpse;
|
||||
return (UnderfootCorpse - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToUnderfootTextLink(std::string& underfootTextLink, const std::string& serverTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find(delimiter) == std::string::npos)) {
|
||||
underfootTextLink = serverTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append(segments[segment_iter].substr(36, 5).c_str());
|
||||
|
||||
if (segments[segment_iter].substr(41, 1) == "0")
|
||||
new_segment.append(segments[segment_iter].substr(42, 1).c_str());
|
||||
else
|
||||
new_segment.append("F");
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(43).c_str());
|
||||
|
||||
underfootTextLink.push_back(delimiter);
|
||||
underfootTextLink.append(new_segment.c_str());
|
||||
underfootTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
underfootTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void UnderfootToServerTextLink(std::string& serverTextLink, const std::string& underfootTextLink)
|
||||
{
|
||||
const char delimiter = 0x12;
|
||||
|
||||
if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (underfootTextLink.find(delimiter) == std::string::npos)) {
|
||||
serverTextLink = underfootTextLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(underfootTextLink, delimiter);
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
std::string new_segment;
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
new_segment.append(segments[segment_iter].substr(0, 31).c_str());
|
||||
new_segment.append("00000");
|
||||
new_segment.append(segments[segment_iter].substr(31, 5).c_str());
|
||||
new_segment.append("0");
|
||||
new_segment.append(segments[segment_iter].substr(36).c_str());
|
||||
|
||||
serverTextLink.push_back(delimiter);
|
||||
serverTextLink.append(new_segment.c_str());
|
||||
serverTextLink.push_back(delimiter);
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end namespace Underfoot
|
||||
|
||||
@ -177,6 +177,8 @@ namespace Underfoot {
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
namespace limits {
|
||||
|
||||
@ -65,6 +65,7 @@ E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_Track)
|
||||
|
||||
@ -135,7 +135,7 @@ bool PersistentTimer::Load(Database *db) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
LogFile->write(EQEMuLog::Error, "Error in PersistentTimer::Load, error: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in PersistentTimer::Load, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -168,7 +168,7 @@ bool PersistentTimer::Store(Database *db) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
LogFile->write(EQEMuLog::Error, "Error in PersistentTimer::Store, error: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in PersistentTimer::Store, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -188,7 +188,7 @@ bool PersistentTimer::Clear(Database *db) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
LogFile->write(EQEMuLog::Error, "Error in PersistentTimer::Clear, error: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in PersistentTimer::Clear, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -200,7 +200,7 @@ bool PersistentTimer::Clear(Database *db) {
|
||||
/* This function checks if the timer triggered */
|
||||
bool PersistentTimer::Expired(Database *db, bool iReset) {
|
||||
if (this == nullptr) {
|
||||
LogFile->write(EQEMuLog::Error, "Null timer during ->Check()!?\n");
|
||||
LogFile->write(EQEmuLog::Error, "Null timer during ->Check()!?\n");
|
||||
return(true);
|
||||
}
|
||||
uint32 current_time = get_current_time();
|
||||
@ -292,7 +292,7 @@ bool PTimerList::Load(Database *db) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
LogFile->write(EQEMuLog::Error, "Error in PersistentTimer::Load, error: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in PersistentTimer::Load, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -351,7 +351,7 @@ bool PTimerList::Clear(Database *db) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
LogFile->write(EQEMuLog::Error, "Error in PersistentTimer::Clear, error: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in PersistentTimer::Clear, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -443,7 +443,7 @@ bool PTimerList::ClearOffline(Database *db, uint32 char_id, pTimerType type) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
LogFile->write(EQEMuLog::Error, "Error in PTimerList::ClearOffline, error: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in PTimerList::ClearOffline, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ bool RuleManager::LoadRules(Database *db, const char *ruleset) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadRules query %s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in LoadRules query %s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -329,7 +329,7 @@ int RuleManager::GetRulesetID(Database *db, const char *rulesetname) {
|
||||
safe_delete_array(rst);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadRules query %s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in LoadRules query %s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -369,7 +369,7 @@ std::string RuleManager::GetRulesetName(Database *db, int id) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadRules query %s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in LoadRules query %s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ bool RuleManager::ListRulesets(Database *db, std::map<int, std::string> &into) {
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (results.Success())
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in ListRulesets query %s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ListRulesets query %s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -124,7 +124,7 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const Ite
|
||||
account_id, slot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error runing inventory verification query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error runing inventory verification query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
//returning true is less harmful in the face of a query error
|
||||
return true;
|
||||
}
|
||||
@ -177,6 +177,7 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 s
|
||||
}
|
||||
|
||||
bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
// need to check 'inst' argument for valid pointer
|
||||
|
||||
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
|
||||
if (inst->IsType(ItemClassCommon))
|
||||
@ -213,7 +214,7 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
|
||||
}
|
||||
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "UpdateInventorySlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "UpdateInventorySlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -221,6 +222,7 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
|
||||
}
|
||||
|
||||
bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
// need to check 'inst' argument for valid pointer
|
||||
|
||||
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
|
||||
if (inst->IsType(ItemClassCommon))
|
||||
@ -256,7 +258,7 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
|
||||
}
|
||||
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "UpdateSharedBankSlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "UpdateSharedBankSlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -269,7 +271,7 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
|
||||
std::string query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid = %i", char_id, slot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "DeleteInventorySlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "DeleteInventorySlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -282,7 +284,7 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
|
||||
char_id, base_slot_id, (base_slot_id+10));
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "DeleteInventorySlot, bags query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "DeleteInventorySlot, bags query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -297,7 +299,7 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
|
||||
std::string query = StringFormat("DELETE FROM sharedbank WHERE acctid=%i AND slotid=%i", account_id, slot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "DeleteSharedBankSlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "DeleteSharedBankSlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -311,7 +313,7 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
|
||||
account_id, base_slot_id, (base_slot_id+10));
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "DeleteSharedBankSlot, bags query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "DeleteSharedBankSlot, bags query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -401,7 +403,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
|
||||
"FROM sharedbank WHERE acctid=%i", id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Database::GetSharedBank(uint32 account_id): %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Database::GetSharedBank(uint32 account_id): %s", results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -421,7 +423,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
|
||||
const Item_Struct* item = GetItem(item_id);
|
||||
|
||||
if (!item) {
|
||||
LogFile->write(EQEMuLog::Error,
|
||||
LogFile->write(EQEmuLog::Error,
|
||||
"Warning: %s %i has an invalid item_id %i in inventory slot %i",
|
||||
((is_charid==true) ? "charid" : "acctid"), id, item_id, slot_id);
|
||||
continue;
|
||||
@ -430,7 +432,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
|
||||
int16 put_slot_id = INVALID_INDEX;
|
||||
|
||||
ItemInst* inst = CreateBaseItem(item, charges);
|
||||
if (item->ItemClass == ItemClassCommon) {
|
||||
if (inst && item->ItemClass == ItemClassCommon) {
|
||||
for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
if (aug[i]) {
|
||||
inst->PutAugment(this, i, aug[i]);
|
||||
@ -471,7 +473,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
|
||||
if (put_slot_id != INVALID_INDEX)
|
||||
continue;
|
||||
|
||||
LogFile->write(EQEMuLog::Error, "Warning: Invalid slot_id for item in shared bank inventory: %s=%i, item_id=%i, slot_id=%i",
|
||||
LogFile->write(EQEmuLog::Error, "Warning: Invalid slot_id for item in shared bank inventory: %s=%i, item_id=%i, slot_id=%i",
|
||||
((is_charid==true)? "charid": "acctid"), id, item_id, slot_id);
|
||||
|
||||
if (is_charid)
|
||||
@ -490,8 +492,8 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
|
||||
"FROM inventory WHERE charid = %i ORDER BY slotid", char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "GetInventory query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEMuLog::Error, "If you got an error related to the 'instnodrop' field, run the following SQL Queries:\nalter table inventory add instnodrop tinyint(1) unsigned default 0 not null;\n");
|
||||
LogFile->write(EQEmuLog::Error, "GetInventory query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "If you got an error related to the 'instnodrop' field, run the following SQL Queries:\nalter table inventory add instnodrop tinyint(1) unsigned default 0 not null;\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -519,7 +521,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
|
||||
const Item_Struct* item = GetItem(item_id);
|
||||
|
||||
if (!item) {
|
||||
LogFile->write(EQEMuLog::Error,"Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id, slot_id);
|
||||
LogFile->write(EQEmuLog::Error,"Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id, slot_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -527,6 +529,9 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
|
||||
|
||||
ItemInst* inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
|
||||
if(row[11]) {
|
||||
std::string data_str(row[11]);
|
||||
std::string idAsString;
|
||||
@ -576,19 +581,25 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
|
||||
inst->PutAugment(this, i, aug[i]);
|
||||
|
||||
if (slot_id >= 8000 && slot_id <= 8999)
|
||||
{
|
||||
put_slot_id = inv->PushCursor(*inst);
|
||||
else if (slot_id >= 3111 && slot_id <= 3179) {
|
||||
}
|
||||
else if (slot_id >= 3111 && slot_id <= 3179)
|
||||
{
|
||||
// Admins: please report any occurrences of this error
|
||||
LogFile->write(EQEMuLog::Error, "Warning: Defunct location for item in inventory: charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...", char_id, item_id, slot_id);
|
||||
LogFile->write(EQEmuLog::Error, "Warning: Defunct location for item in inventory: charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...", char_id, item_id, slot_id);
|
||||
put_slot_id = inv->PushCursor(*inst);
|
||||
} else
|
||||
put_slot_id = inv->PutItem(slot_id, *inst);
|
||||
}
|
||||
else
|
||||
{
|
||||
put_slot_id = inv->PutItem(slot_id, *inst);
|
||||
}
|
||||
|
||||
safe_delete(inst);
|
||||
|
||||
// Save ptr to item in inventory
|
||||
if (put_slot_id == INVALID_INDEX) {
|
||||
LogFile->write(EQEMuLog::Error, "Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i",char_id, item_id, slot_id);
|
||||
LogFile->write(EQEmuLog::Error, "Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i",char_id, item_id, slot_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -606,8 +617,8 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
|
||||
name, account_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()){
|
||||
LogFile->write(EQEMuLog::Error, "GetInventory query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEMuLog::Error, "If you got an error related to the 'instnodrop' field, run the following SQL Queries:\nalter table inventory add instnodrop tinyint(1) unsigned default 0 not null;\n");
|
||||
LogFile->write(EQEmuLog::Error, "GetInventory query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "If you got an error related to the 'instnodrop' field, run the following SQL Queries:\nalter table inventory add instnodrop tinyint(1) unsigned default 0 not null;\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -637,6 +648,10 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
|
||||
continue;
|
||||
|
||||
ItemInst* inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
|
||||
inst->SetAttuned(instnodrop);
|
||||
|
||||
if(row[11]) {
|
||||
@ -689,7 +704,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
|
||||
|
||||
// Save ptr to item in inventory
|
||||
if (put_slot_id == INVALID_INDEX)
|
||||
LogFile->write(EQEMuLog::Error, "Warning: Invalid slot_id for item in inventory: name=%s, acctid=%i, item_id=%i, slot_id=%i", name, account_id, item_id, slot_id);
|
||||
LogFile->write(EQEmuLog::Error, "Warning: Invalid slot_id for item in inventory: name=%s, acctid=%i, item_id=%i, slot_id=%i", name, account_id, item_id, slot_id);
|
||||
|
||||
}
|
||||
|
||||
@ -705,7 +720,7 @@ void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id) {
|
||||
const std::string query = "SELECT MAX(id), count(*) FROM items";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetItemsCount '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in GetItemsCount '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -745,7 +760,7 @@ bool SharedDatabase::LoadItems() {
|
||||
items_hash = new EQEmu::FixedMemoryHashSet<Item_Struct>(reinterpret_cast<uint8*>(items_mmf->Get()), size);
|
||||
mutex.Unlock();
|
||||
} catch(std::exception& ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Error Loading Items: %s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "Error Loading Items: %s", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -790,7 +805,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
"updated FROM items ORDER BY id";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "LoadItems '%s', %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "LoadItems '%s', %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1003,7 +1018,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
try {
|
||||
hash.insert(item.ID, item);
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Database::LoadItems: %s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "Database::LoadItems: %s", ex.what());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1064,7 +1079,7 @@ std::string SharedDatabase::GetBook(const char *txtfile)
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "No book to send, (%s)", txtfile);
|
||||
LogFile->write(EQEmuLog::Error, "No book to send, (%s)", txtfile);
|
||||
txtout.assign(" ",1);
|
||||
return txtout;
|
||||
}
|
||||
@ -1082,7 +1097,7 @@ void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
|
||||
const std::string query = "SELECT COUNT(*), MAX(id) FROM npc_faction";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting npc faction info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error getting npc faction info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1117,7 +1132,7 @@ void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_co
|
||||
"ON npc_faction.id = npc_faction_entries.npc_faction_id ORDER BY npc_faction.id;";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting npc faction info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error getting npc faction info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1183,7 +1198,7 @@ bool SharedDatabase::LoadNPCFactionLists() {
|
||||
faction_hash = new EQEmu::FixedMemoryHashSet<NPCFactionList>(reinterpret_cast<uint8*>(faction_mmf->Get()), size);
|
||||
mutex.Unlock();
|
||||
} catch(std::exception& ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Error Loading npc factions: %s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "Error Loading npc factions: %s", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1195,9 +1210,17 @@ ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1,
|
||||
{
|
||||
const Item_Struct* item = nullptr;
|
||||
ItemInst* inst = nullptr;
|
||||
|
||||
item = GetItem(item_id);
|
||||
if (item) {
|
||||
inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
LogFile->write(EQEmuLog::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
|
||||
LogFile->write(EQEmuLog::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->PutAugment(this, 0, aug1);
|
||||
inst->PutAugment(this, 1, aug2);
|
||||
inst->PutAugment(this, 2, aug3);
|
||||
@ -1217,6 +1240,13 @@ ItemInst* SharedDatabase::CreateItem(const Item_Struct* item, int16 charges, uin
|
||||
ItemInst* inst = nullptr;
|
||||
if (item) {
|
||||
inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
LogFile->write(EQEmuLog::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
|
||||
LogFile->write(EQEmuLog::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->PutAugment(this, 0, aug1);
|
||||
inst->PutAugment(this, 1, aug2);
|
||||
inst->PutAugment(this, 2, aug3);
|
||||
@ -1242,6 +1272,12 @@ ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges)
|
||||
|
||||
inst = new ItemInst(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
LogFile->write(EQEmuLog::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItem()");
|
||||
LogFile->write(EQEmuLog::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(item->CharmFileID != 0 || (item->LoreGroup >= 1000 && item->LoreGroup != -1)) {
|
||||
inst->Initialize(this);
|
||||
}
|
||||
@ -1308,7 +1344,7 @@ bool SharedDatabase::LoadSkillCaps() {
|
||||
|
||||
mutex.Unlock();
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Error loading skill caps: %s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "Error loading skill caps: %s", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1324,7 +1360,7 @@ void SharedDatabase::LoadSkillCaps(void *data) {
|
||||
const std::string query = "SELECT skillID, class, level, cap FROM skill_caps ORDER BY skillID, class, level";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error loading skill caps from database: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error loading skill caps from database: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1426,7 +1462,7 @@ void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpe
|
||||
"AND `spellid` <= %i", iMaxSpellID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadDamageShieldTypes: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in LoadDamageShieldTypes: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1622,7 +1658,7 @@ int SharedDatabase::GetMaxBaseDataLevel() {
|
||||
const std::string query = "SELECT MAX(level) FROM base_data";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetMaxBaseDataLevel query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in GetMaxBaseDataLevel query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1655,7 +1691,7 @@ bool SharedDatabase::LoadBaseData() {
|
||||
|
||||
mutex.Unlock();
|
||||
} catch(std::exception& ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Error Loading Base Data: %s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "Error Loading Base Data: %s", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1668,7 +1704,7 @@ void SharedDatabase::LoadBaseData(void *data, int max_level) {
|
||||
const std::string query = "SELECT * FROM base_data ORDER BY level, class ASC";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadBaseData query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in LoadBaseData query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1680,22 +1716,22 @@ void SharedDatabase::LoadBaseData(void *data, int max_level) {
|
||||
cl = atoi(row[1]);
|
||||
|
||||
if(lvl <= 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Non fatal error: base_data.level <= 0, ignoring.");
|
||||
LogFile->write(EQEmuLog::Error, "Non fatal error: base_data.level <= 0, ignoring.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(lvl >= max_level) {
|
||||
LogFile->write(EQEMuLog::Error, "Non fatal error: base_data.level >= max_level, ignoring.");
|
||||
LogFile->write(EQEmuLog::Error, "Non fatal error: base_data.level >= max_level, ignoring.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cl <= 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Non fatal error: base_data.cl <= 0, ignoring.");
|
||||
LogFile->write(EQEmuLog::Error, "Non fatal error: base_data.cl <= 0, ignoring.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cl > 16) {
|
||||
LogFile->write(EQEMuLog::Error, "Non fatal error: base_data.class > 16, ignoring.");
|
||||
LogFile->write(EQEmuLog::Error, "Non fatal error: base_data.class > 16, ignoring.");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1748,7 +1784,7 @@ void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot
|
||||
const std::string query = "SELECT COUNT(*), MAX(id), (SELECT COUNT(*) FROM loottable_entries) FROM loottable";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error getting loot table info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1770,7 +1806,7 @@ void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_d
|
||||
const std::string query = "SELECT COUNT(*), MAX(id), (SELECT COUNT(*) FROM lootdrop_entries) FROM lootdrop";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error getting loot table info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1796,7 +1832,7 @@ void SharedDatabase::LoadLootTables(void *data, uint32 size) {
|
||||
"ON loottable.id = loottable_entries.loottable_id ORDER BY id";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error getting loot table info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1850,7 +1886,7 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) {
|
||||
"ON lootdrop.id = lootdrop_entries.lootdrop_id ORDER BY lootdrop_id";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting loot drop info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error getting loot drop info from database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
uint32 current_id = 0;
|
||||
@ -1904,7 +1940,7 @@ bool SharedDatabase::LoadLoot() {
|
||||
loot_drop_mmf->Size());
|
||||
mutex.Unlock();
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Error loading loot: %s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "Error loading loot: %s", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1920,7 +1956,7 @@ const LootTable_Struct* SharedDatabase::GetLootTable(uint32 loottable_id) {
|
||||
return &loot_table_hash->at(loottable_id);
|
||||
}
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Could not get loot table: %s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "Could not get loot table: %s", ex.what());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -1934,7 +1970,7 @@ const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
|
||||
return &loot_drop_hash->at(lootdrop_id);
|
||||
}
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "Could not get loot drop: %s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "Could not get loot drop: %s", ex.what());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ void TimeoutManager::CheckTimeouts() {
|
||||
Timeoutable *it = *cur;
|
||||
if(it->next_check.Check()) {
|
||||
#ifdef TIMEOUT_DEBUG
|
||||
LogFile->write(EQEMuLog::Debug, "Checking timeout on 0x%x\n", it);
|
||||
LogFile->write(EQEmuLog::Debug, "Checking timeout on 0x%x\n", it);
|
||||
#endif
|
||||
it->CheckTimeout();
|
||||
}
|
||||
@ -58,13 +58,13 @@ void TimeoutManager::AddMember(Timeoutable *who) {
|
||||
DeleteMember(who); //just in case... prolly not needed.
|
||||
members.push_back(who);
|
||||
#ifdef TIMEOUT_DEBUG
|
||||
LogFile->write(EQEMuLog::Debug, "Adding timeoutable 0x%x\n", who);
|
||||
LogFile->write(EQEmuLog::Debug, "Adding timeoutable 0x%x\n", who);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TimeoutManager::DeleteMember(Timeoutable *who) {
|
||||
#ifdef TIMEOUT_DEBUG
|
||||
LogFile->write(EQEMuLog::Debug, "Removing timeoutable 0x%x\n", who);
|
||||
LogFile->write(EQEmuLog::Debug, "Removing timeoutable 0x%x\n", who);
|
||||
#endif
|
||||
std::vector<Timeoutable *>::iterator cur,end;
|
||||
cur = members.begin();
|
||||
|
||||
@ -141,11 +141,13 @@ uint32 Timer::GetRemainingTime() {
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::SetAtTrigger(uint32 in_set_at_trigger, bool iEnableIfDisabled) {
|
||||
void Timer::SetAtTrigger(uint32 in_set_at_trigger, bool iEnableIfDisabled, bool ChangeTimerTime) {
|
||||
set_at_trigger = in_set_at_trigger;
|
||||
if (!Enabled() && iEnableIfDisabled) {
|
||||
Enable();
|
||||
}
|
||||
if (ChangeTimerTime)
|
||||
timer_time = set_at_trigger;
|
||||
}
|
||||
|
||||
void Timer::Trigger()
|
||||
|
||||
@ -43,7 +43,7 @@ public:
|
||||
inline const uint32& GetTimerTime() { return timer_time; }
|
||||
inline const uint32& GetSetAtTrigger() { return set_at_trigger; }
|
||||
void Trigger();
|
||||
void SetAtTrigger(uint32 set_at_trigger, bool iEnableIfDisabled = false);
|
||||
void SetAtTrigger(uint32 set_at_trigger, bool iEnableIfDisabled = false, bool ChangeTimerTime = false);
|
||||
|
||||
inline bool Enabled() { return enabled; }
|
||||
inline uint32 GetStartTime() { return(start_time); }
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9062
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9066
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
#ifndef WIN32
|
||||
|
||||
@ -537,6 +537,7 @@ namespace detail
|
||||
};
|
||||
|
||||
// Needed because of some strange ADL issues.
|
||||
#if BOOST_VERSION < 105700
|
||||
|
||||
#define LUABIND_OPERATOR_ADL_WKND(op) \
|
||||
inline bool operator op( \
|
||||
@ -557,7 +558,8 @@ namespace detail
|
||||
LUABIND_OPERATOR_ADL_WKND(!=)
|
||||
|
||||
#undef LUABIND_OPERATOR_ADL_WKND
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace adl
|
||||
|
||||
@ -68,14 +68,14 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
if (!Open(host, user, passwd, database, port, &errnum, errbuf))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Failed to connect to database: Error: %s", errbuf);
|
||||
LogFile->write(EQEmuLog::Error, "Failed to connect to database: Error: %s", errbuf);
|
||||
HandleMysqlError(errnum);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "Using database '%s' at %s:%d",database,host,port);
|
||||
LogFile->write(EQEmuLog::Status, "Using database '%s' at %s:%d",database,host,port);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,22 +35,22 @@ int main(int argc, char **argv) {
|
||||
RegisterExecutablePlatform(ExePlatformSharedMemory);
|
||||
set_exception_handler();
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "Shared Memory Loader Program");
|
||||
LogFile->write(EQEmuLog::Status, "Shared Memory Loader Program");
|
||||
if(!EQEmuConfig::LoadConfig()) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to load configuration file.");
|
||||
LogFile->write(EQEmuLog::Error, "Unable to load configuration file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EQEmuConfig *config = EQEmuConfig::get();
|
||||
if(!load_log_settings(config->LogSettingsFile.c_str())) {
|
||||
LogFile->write(EQEMuLog::Error, "Warning: unable to read %s.", config->LogSettingsFile.c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Warning: unable to read %s.", config->LogSettingsFile.c_str());
|
||||
}
|
||||
|
||||
SharedDatabase database;
|
||||
LogFile->write(EQEMuLog::Status, "Connecting to database...");
|
||||
LogFile->write(EQEmuLog::Status, "Connecting to database...");
|
||||
if(!database.Connect(config->DatabaseHost.c_str(), config->DatabaseUsername.c_str(),
|
||||
config->DatabasePassword.c_str(), config->DatabaseDB.c_str(), config->DatabasePort)) {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to connect to the database, cannot continue without a "
|
||||
LogFile->write(EQEmuLog::Error, "Unable to connect to the database, cannot continue without a "
|
||||
"database connection");
|
||||
return 1;
|
||||
}
|
||||
@ -109,61 +109,61 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
if(load_all || load_items) {
|
||||
LogFile->write(EQEMuLog::Status, "Loading items...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading items...");
|
||||
try {
|
||||
LoadItems(&database);
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "%s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "%s", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(load_all || load_factions) {
|
||||
LogFile->write(EQEMuLog::Status, "Loading factions...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading factions...");
|
||||
try {
|
||||
LoadFactions(&database);
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "%s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "%s", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(load_all || load_loot) {
|
||||
LogFile->write(EQEMuLog::Status, "Loading loot...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading loot...");
|
||||
try {
|
||||
LoadLoot(&database);
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "%s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "%s", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(load_all || load_skill_caps) {
|
||||
LogFile->write(EQEMuLog::Status, "Loading skill caps...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading skill caps...");
|
||||
try {
|
||||
LoadSkillCaps(&database);
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "%s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "%s", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(load_all || load_spells) {
|
||||
LogFile->write(EQEMuLog::Status, "Loading spells...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading spells...");
|
||||
try {
|
||||
LoadSpells(&database);
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "%s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "%s", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(load_all || load_bd) {
|
||||
LogFile->write(EQEMuLog::Status, "Loading base data...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading base data...");
|
||||
try {
|
||||
LoadBaseData(&database);
|
||||
} catch(std::exception &ex) {
|
||||
LogFile->write(EQEMuLog::Error, "%s", ex.what());
|
||||
LogFile->write(EQEmuLog::Error, "%s", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,14 +73,14 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
if (!Open(host, user, passwd, database, port, &errnum, errbuf))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Failed to connect to database: Error: %s", errbuf);
|
||||
LogFile->write(EQEmuLog::Error, "Failed to connect to database: Error: %s", errbuf);
|
||||
HandleMysqlError(errnum);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "Using database '%s' at %s:%d",database,host,port);
|
||||
LogFile->write(EQEmuLog::Status, "Using database '%s' at %s:%d",database,host,port);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,7 +193,7 @@ OP_Consent=0x1fd1
|
||||
OP_ConsentDeny=0x7a45
|
||||
OP_AutoFire=0x241e
|
||||
OP_PetCommands=0x0159
|
||||
OP_DeleteSpell=0x52e5
|
||||
OP_DeleteSpell=0x3358
|
||||
OP_Surname=0x0423
|
||||
OP_ClearSurname=0x3fb0
|
||||
OP_FaceChange=0x5578
|
||||
@ -205,14 +205,14 @@ OP_CorpseDrag=0x0904
|
||||
OP_CorpseDrop=0x7037
|
||||
OP_Bug=0x73f4
|
||||
OP_Feedback=0x5602
|
||||
OP_Report=0x1414
|
||||
OP_Report=0x6f14
|
||||
OP_Damage=0x6f15
|
||||
OP_ChannelMessage=0x2b2d
|
||||
OP_Assist=0x4478
|
||||
OP_AssistGroup=0x27f8
|
||||
OP_MoveCoin=0x0bcf
|
||||
OP_ZonePlayerToBind=0x08d8
|
||||
OP_KeyRing=0x6857
|
||||
OP_KeyRing=0x1219
|
||||
OP_WhoAllRequest=0x674b
|
||||
OP_WhoAllResponse=0x578c
|
||||
OP_FriendsWho=0x3956
|
||||
@ -249,7 +249,7 @@ OP_ItemLinkClick=0x4cef
|
||||
OP_ItemPreview=0x6b5c
|
||||
OP_NewSpawn=0x6097
|
||||
OP_Track=0x17e5
|
||||
OP_TrackTarget=0x0029
|
||||
OP_TrackTarget=0x695e
|
||||
OP_TrackUnknown=0x4577
|
||||
OP_ClickDoor=0x3a8f
|
||||
OP_MoveDoor=0x08e8
|
||||
@ -263,7 +263,7 @@ OP_SafeFallSuccess=0x2219
|
||||
OP_RezzComplete=0x760d
|
||||
OP_RezzRequest=0x3c21
|
||||
OP_RezzAnswer=0x701c
|
||||
OP_Shielding=0x48c1
|
||||
OP_Shielding=0x52e5
|
||||
OP_RequestDuel=0x3af1
|
||||
OP_MobRename=0x2c57
|
||||
OP_AugmentItem=0x661b
|
||||
|
||||
@ -155,6 +155,7 @@ sub ShowMenuPrompt {
|
||||
2 => \&database_dump_compress,
|
||||
3 => \&Run_Database_Check,
|
||||
4 => \&AA_Fetch,
|
||||
5 => \&OpCodes_Fetch,
|
||||
0 => \&Exit,
|
||||
);
|
||||
|
||||
@ -204,6 +205,7 @@ Database Management Menu (Please Select):
|
||||
Ideal to perform before performing updates
|
||||
3) $option[3]
|
||||
4) AAs - Get Latest AA's from PEQ (This deletes AA's already in the database)
|
||||
5) OPCodes - Download latest opcodes from repository
|
||||
0) Exit
|
||||
|
||||
EO_MENU
|
||||
@ -305,6 +307,36 @@ sub AA_Fetch{
|
||||
print "\nDone...\n\n";
|
||||
}
|
||||
|
||||
#::: Fetch Latest Opcodes
|
||||
sub OpCodes_Fetch{
|
||||
print "Pulling down latest opcodes...\n";
|
||||
%opcodes = (
|
||||
1 => ["opcodes", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/opcodes.conf"],
|
||||
2 => ["mail_opcodes", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/mail_opcodes.conf"],
|
||||
3 => ["Titanium", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_Titanium.conf"],
|
||||
4 => ["Secrets of Faydwer", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_SoF.conf"],
|
||||
5 => ["Seeds of Destruction", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_SoD.conf"],
|
||||
6 => ["Underfoot", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_Underfoot.conf"],
|
||||
7 => ["Rain of Fear", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_RoF.conf"],
|
||||
8 => ["Rain of Fear 2", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_RoF2.conf"],
|
||||
);
|
||||
$loop = 1;
|
||||
while($opcodes{$loop}[0]){
|
||||
#::: Split the URL by the patches folder to get the file name from URL
|
||||
@real_file = split("patches/", $opcodes{$loop}[1]);
|
||||
$find = 0;
|
||||
while($real_file[$find]){
|
||||
$file_name = $real_file[$find];
|
||||
$find++;
|
||||
}
|
||||
|
||||
print "\nDownloading (" . $opcodes{$loop}[0] . ") File: '" . $file_name . "'...\n\n";
|
||||
GetRemoteFile($opcodes{$loop}[1], $file_name);
|
||||
$loop++;
|
||||
}
|
||||
print "\nDone...\n\n";
|
||||
}
|
||||
|
||||
#::: Responsible for Database Upgrade Routines
|
||||
sub Run_Database_Check{
|
||||
#::: Run 2 - Running pending updates...
|
||||
|
||||
39
utils/scripts/parse_crashes.pl
Normal file
39
utils/scripts/parse_crashes.pl
Normal file
@ -0,0 +1,39 @@
|
||||
opendir my $dir, "logs" or die "Cannot open directory: $!";
|
||||
my @files = readdir $dir;
|
||||
closedir $dir;
|
||||
$inc = 0;
|
||||
foreach my $val (@files){
|
||||
if($val=~/crash_zone/i){
|
||||
$stl = 0;
|
||||
$crash[$inc] = "";
|
||||
my $file = "logs/" . $val;
|
||||
open my $info, $file or die "Could not open $file: $!";
|
||||
while( my $line = <$info>) {
|
||||
if($line=~/CRTStartup/i){ $stl = 0; }
|
||||
@data = split(']', $line);
|
||||
if($stl == 1){ $crash[$inc] .= $data[1]; }
|
||||
if($line=~/dbghelp.dll/i){ $stl = 1; }
|
||||
}
|
||||
close $info;
|
||||
$inc++;
|
||||
}
|
||||
}
|
||||
|
||||
#::: Count Crash Occurrence first
|
||||
$i = 0;
|
||||
while($crash[$i]){
|
||||
$crash_count[length($crash[$i])]++;
|
||||
$unique_crash[length($crash[$i])] = $crash[$i];
|
||||
$i++;
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
while($crash[$i]){
|
||||
if($unique_crash_tracker[length($crash[$i])] != 1){
|
||||
print "Crash Occurrence " . $crash_count[length($crash[$i])] . " Time(s) Length (" . length($crash[$i]) . ") \n\n";
|
||||
print $crash[$i] . "\n";
|
||||
print "=========================================\n";
|
||||
}
|
||||
$unique_crash_tracker[length($crash[$i])] = 1;
|
||||
$i++;
|
||||
}
|
||||
@ -316,6 +316,10 @@
|
||||
9060|2014_12_09_items_table_update.sql|SHOW COLUMNS FROM `items` LIKE 'herosforgemodel'|empty|
|
||||
9061|2014_12_13_inventory_table_update.sql|SHOW COLUMNS FROM `inventory` LIKE 'ornament_hero_model'|empty|
|
||||
9062|2014_12_15_multiple_table_updates.sql|SHOW COLUMNS FROM `items` LIKE 'augslot6type'|empty|
|
||||
9063|2014_12_24_npc_types_update.sql|SHOW COLUMNS FROM `npc_types` LIKE 'd_melee_texture1'|empty|
|
||||
9064|2014_12_24_npc_types_table_update.sql|SHOW COLUMNS FROM `npc_types` LIKE 'herosforgemodel'|empty|
|
||||
9065|2014_12_26_merc_weaponinfo_table_update.sql|SHOW COLUMNS FROM `vwMercNpcTypes` LIKE 'd_melee_texture1'|empty|
|
||||
9066|2014_12_31_npc_types_default_values_update.sql|SHOW COLUMNS FROM `npc_types` LIKE 'bodytype'|contains|YES
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@ -0,0 +1 @@
|
||||
ALTER TABLE `npc_types` ADD `herosforgemodel` int( 11 ) NOT NULL DEFAULT '0' AFTER `helmtexture`;
|
||||
2
utils/sql/git/required/2014_12_24_npc_types_update.sql
Normal file
2
utils/sql/git/required/2014_12_24_npc_types_update.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `npc_types` CHANGE `d_meele_texture1` `d_melee_texture1` INT(11) DEFAULT NULL;
|
||||
ALTER TABLE `npc_types` CHANGE `d_meele_texture2` `d_melee_texture2` INT(11) DEFAULT NULL;
|
||||
@ -0,0 +1,69 @@
|
||||
/* Drop the current Merc View */
|
||||
DROP VIEW vwMercNpcTypes;
|
||||
|
||||
/* Rename fields to match the source changes */
|
||||
ALTER TABLE `merc_weaponinfo` CHANGE `d_meele_texture1` `d_melee_texture1` INT(11) NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `merc_weaponinfo` CHANGE `d_meele_texture2` `d_melee_texture2` INT(11) NOT NULL DEFAULT 0;
|
||||
|
||||
/* Re-Create the Merc View with new field names */
|
||||
CREATE VIEW vwMercNpcTypes AS
|
||||
SELECT
|
||||
ms.merc_npc_type_id,
|
||||
'' AS name,
|
||||
ms.clientlevel,
|
||||
ms.level,
|
||||
mtyp.race_id,
|
||||
mstyp.class_id,
|
||||
ms.hp,
|
||||
ms.mana,
|
||||
0 AS gender,
|
||||
mai.texture,
|
||||
mai.helmtexture,
|
||||
ms.attack_speed,
|
||||
ms.STR,
|
||||
ms.STA,
|
||||
ms.DEX,
|
||||
ms.AGI,
|
||||
ms._INT,
|
||||
ms.WIS,
|
||||
ms.CHA,
|
||||
ms.MR,
|
||||
ms.CR,
|
||||
ms.DR,
|
||||
ms.FR,
|
||||
ms.PR,
|
||||
ms.Corrup,
|
||||
ms.mindmg,
|
||||
ms.maxdmg,
|
||||
ms.attack_count,
|
||||
ms.special_abilities AS special_abilities,
|
||||
mwi.d_melee_texture1,
|
||||
mwi.d_melee_texture2,
|
||||
mwi.prim_melee_type,
|
||||
mwi.sec_melee_type,
|
||||
ms.runspeed,
|
||||
ms.hp_regen_rate,
|
||||
ms.mana_regen_rate,
|
||||
1 AS bodytype,
|
||||
mai.armortint_id,
|
||||
mai.armortint_red,
|
||||
mai.armortint_green,
|
||||
mai.armortint_blue,
|
||||
ms.AC,
|
||||
ms.ATK,
|
||||
ms.Accuracy,
|
||||
ms.spellscale,
|
||||
ms.healscale
|
||||
FROM merc_stats ms
|
||||
INNER JOIN merc_armorinfo mai
|
||||
ON ms.merc_npc_type_id = mai.merc_npc_type_id
|
||||
AND mai.minlevel <= ms.level AND mai.maxlevel >= ms.level
|
||||
INNER JOIN merc_weaponinfo mwi
|
||||
ON ms.merc_npc_type_id = mwi.merc_npc_type_id
|
||||
AND mwi.minlevel <= ms.level AND mwi.maxlevel >= ms.level
|
||||
INNER JOIN merc_templates mtem
|
||||
ON mtem.merc_npc_type_id = ms.merc_npc_type_id
|
||||
INNER JOIN merc_types mtyp
|
||||
ON mtem.merc_type_id = mtyp.merc_type_id
|
||||
INNER JOIN merc_subtypes mstyp
|
||||
ON mtem.merc_subtype_id = mstyp.merc_subtype_id;
|
||||
@ -0,0 +1,3 @@
|
||||
ALTER TABLE `npc_types` MODIFY `bodytype` INT(11) NOT NULL DEFAULT '1';
|
||||
ALTER TABLE `npc_types` MODIFY `d_melee_texture1` INT(11) NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `npc_types` MODIFY `d_melee_texture2` INT(11) NOT NULL DEFAULT '0';
|
||||
@ -385,7 +385,7 @@ void Adventure::MoveCorpsesToGraveyard()
|
||||
std::string query = StringFormat("SELECT id, charid FROM character_corpses WHERE instanceid=%d", GetInstanceID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
dbid_list.push_back(atoi(row[0]));
|
||||
@ -405,7 +405,7 @@ void Adventure::MoveCorpsesToGraveyard()
|
||||
x, y, z, GetInstanceID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
auto c_iter = charid_list.begin();
|
||||
|
||||
@ -649,7 +649,7 @@ bool AdventureManager::LoadAdventureTemplates()
|
||||
"graveyard_radius FROM adventure_template";
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::LoadAdventures: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in AdventureManager:::LoadAdventures: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -699,7 +699,7 @@ bool AdventureManager::LoadAdventureEntries()
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::LoadAdventureEntries: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in AdventureManager:::LoadAdventureEntries: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1074,7 +1074,7 @@ void AdventureManager::LoadLeaderboardInfo()
|
||||
"AS adv_stats LEFT JOIN `character_data` AS ch ON adv_stats.player_id = ch.id;";
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::GetLeaderboardInfo: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in AdventureManager:::GetLeaderboardInfo: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ void EQLConfig::LoadSettings() {
|
||||
std::string query = StringFormat("SELECT dynamics FROM launcher WHERE name = '%s'", namebuf);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "EQLConfig::LoadSettings: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "EQLConfig::LoadSettings: %s", results.ErrorMessage().c_str());
|
||||
else {
|
||||
auto row = results.begin();
|
||||
m_dynamics = atoi(row[0]);
|
||||
@ -51,7 +51,7 @@ void EQLConfig::LoadSettings() {
|
||||
query = StringFormat("SELECT zone, port FROM launcher_zones WHERE launcher = '%s'", namebuf);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "EQLConfig::LoadSettings: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "EQLConfig::LoadSettings: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ EQLConfig *EQLConfig::CreateLauncher(const char *name, uint8 dynamic_count) {
|
||||
std::string query = StringFormat("INSERT INTO launcher (name, dynamics) VALUES('%s', %d)", namebuf, dynamic_count);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in CreateLauncher query: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in CreateLauncher query: %s", results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -118,14 +118,14 @@ void EQLConfig::DeleteLauncher() {
|
||||
std::string query = StringFormat("DELETE FROM launcher WHERE name = '%s'", namebuf);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeleteLauncher 1st query: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in DeleteLauncher 1st query: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
query = StringFormat("DELETE FROM launcher_zones WHERE launcher = '%s'", namebuf);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeleteLauncher 2nd query: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in DeleteLauncher 2nd query: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -173,7 +173,7 @@ bool EQLConfig::BootStaticZone(Const_char *short_name, uint16 port) {
|
||||
"VALUES('%s', '%s', %d)", namebuf, zonebuf, port);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in BootStaticZone query: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in BootStaticZone query: %s", results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ bool EQLConfig::ChangeStaticZone(Const_char *short_name, uint16 port) {
|
||||
res = m_zones.find(short_name);
|
||||
if(res == m_zones.end()) {
|
||||
//not found.
|
||||
LogFile->write(EQEMuLog::Error, "Update for unknown zone %s", short_name);
|
||||
LogFile->write(EQEmuLog::Error, "Update for unknown zone %s", short_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ bool EQLConfig::ChangeStaticZone(Const_char *short_name, uint16 port) {
|
||||
"launcher = '%s' AND zone = '%s'",port, namebuf, zonebuf);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ChangeStaticZone query: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ChangeStaticZone query: %s", results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ bool EQLConfig::DeleteStaticZone(Const_char *short_name) {
|
||||
res = m_zones.find(short_name);
|
||||
if(res == m_zones.end()) {
|
||||
//not found.
|
||||
LogFile->write(EQEMuLog::Error, "Update for unknown zone %s", short_name);
|
||||
LogFile->write(EQEmuLog::Error, "Update for unknown zone %s", short_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ bool EQLConfig::DeleteStaticZone(Const_char *short_name) {
|
||||
"launcher = '%s' AND zone = '%s'", namebuf, zonebuf);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeleteStaticZone query: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in DeleteStaticZone query: %s", results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ bool EQLConfig::SetDynamicCount(int count) {
|
||||
std::string query = StringFormat("UPDATE launcher SET dynamics=%d WHERE name='%s'", count, namebuf);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in SetDynamicCount query: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in SetDynamicCount query: %s", results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ void log_message_clientVA(LogType type, Client *who, const char *fmt, va_list ar
|
||||
|
||||
std::string prefix_buffer = StringFormat("[%s] %s: ", log_type_info[type].name, who->GetAccountName());
|
||||
|
||||
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args);
|
||||
LogFile->writePVA(EQEmuLog::Debug, prefix_buffer.c_str(), fmt, args);
|
||||
}
|
||||
|
||||
void log_message_client(LogType type, Client *who, const char *fmt, ...) {
|
||||
@ -36,7 +36,7 @@ void log_message_zoneVA(LogType type, ZoneServer *who, const char *fmt, va_list
|
||||
|
||||
prefix_buffer = StringFormat("[%s] %s ", log_type_info[type].name, zone_tag.c_str());
|
||||
|
||||
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args);
|
||||
LogFile->writePVA(EQEmuLog::Debug, prefix_buffer.c_str(), fmt, args);
|
||||
}
|
||||
|
||||
void log_message_zone(LogType type, ZoneServer *who, const char *fmt, ...) {
|
||||
|
||||
@ -298,11 +298,11 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
|
||||
in_cc->race);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "Start zone query: %s\n", query.c_str());
|
||||
LogFile->write(EQEmuLog::Status, "Start zone query: %s\n", query.c_str());
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
printf("No start_zones entry in database, using defaults\n");
|
||||
@ -395,7 +395,7 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
|
||||
LogFile->write(EQEmuLog::Status, "Found starting location in start_zones");
|
||||
auto row = results.begin();
|
||||
in_pp->x = atof(row[0]);
|
||||
in_pp->y = atof(row[1]);
|
||||
@ -434,11 +434,11 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
|
||||
in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Status, "SoF Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Status, "SoF Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "SoF Start zone query: %s\n", query.c_str());
|
||||
LogFile->write(EQEmuLog::Status, "SoF Start zone query: %s\n", query.c_str());
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
printf("No start_zones entry in database, using defaults\n");
|
||||
@ -453,7 +453,7 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
|
||||
LogFile->write(EQEmuLog::Status, "Found starting location in start_zones");
|
||||
auto row = results.begin();
|
||||
in_pp->x = atof(row[0]);
|
||||
in_pp->y = atof(row[1]);
|
||||
@ -478,7 +478,7 @@ void WorldDatabase::GetLauncherList(std::vector<std::string> &rl) {
|
||||
const std::string query = "SELECT name FROM launcher";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetLauncherList: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "WorldDatabase::GetLauncherList: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -500,7 +500,7 @@ void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey) {
|
||||
MailKeyString, CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
@ -509,7 +509,7 @@ bool WorldDatabase::GetCharacterLevel(const char *name, int &level)
|
||||
std::string query = StringFormat("SELECT level FROM character_data WHERE name = '%s'", name);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetCharacterLevel: %s", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "WorldDatabase::GetCharacterLevel: %s", results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
48
zone/aa.cpp
48
zone/aa.cpp
@ -444,7 +444,7 @@ void Client::HandleAAAction(aaID activate) {
|
||||
break;
|
||||
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Error, "Unknown AA nonspell action type %d", caa->action);
|
||||
LogFile->write(EQEmuLog::Error, "Unknown AA nonspell action type %d", caa->action);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -500,7 +500,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
PetRecord record;
|
||||
if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Unknown swarm pet spell id: %d, check pets table", spell_id);
|
||||
LogFile->write(EQEmuLog::Error, "Unknown swarm pet spell id: %d, check pets table", spell_id);
|
||||
Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone);
|
||||
return;
|
||||
}
|
||||
@ -527,7 +527,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
const NPCType *npc_type = database.GetNPCType(pet.npc_id);
|
||||
if(npc_type == nullptr) {
|
||||
//log write
|
||||
LogFile->write(EQEMuLog::Error, "Unknown npc type for swarm pet spell id: %d", spell_id);
|
||||
LogFile->write(EQEmuLog::Error, "Unknown npc type for swarm pet spell id: %d", spell_id);
|
||||
Message(0,"Unable to find pet!");
|
||||
return;
|
||||
}
|
||||
@ -606,6 +606,9 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
//the target of these swarm pets will take offense to being cast on...
|
||||
if(targ != nullptr)
|
||||
targ->AddToHateList(this, 1, 0);
|
||||
|
||||
// The other pointers we make are handled elsewhere.
|
||||
delete made_npc;
|
||||
}
|
||||
|
||||
void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_override, uint32 duration_override, bool followme, bool sticktarg) {
|
||||
@ -621,7 +624,7 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
|
||||
const NPCType *npc_type = database.GetNPCType(typesid);
|
||||
if(npc_type == nullptr) {
|
||||
//log write
|
||||
LogFile->write(EQEMuLog::Error, "Unknown npc type for swarm pet type id: %d", typesid);
|
||||
LogFile->write(EQEmuLog::Error, "Unknown npc type for swarm pet type id: %d", typesid);
|
||||
Message(0,"Unable to find pet!");
|
||||
return;
|
||||
}
|
||||
@ -697,6 +700,9 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
|
||||
entity_list.AddNPC(npca, true, true);
|
||||
summon_count--;
|
||||
}
|
||||
|
||||
// The other pointers we make are handled elsewhere.
|
||||
delete made_npc;
|
||||
}
|
||||
|
||||
void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
|
||||
@ -843,8 +849,8 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
|
||||
|
||||
make_npc->loottable_id = 0;
|
||||
make_npc->merchanttype = 0;
|
||||
make_npc->d_meele_texture1 = 0;
|
||||
make_npc->d_meele_texture2 = 0;
|
||||
make_npc->d_melee_texture1 = 0;
|
||||
make_npc->d_melee_texture2 = 0;
|
||||
|
||||
NPC* npca = new NPC(make_npc, 0, GetPosition(), FlyMode3);
|
||||
|
||||
@ -1421,10 +1427,10 @@ SendAA_Struct* Zone::FindAA(uint32 id) {
|
||||
}
|
||||
|
||||
void Zone::LoadAAs() {
|
||||
LogFile->write(EQEMuLog::Status, "Loading AA information...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading AA information...");
|
||||
totalAAs = database.CountAAs();
|
||||
if(totalAAs == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Failed to load AAs!");
|
||||
LogFile->write(EQEmuLog::Error, "Failed to load AAs!");
|
||||
aas = nullptr;
|
||||
return;
|
||||
}
|
||||
@ -1439,11 +1445,11 @@ void Zone::LoadAAs() {
|
||||
}
|
||||
|
||||
//load AA Effects into aa_effects
|
||||
LogFile->write(EQEMuLog::Status, "Loading AA Effects...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading AA Effects...");
|
||||
if (database.LoadAAEffects2())
|
||||
LogFile->write(EQEMuLog::Status, "Loaded %d AA Effects.", aa_effects.size());
|
||||
LogFile->write(EQEmuLog::Status, "Loaded %d AA Effects.", aa_effects.size());
|
||||
else
|
||||
LogFile->write(EQEMuLog::Error, "Failed to load AA Effects!");
|
||||
LogFile->write(EQEmuLog::Error, "Failed to load AA Effects!");
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadAAEffects2() {
|
||||
@ -1452,12 +1458,12 @@ bool ZoneDatabase::LoadAAEffects2() {
|
||||
const std::string query = "SELECT aaid, slot, effectid, base1, base2 FROM aa_effects ORDER BY aaid ASC, slot ASC";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAEffects2 query: '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadAAEffects2 query: '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!results.RowCount()) { //no results
|
||||
LogFile->write(EQEMuLog::Error, "Error loading AA Effects, none found in the database.");
|
||||
LogFile->write(EQEmuLog::Error, "Error loading AA Effects, none found in the database.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1794,7 +1800,7 @@ bool ZoneDatabase::LoadAAEffects() {
|
||||
"redux_aa, redux_rate, redux_aa2, redux_rate2 FROM aa_actions";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in LoadAAEffects query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in LoadAAEffects query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1833,7 +1839,7 @@ uint8 ZoneDatabase::GetTotalAALevels(uint32 skill_id) {
|
||||
std::string query = StringFormat("SELECT count(slot) FROM aa_effects WHERE aaid = %i", skill_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetTotalAALevels '%s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in GetTotalAALevels '%s: %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1887,7 +1893,7 @@ uint32 ZoneDatabase::CountAAs(){
|
||||
const std::string query = "SELECT count(title_sid) FROM altadv_vars";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::CountAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::CountAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1904,7 +1910,7 @@ uint32 ZoneDatabase::CountAAEffects() {
|
||||
const std::string query = "SELECT count(id) FROM aa_effects";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::CountAALevels query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::CountAALevels query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1937,14 +1943,14 @@ void ZoneDatabase::LoadAAs(SendAA_Struct **load){
|
||||
load[index]->seq = index+1;
|
||||
}
|
||||
} else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
AARequiredLevelAndCost.clear();
|
||||
query = "SELECT skill_id, level, cost from aa_required_level_cost order by skill_id";
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1962,7 +1968,7 @@ SendAA_Struct* ZoneDatabase::GetAASkillVars(uint32 skill_id)
|
||||
std::string query = "SET @row = 0"; //initialize "row" variable in database for next query
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -1982,7 +1988,7 @@ SendAA_Struct* ZoneDatabase::GetAASkillVars(uint32 skill_id)
|
||||
"FROM altadv_vars a WHERE skill_id=%i", skill_id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -344,7 +344,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
|
||||
// Aggro
|
||||
#if EQDEBUG>=6
|
||||
LogFile->write(EQEMuLog::Debug, "Check aggro for %s target %s.", GetName(), mob->GetName());
|
||||
LogFile->write(EQEmuLog::Debug, "Check aggro for %s target %s.", GetName(), mob->GetName());
|
||||
#endif
|
||||
return( mod_will_aggro(mob, this) );
|
||||
}
|
||||
@ -469,7 +469,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
//Father Nitwit: make sure we can see them.
|
||||
if(mob->CheckLosFN(sender)) {
|
||||
#if (EQDEBUG>=5)
|
||||
LogFile->write(EQEMuLog::Debug, "AIYellForHelp(\"%s\",\"%s\") %s attacking %s Dist %f Z %f",
|
||||
LogFile->write(EQEmuLog::Debug, "AIYellForHelp(\"%s\",\"%s\") %s attacking %s Dist %f Z %f",
|
||||
sender->GetName(), attacker->GetName(), mob->GetName(), attacker->GetName(), mob->DistNoRoot(*sender), fabs(sender->GetZ()+mob->GetZ()));
|
||||
#endif
|
||||
mob->AddToHateList(attacker, 1, 0, false);
|
||||
@ -696,7 +696,7 @@ type', in which case, the answer is yes.
|
||||
}
|
||||
while( reverse++ == 0 );
|
||||
|
||||
LogFile->write(EQEMuLog::Debug, "Mob::IsAttackAllowed: don't have a rule for this - %s vs %s\n", this->GetName(), target->GetName());
|
||||
LogFile->write(EQEmuLog::Debug, "Mob::IsAttackAllowed: don't have a rule for this - %s vs %s\n", this->GetName(), target->GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -836,7 +836,7 @@ bool Mob::IsBeneficialAllowed(Mob *target)
|
||||
}
|
||||
while( reverse++ == 0 );
|
||||
|
||||
LogFile->write(EQEMuLog::Debug, "Mob::IsBeneficialAllowed: don't have a rule for this - %s to %s\n", this->GetName(), target->GetName());
|
||||
LogFile->write(EQEmuLog::Debug, "Mob::IsBeneficialAllowed: don't have a rule for this - %s to %s\n", this->GetName(), target->GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -948,7 +948,7 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
|
||||
oloc.z = posZ + (mobSize==0.0?LOS_DEFAULT_HEIGHT:mobSize)/2 * SEE_POSITION;
|
||||
|
||||
#if LOSDEBUG>=5
|
||||
LogFile->write(EQEMuLog::Debug, "LOS from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f) sizes: (%.2f, %.2f)", myloc.x, myloc.y, myloc.z, oloc.x, oloc.y, oloc.z, GetSize(), mobSize);
|
||||
LogFile->write(EQEmuLog::Debug, "LOS from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f) sizes: (%.2f, %.2f)", myloc.x, myloc.y, myloc.z, oloc.x, oloc.y, oloc.z, GetSize(), mobSize);
|
||||
#endif
|
||||
return zone->zonemap->CheckLoS(myloc, oloc);
|
||||
}
|
||||
@ -1298,7 +1298,7 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {
|
||||
void Mob::RogueEvade(Mob *other)
|
||||
{
|
||||
int amount = other->GetHateAmount(this) - (GetLevel() * 13);
|
||||
other->SetHate(this, std::max(1, amount));
|
||||
other->SetHateAmountOnEnt(this, std::max(1, amount));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w
|
||||
if (weapon && weapon->IsType(ItemClassCommon)) {
|
||||
const Item_Struct* item = weapon->GetItem();
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Debug, "Weapon skill:%i", item->ItemType);
|
||||
LogFile->write(EQEmuLog::Debug, "Weapon skill:%i", item->ItemType);
|
||||
#endif
|
||||
switch (item->ItemType)
|
||||
{
|
||||
@ -192,7 +192,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
chancetohit += RuleR(Combat, NPCBonusHitChance);
|
||||
|
||||
#if ATTACK_DEBUG>=11
|
||||
LogFile->write(EQEMuLog::Debug, "CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
|
||||
LogFile->write(EQEmuLog::Debug, "CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
|
||||
#endif
|
||||
mlog(COMBAT__TOHIT,"CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
|
||||
|
||||
@ -334,7 +334,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
//agains a garunteed riposte (for example) discipline... for now, garunteed hit wins
|
||||
|
||||
#if EQDEBUG>=11
|
||||
LogFile->write(EQEMuLog::Debug, "3 FINAL calculated chance to hit is: %5.2f", chancetohit);
|
||||
LogFile->write(EQEmuLog::Debug, "3 FINAL calculated chance to hit is: %5.2f", chancetohit);
|
||||
#endif
|
||||
|
||||
//
|
||||
@ -1135,7 +1135,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
{
|
||||
if (!other) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Client::Attack() for evaluation!");
|
||||
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Client::Attack() for evaluation!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1518,7 +1518,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
||||
}
|
||||
|
||||
entity_list.RemoveFromTargets(this);
|
||||
hate_list.RemoveEnt(this);
|
||||
hate_list.RemoveEntFromHateList(this);
|
||||
RemoveAutoXTargets();
|
||||
|
||||
//remove ourself from all proximities
|
||||
@ -1699,7 +1699,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
|
||||
if (!other) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to NPC::Attack() for evaluation!");
|
||||
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to NPC::Attack() for evaluation!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2036,7 +2036,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
{
|
||||
zone->DelAggroMob();
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Debug,"NPC::Death() Mobs currently Aggro %i", zone->MobsAggroCount());
|
||||
LogFile->write(EQEmuLog::Debug,"NPC::Death() Mobs currently Aggro %i", zone->MobsAggroCount());
|
||||
#endif
|
||||
}
|
||||
SetHP(0);
|
||||
@ -2076,12 +2076,12 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
|
||||
if (killerMob) {
|
||||
if(GetClass() != LDON_TREASURE)
|
||||
hate_list.Add(killerMob, damage);
|
||||
hate_list.AddEntToHateList(killerMob, damage);
|
||||
}
|
||||
|
||||
safe_delete(app);
|
||||
|
||||
Mob *give_exp = hate_list.GetDamageTop(this);
|
||||
Mob *give_exp = hate_list.GetDamageTopOnHateList(this);
|
||||
|
||||
if(give_exp == nullptr)
|
||||
give_exp = killer;
|
||||
@ -2400,7 +2400,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, bool bFrenzy, bool iBuffTic) {
|
||||
void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/)
|
||||
{
|
||||
|
||||
assert(other != nullptr);
|
||||
|
||||
@ -2413,7 +2414,7 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
|
||||
|
||||
bool wasengaged = IsEngaged();
|
||||
Mob* owner = other->GetOwner();
|
||||
Mob* mypet = this->GetPet();
|
||||
Mob* mypet = this->GetPet();
|
||||
Mob* myowner = this->GetOwner();
|
||||
Mob* targetmob = this->GetTarget();
|
||||
|
||||
@ -2488,7 +2489,7 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
|
||||
&& other && (buffs[spellbonuses.ImprovedTaunt[2]].casterid != other->GetID()))
|
||||
hate = (hate*spellbonuses.ImprovedTaunt[1])/100;
|
||||
|
||||
hate_list.Add(other, hate, damage, bFrenzy, !iBuffTic);
|
||||
hate_list.AddEntToHateList(other, hate, damage, bFrenzy, !iBuffTic);
|
||||
|
||||
if(other->IsClient())
|
||||
other->CastToClient()->AddAutoXTarget(this);
|
||||
@ -2500,8 +2501,8 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
|
||||
AddFeignMemory(other->CastToBot()->GetBotOwner()->CastToClient());
|
||||
}
|
||||
else {
|
||||
if(!hate_list.IsOnHateList(other->CastToBot()->GetBotOwner()))
|
||||
hate_list.Add(other->CastToBot()->GetBotOwner(), 0, 0, false, true);
|
||||
if(!hate_list.IsEntOnHateList(other->CastToBot()->GetBotOwner()))
|
||||
hate_list.AddEntToHateList(other->CastToBot()->GetBotOwner(), 0, 0, false, true);
|
||||
}
|
||||
}
|
||||
#endif //BOTS
|
||||
@ -2512,8 +2513,8 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
|
||||
AddFeignMemory(other->CastToMerc()->GetMercOwner()->CastToClient());
|
||||
}
|
||||
else {
|
||||
if(!hate_list.IsOnHateList(other->CastToMerc()->GetMercOwner()))
|
||||
hate_list.Add(other->CastToMerc()->GetMercOwner(), 0, 0, false, true);
|
||||
if(!hate_list.IsEntOnHateList(other->CastToMerc()->GetMercOwner()))
|
||||
hate_list.AddEntToHateList(other->CastToMerc()->GetMercOwner(), 0, 0, false, true);
|
||||
}
|
||||
} //MERC
|
||||
|
||||
@ -2528,7 +2529,7 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
|
||||
// owner must get on list, but he's not actually gained any hate yet
|
||||
if(!owner->GetSpecialAbility(IMMUNE_AGGRO))
|
||||
{
|
||||
hate_list.Add(owner, 0, 0, false, !iBuffTic);
|
||||
hate_list.AddEntToHateList(owner, 0, 0, false, !iBuffTic);
|
||||
if(owner->IsClient())
|
||||
owner->CastToClient()->AddAutoXTarget(this);
|
||||
}
|
||||
@ -2537,10 +2538,10 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
|
||||
|
||||
if (mypet && (!(GetAA(aaPetDiscipline) && mypet->IsHeld()))) { // I have a pet, add other to it
|
||||
if(!mypet->IsFamiliar() && !mypet->GetSpecialAbility(IMMUNE_AGGRO))
|
||||
mypet->hate_list.Add(other, 0, 0, bFrenzy);
|
||||
mypet->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
|
||||
} else if (myowner) { // I am a pet, add other to owner if it's NPC/LD
|
||||
if (myowner->IsAIControlled() && !myowner->GetSpecialAbility(IMMUNE_AGGRO))
|
||||
myowner->hate_list.Add(other, 0, 0, bFrenzy);
|
||||
myowner->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
|
||||
}
|
||||
|
||||
if (other->GetTempPetCount())
|
||||
@ -3890,11 +3891,12 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 h
|
||||
return ProcChance;
|
||||
}
|
||||
|
||||
// argument 'weapon' not used
|
||||
void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
|
||||
|
||||
if (!on) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TryDefensiveProc for evaluation!");
|
||||
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Mob::TryDefensiveProc for evaluation!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3925,7 +3927,7 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
|
||||
void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
||||
if(!on) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TryWeaponProc for evaluation!");
|
||||
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Mob::TryWeaponProc for evaluation!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4474,7 +4476,7 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
|
||||
|
||||
if (!on) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TrySkillProc for evaluation!");
|
||||
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Mob::TrySkillProc for evaluation!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4932,7 +4934,7 @@ void Client::SetAttackTimer()
|
||||
// this is probably wrong
|
||||
if (quiver_haste > 0)
|
||||
speed *= quiver_haste;
|
||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true);
|
||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
||||
|
||||
if (i == MainPrimary)
|
||||
PrimaryWeapon = ItemToUse;
|
||||
@ -4980,6 +4982,6 @@ void NPC::SetAttackTimer()
|
||||
}
|
||||
}
|
||||
|
||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true);
|
||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
892
zone/bonuses.cpp
892
zone/bonuses.cpp
File diff suppressed because it is too large
Load Diff
206
zone/bot.cpp
206
zone/bot.cpp
@ -234,45 +234,28 @@ void Bot::SetBotSpellID(uint32 newSpellID) {
|
||||
this->npc_spells_id = newSpellID;
|
||||
}
|
||||
|
||||
uint32 Bot::GetBotArcheryRange() {
|
||||
uint32 result = 0;
|
||||
uint32 Bot::GetBotArcheryRange()
|
||||
{
|
||||
const ItemInst *range_inst = GetBotItem(MainRange);
|
||||
const ItemInst *ammo_inst = GetBotItem(MainAmmo);
|
||||
|
||||
ItemInst* rangeItem = GetBotItem(MainRange);
|
||||
|
||||
if(!rangeItem)
|
||||
// empty slots
|
||||
if (!range_inst || !ammo_inst)
|
||||
return 0;
|
||||
|
||||
const Item_Struct* botweapon = rangeItem->GetItem();
|
||||
const Item_Struct *range_item = range_inst->GetItem();
|
||||
const Item_Struct *ammo_item = ammo_inst->GetItem();
|
||||
|
||||
uint32 archeryMaterial;
|
||||
uint32 archeryColor;
|
||||
uint32 archeryBowID;
|
||||
uint32 archeryAmmoID;
|
||||
// no item struct for whatever reason
|
||||
if (!range_item || !ammo_item)
|
||||
return 0;
|
||||
|
||||
if(botweapon && botweapon->ItemType == ItemTypeBow) {
|
||||
uint32 range = 0;
|
||||
// bad item types
|
||||
if (range_item->ItemType != ItemTypeBow || ammo_item->ItemType != ItemTypeArrow)
|
||||
return 0;
|
||||
|
||||
archeryMaterial = atoi(botweapon->IDFile + 2);
|
||||
archeryBowID = botweapon->ID;
|
||||
archeryColor = botweapon->Color;
|
||||
range =+ botweapon->Range;
|
||||
|
||||
rangeItem = GetBotItem(MainAmmo);
|
||||
if(rangeItem)
|
||||
botweapon = rangeItem->GetItem();
|
||||
|
||||
if(!botweapon || (botweapon->ItemType != ItemTypeArrow)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
range += botweapon->Range;
|
||||
|
||||
archeryAmmoID = botweapon->ID;
|
||||
|
||||
result = range;
|
||||
}
|
||||
|
||||
return result;
|
||||
// everything is good!
|
||||
return range_item->Range + ammo_item->Range;
|
||||
}
|
||||
|
||||
void Bot::ChangeBotArcherWeapons(bool isArcher) {
|
||||
@ -386,8 +369,8 @@ NPCType Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::str
|
||||
|
||||
BotNPCType.npc_id = 0;
|
||||
BotNPCType.texture = 0;
|
||||
BotNPCType.d_meele_texture1 = 0;
|
||||
BotNPCType.d_meele_texture2 = 0;
|
||||
BotNPCType.d_melee_texture1 = 0;
|
||||
BotNPCType.d_melee_texture2 = 0;
|
||||
BotNPCType.qglobal = false;
|
||||
BotNPCType.attack_speed = 0;
|
||||
BotNPCType.runspeed = 1.25;
|
||||
@ -431,8 +414,8 @@ NPCType Bot::CreateDefaultNPCTypeStructForBot(std::string botName, std::string b
|
||||
Result.hp_regen = 1;
|
||||
Result.mana_regen = 1;
|
||||
Result.texture = 0;
|
||||
Result.d_meele_texture1 = 0;
|
||||
Result.d_meele_texture2 = 0;
|
||||
Result.d_melee_texture1 = 0;
|
||||
Result.d_melee_texture2 = 0;
|
||||
Result.qglobal = false;
|
||||
Result.npc_spells_id = 0;
|
||||
Result.attack_speed = 0;
|
||||
@ -1242,7 +1225,7 @@ int32 Bot::acmod()
|
||||
return (65 + ((agility-300) / 21));
|
||||
}
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::acmod(): Agility: %i, Level: %i",agility,level);
|
||||
LogFile->write(EQEmuLog::Error, "Error in Bot::acmod(): Agility: %i, Level: %i",agility,level);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -1479,7 +1462,7 @@ void Bot::LoadAAs() {
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadAAs()");
|
||||
LogFile->write(EQEmuLog::Error, "Error in Bot::LoadAAs()");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2791,7 +2774,7 @@ void Bot::LoadStance() {
|
||||
std::string query = StringFormat("SELECT StanceID FROM botstances WHERE BotID = %u;", GetBotID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success() || results.RowCount() == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadStance()");
|
||||
LogFile->write(EQEmuLog::Error, "Error in Bot::LoadStance()");
|
||||
SetDefaultBotStance();
|
||||
return;
|
||||
}
|
||||
@ -2809,7 +2792,7 @@ void Bot::SaveStance() {
|
||||
"VALUES(%u, %u);", GetBotID(), GetBotStance());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::SaveStance()");
|
||||
LogFile->write(EQEmuLog::Error, "Error in Bot::SaveStance()");
|
||||
|
||||
}
|
||||
|
||||
@ -2824,7 +2807,7 @@ void Bot::LoadTimers() {
|
||||
GetBotID(), DisciplineReuseStart-1, DisciplineReuseStart-1, GetClass(), GetLevel());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadTimers()");
|
||||
LogFile->write(EQEmuLog::Error, "Error in Bot::LoadTimers()");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2864,7 +2847,7 @@ void Bot::SaveTimers() {
|
||||
}
|
||||
|
||||
if(hadError)
|
||||
LogFile->write(EQEMuLog::Error, "Error in Bot::SaveTimers()");
|
||||
LogFile->write(EQEmuLog::Error, "Error in Bot::SaveTimers()");
|
||||
|
||||
}
|
||||
|
||||
@ -3439,9 +3422,9 @@ void Bot::AI_Process() {
|
||||
rest_timer.Disable();
|
||||
|
||||
if(IsRooted())
|
||||
SetTarget(hate_list.GetClosest(this));
|
||||
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
||||
else
|
||||
SetTarget(hate_list.GetTop(this));
|
||||
SetTarget(hate_list.GetEntWithMostHateOnList(this));
|
||||
|
||||
if(!GetTarget())
|
||||
return;
|
||||
@ -3808,9 +3791,9 @@ void Bot::PetAIProcess() {
|
||||
if (IsEngaged()) {
|
||||
|
||||
if (botPet->IsRooted())
|
||||
botPet->SetTarget(hate_list.GetClosest(botPet));
|
||||
botPet->SetTarget(hate_list.GetClosestEntOnHateList(botPet));
|
||||
else
|
||||
botPet->SetTarget(hate_list.GetTop(botPet));
|
||||
botPet->SetTarget(hate_list.GetEntWithMostHateOnList(botPet));
|
||||
|
||||
// Let's check if we have a los with our target.
|
||||
// If we don't, our hate_list is wiped.
|
||||
@ -4228,7 +4211,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
|
||||
|
||||
ItemInst* inst = database.CreateItem(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]);
|
||||
if (!inst) {
|
||||
LogFile->write(EQEMuLog::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id);
|
||||
LogFile->write(EQEmuLog::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -4252,7 +4235,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
|
||||
|
||||
// Save ptr to item in inventory
|
||||
if (put_slot_id == INVALID_INDEX)
|
||||
LogFile->write(EQEMuLog::Error, "Warning: Invalid slot_id for item in inventory: botid=%i, item_id=%i, slot_id=%i",this->GetBotID(), item_id, slot_id);
|
||||
LogFile->write(EQEmuLog::Error, "Warning: Invalid slot_id for item in inventory: botid=%i, item_id=%i, slot_id=%i",this->GetBotID(), item_id, slot_id);
|
||||
|
||||
}
|
||||
|
||||
@ -5871,7 +5854,7 @@ bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, SkillUseTypes att
|
||||
|
||||
Save();
|
||||
|
||||
Mob *give_exp = hate_list.GetDamageTop(this);
|
||||
Mob *give_exp = hate_list.GetDamageTopOnHateList(this);
|
||||
Client *give_exp_client = nullptr;
|
||||
|
||||
if(give_exp && give_exp->IsClient())
|
||||
@ -6025,7 +6008,7 @@ void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, SkillUseTypes attack_
|
||||
}
|
||||
}
|
||||
|
||||
void Bot::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, bool bFrenzy, bool iBuffTic)
|
||||
void Bot::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/)
|
||||
{
|
||||
Mob::AddToHateList(other, hate, damage, iYellForHelp, bFrenzy, iBuffTic);
|
||||
}
|
||||
@ -6034,7 +6017,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
{
|
||||
if (!other) {
|
||||
SetTarget(nullptr);
|
||||
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
|
||||
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7045,7 +7028,7 @@ int32 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
|
||||
LogFile->write(EQEmuLog::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -7353,7 +7336,7 @@ int32 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
|
||||
//this spits up a lot of garbage when calculating spell focuses
|
||||
//since they have all kinds of extra effects on them.
|
||||
default:
|
||||
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
||||
LogFile->write(EQEmuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -8567,7 +8550,7 @@ int32 Bot::CalcMaxMana() {
|
||||
}
|
||||
default:
|
||||
{
|
||||
LogFile->write(EQEMuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
|
||||
LogFile->write(EQEmuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
@ -11716,106 +11699,46 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
const char* equipped[EmuConstants::EQUIPMENT_SIZE] = {"Charm", "Left Ear", "Head", "Face", "Right Ear", "Neck", "Shoulders", "Arms", "Back",
|
||||
"Left Wrist", "Right Wrist", "Range", "Hands", "Primary Hand", "Secondary Hand",
|
||||
"Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo" };
|
||||
const ItemInst* item1 = nullptr;
|
||||
const Item_Struct* item2 = nullptr;
|
||||
|
||||
const ItemInst* inst = nullptr;
|
||||
const Item_Struct* item = nullptr;
|
||||
bool is2Hweapon = false;
|
||||
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i)
|
||||
{
|
||||
|
||||
std::string item_link;
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemInst);
|
||||
|
||||
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
|
||||
if((i == MainSecondary) && is2Hweapon) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item1 = b->CastToBot()->GetBotItem(i);
|
||||
if(item1)
|
||||
item2 = item1->GetItem();
|
||||
inst = b->CastToBot()->GetBotItem(i);
|
||||
if (inst)
|
||||
item = inst->GetItem();
|
||||
else
|
||||
item2 = nullptr;
|
||||
item = nullptr;
|
||||
|
||||
if(!TempErrorMessage.empty()) {
|
||||
c->Message(13, "Database Error: %s", TempErrorMessage.c_str());
|
||||
return;
|
||||
}
|
||||
if(item2 == 0) {
|
||||
if(item == nullptr) {
|
||||
c->Message(15, "I need something for my %s (Item %i)", equipped[i], i);
|
||||
continue;
|
||||
}
|
||||
if((i == MainPrimary) && ((item2->ItemType == ItemType2HSlash) || (item2->ItemType == ItemType2HBlunt) || (item2->ItemType == ItemType2HPiercing))) {
|
||||
if((i == MainPrimary) && ((item->ItemType == ItemType2HSlash) || (item->ItemType == ItemType2HBlunt) || (item->ItemType == ItemType2HPiercing))) {
|
||||
is2Hweapon = true;
|
||||
}
|
||||
|
||||
char* itemLink = 0;
|
||||
if((i == MainCharm) || (i == MainRange) || (i == MainPrimary) || (i == MainSecondary) || (i == MainAmmo)) {
|
||||
if (c->GetClientVersion() >= EQClientSoF)
|
||||
{
|
||||
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
|
||||
0,
|
||||
item2->ID,
|
||||
item1->GetAugmentItemID(0),
|
||||
item1->GetAugmentItemID(1),
|
||||
item1->GetAugmentItemID(2),
|
||||
item1->GetAugmentItemID(3),
|
||||
item1->GetAugmentItemID(4),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
|
||||
}
|
||||
else
|
||||
{
|
||||
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
|
||||
0,
|
||||
item2->ID,
|
||||
item1->GetAugmentItemID(0),
|
||||
item1->GetAugmentItemID(1),
|
||||
item1->GetAugmentItemID(2),
|
||||
item1->GetAugmentItemID(3),
|
||||
item1->GetAugmentItemID(4),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetClientVersion() >= EQClientSoF)
|
||||
{
|
||||
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
|
||||
0,
|
||||
item2->ID,
|
||||
item1->GetAugmentItemID(0),
|
||||
item1->GetAugmentItemID(1),
|
||||
item1->GetAugmentItemID(2),
|
||||
item1->GetAugmentItemID(3),
|
||||
item1->GetAugmentItemID(4),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
|
||||
}
|
||||
else
|
||||
{
|
||||
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
|
||||
0,
|
||||
item2->ID,
|
||||
item1->GetAugmentItemID(0),
|
||||
item1->GetAugmentItemID(1),
|
||||
item1->GetAugmentItemID(2),
|
||||
item1->GetAugmentItemID(3),
|
||||
item1->GetAugmentItemID(4),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
|
||||
}
|
||||
}
|
||||
// I could not find a difference between the criteria positive code and the criteria negative code..
|
||||
// ..so, I deleted the check (old criteria: i = { MainCharm, MainRange, MainPrimary, MainSecondary, MainAmmo })
|
||||
|
||||
linker.SetItemInst(inst);
|
||||
|
||||
item_link = linker.GenerateLink();
|
||||
|
||||
c->Message(15, "Using %s in my %s (Item %i)", item_link.c_str(), equipped[i], i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -14364,8 +14287,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<BotGroup>::iterator botGroupItr = botGroup.begin();
|
||||
for(botGroupItr; botGroupItr != botGroup.end(); ++botGroupItr) {
|
||||
for(auto botGroupItr = botGroup.begin(); botGroupItr != botGroup.end(); ++botGroupItr) {
|
||||
// Don't try to re-spawn the botgroup's leader.
|
||||
if(botGroupItr->BotID == botGroupLeader->GetBotID()) { continue; }
|
||||
|
||||
@ -15474,7 +15396,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
else {
|
||||
Mob *target = c->GetTarget();
|
||||
|
||||
if(target->IsBot() && (c == target->GetOwner()->CastToClient())) {
|
||||
if(target && target->IsBot() && (c == target->GetOwner()->CastToClient())) {
|
||||
const InspectMessage_Struct& playermessage = c->GetInspectMessage();
|
||||
InspectMessage_Struct& botmessage = target->CastToBot()->GetInspectMessage();
|
||||
|
||||
@ -15504,7 +15426,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
|
||||
Mob *target = c->GetTarget();
|
||||
|
||||
if(target->IsBot() && (c == target->GetOwner()->CastToClient())) {
|
||||
if(target && target->IsBot() && (c == target->GetOwner()->CastToClient())) {
|
||||
Bot* bardBot = target->CastToBot();
|
||||
|
||||
if(bardBot) {
|
||||
|
||||
@ -208,7 +208,7 @@ public:
|
||||
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, uint16 slot, bool &stopLogic);
|
||||
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
|
||||
void Camp(bool databaseSave = true);
|
||||
virtual void AddToHateList(Mob* other, int32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false);
|
||||
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false);
|
||||
virtual void SetTarget(Mob* mob);
|
||||
virtual void Zone();
|
||||
std::vector<AISpells_Struct> GetBotSpells() { return AIspells; }
|
||||
|
||||
330
zone/client.cpp
330
zone/client.cpp
@ -327,7 +327,7 @@ Client::~Client() {
|
||||
ToggleBuyerMode(false);
|
||||
|
||||
if(conn_state != ClientConnectFinished) {
|
||||
LogFile->write(EQEMuLog::Debug, "Client '%s' was destroyed before reaching the connected state:", GetName());
|
||||
LogFile->write(EQEmuLog::Debug, "Client '%s' was destroyed before reaching the connected state:", GetName());
|
||||
ReportConnectingState();
|
||||
}
|
||||
|
||||
@ -425,31 +425,31 @@ void Client::SendLogoutPackets() {
|
||||
void Client::ReportConnectingState() {
|
||||
switch(conn_state) {
|
||||
case NoPacketsReceived: //havent gotten anything
|
||||
LogFile->write(EQEMuLog::Debug, "Client has not sent us an initial zone entry packet.");
|
||||
LogFile->write(EQEmuLog::Debug, "Client has not sent us an initial zone entry packet.");
|
||||
break;
|
||||
case ReceivedZoneEntry: //got the first packet, loading up PP
|
||||
LogFile->write(EQEMuLog::Debug, "Client sent initial zone packet, but we never got their player info from the database.");
|
||||
LogFile->write(EQEmuLog::Debug, "Client sent initial zone packet, but we never got their player info from the database.");
|
||||
break;
|
||||
case PlayerProfileLoaded: //our DB work is done, sending it
|
||||
LogFile->write(EQEMuLog::Debug, "We were sending the player profile, tributes, tasks, spawns, time and weather, but never finished.");
|
||||
LogFile->write(EQEmuLog::Debug, "We were sending the player profile, tributes, tasks, spawns, time and weather, but never finished.");
|
||||
break;
|
||||
case ZoneInfoSent: //includes PP, tributes, tasks, spawns, time and weather
|
||||
LogFile->write(EQEMuLog::Debug, "We successfully sent player info and spawns, waiting for client to request new zone.");
|
||||
LogFile->write(EQEmuLog::Debug, "We successfully sent player info and spawns, waiting for client to request new zone.");
|
||||
break;
|
||||
case NewZoneRequested: //received and sent new zone request
|
||||
LogFile->write(EQEMuLog::Debug, "We received client's new zone request, waiting for client spawn request.");
|
||||
LogFile->write(EQEmuLog::Debug, "We received client's new zone request, waiting for client spawn request.");
|
||||
break;
|
||||
case ClientSpawnRequested: //client sent ReqClientSpawn
|
||||
LogFile->write(EQEMuLog::Debug, "We received the client spawn request, and were sending objects, doors, zone points and some other stuff, but never finished.");
|
||||
LogFile->write(EQEmuLog::Debug, "We received the client spawn request, and were sending objects, doors, zone points and some other stuff, but never finished.");
|
||||
break;
|
||||
case ZoneContentsSent: //objects, doors, zone points
|
||||
LogFile->write(EQEMuLog::Debug, "The rest of the zone contents were successfully sent, waiting for client ready notification.");
|
||||
LogFile->write(EQEmuLog::Debug, "The rest of the zone contents were successfully sent, waiting for client ready notification.");
|
||||
break;
|
||||
case ClientReadyReceived: //client told us its ready, send them a bunch of crap like guild MOTD, etc
|
||||
LogFile->write(EQEMuLog::Debug, "We received client ready notification, but never finished Client::CompleteConnect");
|
||||
LogFile->write(EQEmuLog::Debug, "We received client ready notification, but never finished Client::CompleteConnect");
|
||||
break;
|
||||
case ClientConnectFinished: //client finally moved to finished state, were done here
|
||||
LogFile->write(EQEMuLog::Debug, "Client is successfully connected.");
|
||||
LogFile->write(EQEmuLog::Debug, "Client is successfully connected.");
|
||||
break;
|
||||
};
|
||||
}
|
||||
@ -640,7 +640,7 @@ bool Client::SendAllPackets() {
|
||||
eqs->FastQueuePacket((EQApplicationPacket **)&cp->app, cp->ack_req);
|
||||
iterator.RemoveCurrent();
|
||||
#if EQDEBUG >= 6
|
||||
LogFile->write(EQEMuLog::Normal, "Transmitting a packet");
|
||||
LogFile->write(EQEmuLog::Normal, "Transmitting a packet");
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
@ -691,7 +691,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
|
||||
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Debug,"Client::ChannelMessageReceived() Channel:%i message:'%s'", chan_num, message);
|
||||
LogFile->write(EQEmuLog::Debug,"Client::ChannelMessageReceived() Channel:%i message:'%s'", chan_num, message);
|
||||
#endif
|
||||
|
||||
if (targetname == nullptr) {
|
||||
@ -1807,45 +1807,8 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
}
|
||||
ns->spawn.size = 0; // Changing size works, but then movement stops! (wth?)
|
||||
ns->spawn.runspeed = (gmspeed == 0) ? runspeed : 3.125f;
|
||||
if (!m_pp.showhelm) ns->spawn.showhelm = 0;
|
||||
ns->spawn.showhelm = m_pp.showhelm ? 1 : 0;
|
||||
|
||||
/*
|
||||
// Equipment/Weapons already set from Mob::FillSpawnStruct
|
||||
// Commenting this out for now
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemInst* inst = nullptr;
|
||||
int16 invslot;
|
||||
|
||||
for (uint32 matslot = 0; matslot < _MaterialCount; matslot++)
|
||||
{
|
||||
// Only Player Races Wear Armor
|
||||
if (IsPlayerRace(race) || matslot > 6)
|
||||
{
|
||||
invslot = Inventory::CalcSlotFromMaterial(matslot);
|
||||
if (invslot == INVALID_INDEX)
|
||||
continue;
|
||||
|
||||
if ((inst = m_inv[invslot]) && inst->IsType(ItemClassCommon))
|
||||
{
|
||||
item = inst->GetItem();
|
||||
|
||||
if (matslot > 6)
|
||||
{
|
||||
// Weapon Models
|
||||
ns->spawn.equipment[matslot].material = GetEquipmentMaterial(matslot);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Armor Materials/Models
|
||||
ns->spawn.equipment[matslot].material = item->Material;
|
||||
ns->spawn.equipment[matslot].elitematerial = item->EliteMaterial;
|
||||
ns->spawn.equipment[matslot].heroforgemodel = GetHerosForgeModel(matslot);
|
||||
ns->spawn.colors[matslot].color = m_pp.item_tint[matslot].rgb.use_tint ? m_pp.item_tint[matslot].color : item->Color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
bool Client::GMHideMe(Client* client) {
|
||||
@ -1944,7 +1907,7 @@ void Client::ReadBook(BookRequest_Struct *book) {
|
||||
|
||||
if (booktxt2[0] != '\0') {
|
||||
#if EQDEBUG >= 6
|
||||
LogFile->write(EQEMuLog::Normal,"Client::ReadBook() textfile:%s Text:%s", txtfile, booktxt2.c_str());
|
||||
LogFile->write(EQEmuLog::Normal,"Client::ReadBook() textfile:%s Text:%s", txtfile, booktxt2.c_str());
|
||||
#endif
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ReadBook, length + sizeof(BookText_Struct));
|
||||
|
||||
@ -2138,7 +2101,7 @@ void Client::AddMoneyToPP(uint64 copper, bool updateclient){
|
||||
|
||||
SaveCurrency();
|
||||
|
||||
LogFile->write(EQEMuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
|
||||
LogFile->write(EQEmuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
|
||||
}
|
||||
|
||||
void Client::EVENT_ITEM_ScriptStopReturn(){
|
||||
@ -2178,7 +2141,7 @@ void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 plat
|
||||
SaveCurrency();
|
||||
|
||||
#if (EQDEBUG>=5)
|
||||
LogFile->write(EQEMuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i",
|
||||
LogFile->write(EQEmuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i",
|
||||
GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
|
||||
#endif
|
||||
}
|
||||
@ -2397,7 +2360,7 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(SkillUseTypes skillid, uint16
|
||||
|
||||
Save();
|
||||
|
||||
LogFile->write(EQEMuLog::Normal, "Reset %s's caster specialization skills to 1. "
|
||||
LogFile->write(EQEmuLog::Normal, "Reset %s's caster specialization skills to 1. "
|
||||
"Too many specializations skills were above 50.", GetCleanName());
|
||||
}
|
||||
|
||||
@ -4577,14 +4540,14 @@ void Client::HandleLDoNOpen(NPC *target)
|
||||
{
|
||||
if(target->GetClass() != LDON_TREASURE)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Debug, "%s tried to open %s but %s was not a treasure chest.",
|
||||
LogFile->write(EQEmuLog::Debug, "%s tried to open %s but %s was not a treasure chest.",
|
||||
GetName(), target->GetName(), target->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
if(DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Debug, "%s tried to open %s but %s was out of range",
|
||||
LogFile->write(EQEmuLog::Debug, "%s tried to open %s but %s was out of range",
|
||||
GetName(), target->GetName(), target->GetName());
|
||||
Message(13, "Treasure chest out of range.");
|
||||
return;
|
||||
@ -5319,7 +5282,7 @@ void Client::SendRewards()
|
||||
"ORDER BY reward_id", AccountID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Client::SendRewards(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in Client::SendRewards(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5387,7 +5350,7 @@ bool Client::TryReward(uint32 claim_id) {
|
||||
AccountID(), claim_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5414,7 +5377,7 @@ bool Client::TryReward(uint32 claim_id) {
|
||||
AccountID(), claim_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
else {
|
||||
query = StringFormat("UPDATE account_rewards SET amount = (amount-1) "
|
||||
@ -5422,7 +5385,7 @@ bool Client::TryReward(uint32 claim_id) {
|
||||
AccountID(), claim_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
InternalVeteranReward ivr = (*iter);
|
||||
@ -6236,7 +6199,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
|
||||
PetRecord record;
|
||||
if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Unknown doppelganger spell id: %d, check pets table", spell_id);
|
||||
LogFile->write(EQEmuLog::Error, "Unknown doppelganger spell id: %d, check pets table", spell_id);
|
||||
Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone);
|
||||
return;
|
||||
}
|
||||
@ -6250,7 +6213,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
|
||||
|
||||
const NPCType *npc_type = database.GetNPCType(pet.npc_id);
|
||||
if(npc_type == nullptr) {
|
||||
LogFile->write(EQEMuLog::Error, "Unknown npc type for doppelganger spell id: %d", spell_id);
|
||||
LogFile->write(EQEmuLog::Error, "Unknown npc type for doppelganger spell id: %d", spell_id);
|
||||
Message(0,"Unable to find pet!");
|
||||
return;
|
||||
}
|
||||
@ -6274,6 +6237,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
|
||||
made_npc->DR = GetDR();
|
||||
made_npc->PR = GetPR();
|
||||
made_npc->Corrup = GetCorrup();
|
||||
made_npc->PhR = GetPhR();
|
||||
// looks
|
||||
made_npc->texture = GetEquipmentMaterial(MaterialChest);
|
||||
made_npc->helmtexture = GetEquipmentMaterial(MaterialHead);
|
||||
@ -6287,8 +6251,8 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
|
||||
made_npc->drakkin_heritage = GetDrakkinHeritage();
|
||||
made_npc->drakkin_tattoo = GetDrakkinTattoo();
|
||||
made_npc->drakkin_details = GetDrakkinDetails();
|
||||
made_npc->d_meele_texture1 = GetEquipmentMaterial(MaterialPrimary);
|
||||
made_npc->d_meele_texture2 = GetEquipmentMaterial(MaterialSecondary);
|
||||
made_npc->d_melee_texture1 = GetEquipmentMaterial(MaterialPrimary);
|
||||
made_npc->d_melee_texture2 = GetEquipmentMaterial(MaterialSecondary);
|
||||
for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_END; i++) {
|
||||
made_npc->armor_tint[i] = GetEquipmentColor(i);
|
||||
}
|
||||
@ -6374,7 +6338,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
|
||||
|
||||
// Set Class
|
||||
std::string class_Name = itoa(GetClass());
|
||||
std::string class_List[] = { "WAR", "CLR", "PAL", "RNG", "SK", "DRU", "MNK", "BRD", "ROG", "SHM", "NEC", "WIZ", "MAG", "ENC", "BST", "BER" };
|
||||
std::string class_List[] = { "WAR", "CLR", "PAL", "RNG", "SHD", "DRU", "MNK", "BRD", "ROG", "SHM", "NEC", "WIZ", "MAG", "ENC", "BST", "BER" };
|
||||
|
||||
if(GetClass() < 17 && GetClass() > 0) { class_Name = class_List[GetClass()-1]; }
|
||||
|
||||
@ -6462,7 +6426,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
|
||||
/*===========================*/
|
||||
std::string regen_row_header = "";
|
||||
std::string regen_row_color = "";
|
||||
std::string base_regen_field = "";
|
||||
std::string base_regen_field = "";
|
||||
std::string base_regen_spacing = "";
|
||||
std::string item_regen_field = "";
|
||||
std::string item_regen_spacing = "";
|
||||
@ -6623,8 +6587,11 @@ void Client::SendStatsWindow(Client* client, bool use_window)
|
||||
}
|
||||
case 6: {
|
||||
a_stat_name = " CHA: ";
|
||||
a_resist_name = "PhR: "; // Not implemented for clients yet
|
||||
a_stat = itoa(GetCHA());
|
||||
h_stat = itoa(GetHeroicCHA());
|
||||
a_resist = itoa(GetPhR());
|
||||
h_resist_field = itoa(GetHeroicPhR());
|
||||
break;
|
||||
}
|
||||
default: { break; }
|
||||
@ -6639,8 +6606,9 @@ void Client::SendStatsWindow(Client* client, bool use_window)
|
||||
for(int h = a_resist.size(); h < max_stat_value_len; h++) { a_resist_spacing += " . "; }
|
||||
|
||||
stat_field += indP + a_stat_name + a_stat_spacing + a_stat + heroic_color + h_stat + "</c>";
|
||||
stat_field += h_stat_spacing + a_resist_name + a_resist_spacing + a_resist + heroic_color + h_resist_field + "</c>";
|
||||
if(stat_row_counter < 6) {
|
||||
stat_field += h_stat_spacing + a_resist_name + a_resist_spacing + a_resist + heroic_color + h_resist_field + "</c><br>";
|
||||
stat_field += "<br>";
|
||||
}
|
||||
}
|
||||
/*##########################################################
|
||||
@ -6849,7 +6817,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
|
||||
client->Message(0, " Haste: %i / %i (Item: %i + Spell: %i + Over: %i)", GetHaste(), RuleI(Character, HasteCap), itembonuses.haste, spellbonuses.haste + spellbonuses.hastetype2, spellbonuses.hastetype3 + ExtraHaste);
|
||||
client->Message(0, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA());
|
||||
client->Message(0, " hSTR: %i hSTA: %i hDEX: %i hAGI: %i hINT: %i hWIS: %i hCHA: %i", GetHeroicSTR(), GetHeroicSTA(), GetHeroicDEX(), GetHeroicAGI(), GetHeroicINT(), GetHeroicWIS(), GetHeroicCHA());
|
||||
client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup());
|
||||
client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR());
|
||||
client->Message(0, " hMR: %i hPR: %i hFR: %i hCR: %i hDR: %i hCorruption: %i", GetHeroicMR(), GetHeroicPR(), GetHeroicFR(), GetHeroicCR(), GetHeroicDR(), GetHeroicCorrup());
|
||||
client->Message(0, " Shielding: %i Spell Shield: %i DoT Shielding: %i Stun Resist: %i Strikethrough: %i Avoidance: %i Accuracy: %i Combat Effects: %i", GetShielding(), GetSpellShield(), GetDoTShield(), GetStunResist(), GetStrikeThrough(), GetAvoidance(), GetAccuracy(), GetCombatEffects());
|
||||
client->Message(0, " Heal Amt.: %i Spell Dmg.: %i Clairvoyance: %i DS Mitigation: %i", GetHealAmt(), GetSpellDmg(), GetClair(), GetDSMit());
|
||||
@ -7487,8 +7455,17 @@ void Client::GarbleMessage(char *message, uint8 variance)
|
||||
{
|
||||
// Garble message by variance%
|
||||
const char alpha_list[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; // only change alpha characters for now
|
||||
const char delimiter = 0x12;
|
||||
int delimiter_count = 0;
|
||||
|
||||
for (size_t i = 0; i < strlen(message); i++) {
|
||||
// Client expects hex values inside of a text link body
|
||||
if (message[i] == delimiter) {
|
||||
if (!(delimiter_count & 1)) { i += EmuConstants::TEXT_LINK_BODY_LENGTH; }
|
||||
++delimiter_count;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8 chance = (uint8)zone->random.Int(0, 115); // variation just over worst possible scrambling
|
||||
if (isalpha(message[i]) && (chance <= variance)) {
|
||||
uint8 rand_char = (uint8)zone->random.Int(0,51); // choose a random character from the alpha list
|
||||
@ -8163,7 +8140,7 @@ void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_
|
||||
entity_list.MessageClose_StringID(this, true, 50, 0, EATING_MESSAGE, GetName(), item->Name);
|
||||
|
||||
#if EQDEBUG >= 5
|
||||
LogFile->write(EQEMuLog::Debug, "Eating from slot:%i", (int)slot);
|
||||
LogFile->write(EQEmuLog::Debug, "Eating from slot:%i", (int)slot);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -8180,7 +8157,7 @@ void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_
|
||||
entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name);
|
||||
|
||||
#if EQDEBUG >= 5
|
||||
LogFile->write(EQEMuLog::Debug, "Drinking from slot:%i", (int)slot);
|
||||
LogFile->write(EQEmuLog::Debug, "Drinking from slot:%i", (int)slot);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -8280,3 +8257,216 @@ void Client::SendColoredText(uint32 color, std::string message)
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// class Client::TextLink
|
||||
//
|
||||
std::string Client::TextLink::GenerateLink()
|
||||
{
|
||||
m_Link.clear();
|
||||
m_LinkBody.clear();
|
||||
m_LinkText.clear();
|
||||
|
||||
generate_body();
|
||||
generate_text();
|
||||
|
||||
if ((m_LinkBody.length() == EmuConstants::TEXT_LINK_BODY_LENGTH) && (m_LinkText.length() > 0)) {
|
||||
m_Link.push_back(0x12);
|
||||
m_Link.append(m_LinkBody);
|
||||
m_Link.append(m_LinkText);
|
||||
m_Link.push_back(0x12);
|
||||
}
|
||||
|
||||
if ((m_Link.length() == 0) || (m_Link.length() > 250)) {
|
||||
m_Error = true;
|
||||
m_Link = "<LINKER ERROR>";
|
||||
_log(CHANNELS__ERROR, "TextLink::GenerateLink() failed to generate a useable text link (LinkType: %i, Lengths: {link: %u, body: %u, text: %u})",
|
||||
m_LinkType, m_Link.length(), m_LinkBody.length(), m_LinkText.length());
|
||||
#if EQDEBUG >= 5
|
||||
_log(CHANNELS__ERROR, ">> LinkBody: %s", m_LinkBody.c_str());
|
||||
_log(CHANNELS__ERROR, ">> LinkText: %s", m_LinkText.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
return m_Link;
|
||||
}
|
||||
|
||||
void Client::TextLink::Reset()
|
||||
{
|
||||
m_LinkType = linkBlank;
|
||||
m_ItemData = nullptr;
|
||||
m_LootData = nullptr;
|
||||
m_ItemInst = nullptr;
|
||||
m_ProxyItemID = NOT_USED;
|
||||
m_ProxyText = nullptr;
|
||||
m_TaskUse = false;
|
||||
m_Link.clear();
|
||||
m_LinkBody.clear();
|
||||
m_LinkText.clear();
|
||||
m_Error = false;
|
||||
}
|
||||
|
||||
void Client::TextLink::generate_body()
|
||||
{
|
||||
/*
|
||||
Current server mask: EQClientRoF2
|
||||
|
||||
RoF2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X" (56)
|
||||
RoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (55)
|
||||
SoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (50)
|
||||
6.2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X" (45)
|
||||
*/
|
||||
|
||||
memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct));
|
||||
|
||||
const Item_Struct* item_data = nullptr;
|
||||
|
||||
switch (m_LinkType) {
|
||||
case linkBlank:
|
||||
break;
|
||||
case linkItemData:
|
||||
if (m_ItemData == nullptr) { break; }
|
||||
m_LinkBodyStruct.item_id = m_ItemData->ID;
|
||||
m_LinkBodyStruct.evolve_group = m_ItemData->LoreGroup; // this probably won't work for all items
|
||||
//m_LinkBodyStruct.evolve_level = m_ItemData->EvolvingLevel;
|
||||
// TODO: add hash call
|
||||
break;
|
||||
case linkLootItem:
|
||||
if (m_LootData == nullptr) { break; }
|
||||
item_data = database.GetItem(m_LootData->item_id);
|
||||
if (item_data == nullptr) { break; }
|
||||
m_LinkBodyStruct.item_id = item_data->ID;
|
||||
m_LinkBodyStruct.augment_1 = m_LootData->aug_1;
|
||||
m_LinkBodyStruct.augment_2 = m_LootData->aug_2;
|
||||
m_LinkBodyStruct.augment_3 = m_LootData->aug_3;
|
||||
m_LinkBodyStruct.augment_4 = m_LootData->aug_4;
|
||||
m_LinkBodyStruct.augment_5 = m_LootData->aug_5;
|
||||
m_LinkBodyStruct.augment_6 = m_LootData->aug_6;
|
||||
m_LinkBodyStruct.evolve_group = item_data->LoreGroup; // see note above
|
||||
//m_LinkBodyStruct.evolve_level = item_data->EvolvingLevel;
|
||||
// TODO: add hash call
|
||||
break;
|
||||
case linkItemInst:
|
||||
if (m_ItemInst == nullptr) { break; }
|
||||
if (m_ItemInst->GetItem() == nullptr) { break; }
|
||||
m_LinkBodyStruct.item_id = m_ItemInst->GetItem()->ID;
|
||||
m_LinkBodyStruct.augment_1 = m_ItemInst->GetAugmentItemID(0);
|
||||
m_LinkBodyStruct.augment_2 = m_ItemInst->GetAugmentItemID(1);
|
||||
m_LinkBodyStruct.augment_3 = m_ItemInst->GetAugmentItemID(2);
|
||||
m_LinkBodyStruct.augment_4 = m_ItemInst->GetAugmentItemID(3);
|
||||
m_LinkBodyStruct.augment_5 = m_ItemInst->GetAugmentItemID(4);
|
||||
m_LinkBodyStruct.augment_6 = m_ItemInst->GetAugmentItemID(5);
|
||||
m_LinkBodyStruct.is_evolving = (m_ItemInst->IsEvolving() ? 1 : 0);
|
||||
m_LinkBodyStruct.evolve_group = m_ItemInst->GetItem()->LoreGroup; // see note above
|
||||
m_LinkBodyStruct.evolve_level = m_ItemInst->GetEvolveLvl();
|
||||
m_LinkBodyStruct.ornament_icon = m_ItemInst->GetOrnamentationIcon();
|
||||
// TODO: add hash call
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_ProxyItemID != NOT_USED) {
|
||||
m_LinkBodyStruct.item_id = m_ProxyItemID;
|
||||
}
|
||||
|
||||
if (m_TaskUse) {
|
||||
m_LinkBodyStruct.hash = 0x14505DC2;
|
||||
}
|
||||
|
||||
m_LinkBody = StringFormat(
|
||||
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
|
||||
(0x0F & m_LinkBodyStruct.unknown_1),
|
||||
(0x000FFFFF & m_LinkBodyStruct.item_id),
|
||||
(0x000FFFFF & m_LinkBodyStruct.augment_1),
|
||||
(0x000FFFFF & m_LinkBodyStruct.augment_2),
|
||||
(0x000FFFFF & m_LinkBodyStruct.augment_3),
|
||||
(0x000FFFFF & m_LinkBodyStruct.augment_4),
|
||||
(0x000FFFFF & m_LinkBodyStruct.augment_5),
|
||||
(0x000FFFFF & m_LinkBodyStruct.augment_6),
|
||||
(0x0F & m_LinkBodyStruct.is_evolving),
|
||||
(0x0000FFFF & m_LinkBodyStruct.evolve_group),
|
||||
(0xFF & m_LinkBodyStruct.evolve_level),
|
||||
(0x000FFFFF & m_LinkBodyStruct.ornament_icon),
|
||||
(0xFFFFFFFF & m_LinkBodyStruct.hash)
|
||||
);
|
||||
}
|
||||
|
||||
void Client::TextLink::generate_text()
|
||||
{
|
||||
if (m_ProxyText != nullptr) {
|
||||
m_LinkText = m_ProxyText;
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item_data = nullptr;
|
||||
|
||||
switch (m_LinkType) {
|
||||
case linkBlank:
|
||||
break;
|
||||
case linkItemData:
|
||||
if (m_ItemData == nullptr) { break; }
|
||||
m_LinkText = m_ItemData->Name;
|
||||
return;
|
||||
case linkLootItem:
|
||||
if (m_LootData == nullptr) { break; }
|
||||
item_data = database.GetItem(m_LootData->item_id);
|
||||
if (item_data == nullptr) { break; }
|
||||
m_LinkText = item_data->Name;
|
||||
return;
|
||||
case linkItemInst:
|
||||
if (m_ItemInst == nullptr) { break; }
|
||||
if (m_ItemInst->GetItem() == nullptr) { break; }
|
||||
m_LinkText = m_ItemInst->GetItem()->Name;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_LinkText = "null";
|
||||
}
|
||||
|
||||
bool Client::TextLink::DegenerateLinkBody(TextLinkBody_Struct& textLinkBodyStruct, const std::string& textLinkBody)
|
||||
{
|
||||
memset(&textLinkBodyStruct, 0, sizeof(TextLinkBody_Struct));
|
||||
if (textLinkBody.length() != EmuConstants::TEXT_LINK_BODY_LENGTH) { return false; }
|
||||
|
||||
textLinkBodyStruct.unknown_1 = (uint8)strtol(textLinkBody.substr(0, 1).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.item_id = (uint32)strtol(textLinkBody.substr(1, 5).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.augment_1 = (uint32)strtol(textLinkBody.substr(6, 5).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.augment_2 = (uint32)strtol(textLinkBody.substr(11, 5).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.augment_3 = (uint32)strtol(textLinkBody.substr(16, 5).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.augment_4 = (uint32)strtol(textLinkBody.substr(21, 5).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.augment_5 = (uint32)strtol(textLinkBody.substr(26, 5).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.augment_6 = (uint32)strtol(textLinkBody.substr(31, 5).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.is_evolving = (uint8)strtol(textLinkBody.substr(36, 1).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.evolve_group = (uint32)strtol(textLinkBody.substr(37, 4).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.evolve_level = (uint8)strtol(textLinkBody.substr(41, 2).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.ornament_icon = (uint32)strtol(textLinkBody.substr(43, 5).c_str(), nullptr, 16);
|
||||
textLinkBodyStruct.hash = (int)strtol(textLinkBody.substr(48, 8).c_str(), nullptr, 16);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Client::TextLink::GenerateLinkBody(std::string& textLinkBody, const TextLinkBody_Struct& textLinkBodyStruct)
|
||||
{
|
||||
textLinkBody = StringFormat(
|
||||
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
|
||||
(0x0F & textLinkBodyStruct.unknown_1),
|
||||
(0x000FFFFF & textLinkBodyStruct.item_id),
|
||||
(0x000FFFFF & textLinkBodyStruct.augment_1),
|
||||
(0x000FFFFF & textLinkBodyStruct.augment_2),
|
||||
(0x000FFFFF & textLinkBodyStruct.augment_3),
|
||||
(0x000FFFFF & textLinkBodyStruct.augment_4),
|
||||
(0x000FFFFF & textLinkBodyStruct.augment_5),
|
||||
(0x000FFFFF & textLinkBodyStruct.augment_6),
|
||||
(0x0F & textLinkBodyStruct.is_evolving),
|
||||
(0x0000FFFF & textLinkBodyStruct.evolve_group),
|
||||
(0xFF & textLinkBodyStruct.evolve_level),
|
||||
(0x000FFFFF & textLinkBodyStruct.ornament_icon),
|
||||
(0xFFFFFFFF & textLinkBodyStruct.hash)
|
||||
);
|
||||
|
||||
if (textLinkBody.length() != EmuConstants::TEXT_LINK_BODY_LENGTH) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -428,6 +428,7 @@ public:
|
||||
inline virtual int32 GetPR() const { return PR; }
|
||||
inline virtual int32 GetCR() const { return CR; }
|
||||
inline virtual int32 GetCorrup() const { return Corrup; }
|
||||
inline virtual int32 GetPhR() const { return PhR; }
|
||||
|
||||
int32 GetMaxStat() const;
|
||||
int32 GetMaxResist() const;
|
||||
@ -452,6 +453,7 @@ public:
|
||||
inline uint8 GetBaseAGI() const { return m_pp.AGI; }
|
||||
inline uint8 GetBaseWIS() const { return m_pp.WIS; }
|
||||
inline uint8 GetBaseCorrup() const { return 15; } // Same for all
|
||||
inline uint8 GetBasePhR() const { return 0; } // Guessing at 0 as base
|
||||
|
||||
inline virtual int32 GetHeroicSTR() const { return itembonuses.HeroicSTR; }
|
||||
inline virtual int32 GetHeroicSTA() const { return itembonuses.HeroicSTA; }
|
||||
@ -466,6 +468,7 @@ public:
|
||||
inline virtual int32 GetHeroicPR() const { return itembonuses.HeroicPR; }
|
||||
inline virtual int32 GetHeroicCR() const { return itembonuses.HeroicCR; }
|
||||
inline virtual int32 GetHeroicCorrup() const { return itembonuses.HeroicCorrup; }
|
||||
inline virtual int32 GetHeroicPhR() const { return 0; } // Heroic PhR not implemented yet
|
||||
// Mod2
|
||||
inline virtual int32 GetShielding() const { return itembonuses.MeleeMitigation; }
|
||||
inline virtual int32 GetSpellShield() const { return itembonuses.SpellShield; }
|
||||
@ -804,6 +807,7 @@ public:
|
||||
int32 GetAugmentIDAt(int16 slot_id, uint8 augslot);
|
||||
bool PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update = false);
|
||||
bool PushItemOnCursor(const ItemInst& inst, bool client_update = false);
|
||||
void SendCursorBuffer();
|
||||
void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true);
|
||||
bool SwapItem(MoveItem_Struct* move_in);
|
||||
void SwapItemResync(MoveItem_Struct* move_slots);
|
||||
@ -814,8 +818,56 @@ public:
|
||||
void SetStats(uint8 type,int16 set_val);
|
||||
void IncStats(uint8 type,int16 increase_val);
|
||||
void DropItem(int16 slot_id);
|
||||
bool MakeItemLink(char* &ret_link, const ItemInst* inst);
|
||||
int GetItemLinkHash(const ItemInst* inst);
|
||||
|
||||
//
|
||||
// class Client::TextLink
|
||||
//
|
||||
class TextLink {
|
||||
public:
|
||||
enum LinkType { linkBlank = 0, linkItemData, linkLootItem, linkItemInst };
|
||||
|
||||
TextLink() { Reset(); }
|
||||
|
||||
void SetLinkType(LinkType linkType) { m_LinkType = linkType; }
|
||||
void SetItemData(const Item_Struct* itemData) { m_ItemData = itemData; }
|
||||
void SetLootData(const ServerLootItem_Struct* lootData) { m_LootData = lootData; }
|
||||
void SetItemInst(const ItemInst* itemInst) { m_ItemInst = itemInst; }
|
||||
void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to
|
||||
void SetProxyText(const char* proxyText) { m_ProxyText = proxyText; } // overrides standard text use
|
||||
void SetTaskUse() { m_TaskUse = true; }
|
||||
|
||||
std::string GenerateLink();
|
||||
bool LinkError() { return m_Error; }
|
||||
|
||||
std::string GetLink() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
|
||||
std::string GetLinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
|
||||
std::string GetLinkText() { return m_LinkText; } // contains string format: '<LinkText>'
|
||||
|
||||
void Reset();
|
||||
|
||||
static bool DegenerateLinkBody(TextLinkBody_Struct& textLinkBodyStruct, const std::string& textLinkBody);
|
||||
static bool GenerateLinkBody(std::string& textLinkBody, const TextLinkBody_Struct& textLinkBodyStruct);
|
||||
|
||||
private:
|
||||
void generate_body();
|
||||
void generate_text();
|
||||
|
||||
int m_LinkType;
|
||||
const Item_Struct* m_ItemData;
|
||||
const ServerLootItem_Struct* m_LootData;
|
||||
const ItemInst* m_ItemInst;
|
||||
uint32 m_ProxyItemID;
|
||||
const char* m_ProxyText;
|
||||
bool m_TaskUse;
|
||||
TextLinkBody_Struct m_LinkBodyStruct;
|
||||
std::string m_Link;
|
||||
std::string m_LinkBody;
|
||||
std::string m_LinkText;
|
||||
bool m_Error;
|
||||
};
|
||||
|
||||
int GetItemLinkHash(const ItemInst* inst); // move to Item_Struct..or make use of the pre-calculated database field
|
||||
|
||||
void SendItemLink(const ItemInst* inst, bool sendtoall=false);
|
||||
void SendLootItemInPacket(const ItemInst* inst, int16 slot_id);
|
||||
void SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type);
|
||||
@ -832,11 +884,11 @@ public:
|
||||
|
||||
bool Hungry() const {if (GetGM()) return false; return m_pp.hunger_level <= 3000;}
|
||||
bool Thirsty() const {if (GetGM()) return false; return m_pp.thirst_level <= 3000;}
|
||||
int32 GetHunger() const { return m_pp.hunger_level; }
|
||||
int32 GetThirst() const { return m_pp.thirst_level; }
|
||||
void SetHunger(int32 in_hunger);
|
||||
void SetThirst(int32 in_thirst);
|
||||
void SetConsumption(int32 in_hunger, int32 in_thirst);
|
||||
int32 GetHunger() const { return m_pp.hunger_level; }
|
||||
int32 GetThirst() const { return m_pp.thirst_level; }
|
||||
void SetHunger(int32 in_hunger);
|
||||
void SetThirst(int32 in_thirst);
|
||||
void SetConsumption(int32 in_hunger, int32 in_thirst);
|
||||
|
||||
bool CheckTradeLoreConflict(Client* other);
|
||||
void LinkDead();
|
||||
@ -937,7 +989,7 @@ void SetConsumption(int32 in_hunger, int32 in_thirst);
|
||||
inline bool IsTaskActive(int TaskID) { return (taskstate ? taskstate->IsTaskActive(TaskID) : false); }
|
||||
inline bool IsTaskActivityActive(int TaskID, int ActivityID) { return (taskstate ? taskstate->IsTaskActivityActive(TaskID, ActivityID) : false); }
|
||||
inline ActivityState GetTaskActivityState(int index, int ActivityID) { return (taskstate ? taskstate->GetTaskActivityState(index, ActivityID) : ActivityHidden); }
|
||||
inline void UpdateTaskActivity(int TaskID, int ActivityID, int Count) { if(taskstate) taskstate->UpdateTaskActivity(this, TaskID, ActivityID, Count); }
|
||||
inline void UpdateTaskActivity(int TaskID, int ActivityID, int Count, bool ignore_quest_update = false) { if (taskstate) taskstate->UpdateTaskActivity(this, TaskID, ActivityID, Count, ignore_quest_update); }
|
||||
inline void ResetTaskActivity(int TaskID, int ActivityID) { if(taskstate) taskstate->ResetTaskActivity(this, TaskID, ActivityID); }
|
||||
inline void UpdateTasksOnKill(int NPCTypeID) { if(taskstate) taskstate->UpdateTasksOnKill(this, NPCTypeID); }
|
||||
inline void UpdateTasksForItem(ActivityType Type, int ItemID, int Count=1) { if(taskstate) taskstate->UpdateTasksForItem(this, Type, ItemID, Count); }
|
||||
|
||||
@ -27,8 +27,8 @@ ClientLogs client_logs;
|
||||
|
||||
char ClientLogs::_buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH+1];
|
||||
|
||||
void ClientLogs::subscribe(EQEMuLog::LogIDs id, Client *c) {
|
||||
if(id >= EQEMuLog::MaxLogID)
|
||||
void ClientLogs::subscribe(EQEmuLog::LogIDs id, Client *c) {
|
||||
if(id >= EQEmuLog::MaxLogID)
|
||||
return;
|
||||
if(c == nullptr)
|
||||
return;
|
||||
@ -47,8 +47,8 @@ void ClientLogs::subscribe(EQEMuLog::LogIDs id, Client *c) {
|
||||
entries[id].push_back(c);
|
||||
}
|
||||
|
||||
void ClientLogs::unsubscribe(EQEMuLog::LogIDs id, Client *c) {
|
||||
if(id >= EQEMuLog::MaxLogID)
|
||||
void ClientLogs::unsubscribe(EQEmuLog::LogIDs id, Client *c) {
|
||||
if(id >= EQEmuLog::MaxLogID)
|
||||
return;
|
||||
if(c == nullptr)
|
||||
return;
|
||||
@ -68,8 +68,8 @@ void ClientLogs::subscribeAll(Client *c) {
|
||||
if(c == nullptr)
|
||||
return;
|
||||
int r;
|
||||
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
|
||||
subscribe((EQEMuLog::LogIDs)r, c);
|
||||
for(r = EQEmuLog::Status; r < EQEmuLog::MaxLogID; r++) {
|
||||
subscribe((EQEmuLog::LogIDs)r, c);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,20 +77,20 @@ void ClientLogs::unsubscribeAll(Client *c) {
|
||||
if(c == nullptr)
|
||||
return;
|
||||
int r;
|
||||
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
|
||||
unsubscribe((EQEMuLog::LogIDs)r, c);
|
||||
for(r = EQEmuLog::Status; r < EQEmuLog::MaxLogID; r++) {
|
||||
unsubscribe((EQEmuLog::LogIDs)r, c);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLogs::clear() {
|
||||
int r;
|
||||
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
|
||||
for(r = EQEmuLog::Status; r < EQEmuLog::MaxLogID; r++) {
|
||||
entries[r].clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLogs::msg(EQEMuLog::LogIDs id, const char *buf) {
|
||||
if(id >= EQEMuLog::MaxLogID)
|
||||
void ClientLogs::msg(EQEmuLog::LogIDs id, const char *buf) {
|
||||
if(id >= EQEmuLog::MaxLogID)
|
||||
return;
|
||||
std::vector<Client *>::iterator cur,end;
|
||||
cur = entries[id].begin();
|
||||
@ -103,7 +103,7 @@ void ClientLogs::msg(EQEMuLog::LogIDs id, const char *buf) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLogs::EQEmuIO_buf(EQEMuLog::LogIDs id, const char *buf, uint8 size, uint32 count) {
|
||||
void ClientLogs::EQEmuIO_buf(EQEmuLog::LogIDs id, const char *buf, uint8 size, uint32 count) {
|
||||
if(size != 1)
|
||||
return; //cannot print multibyte data
|
||||
if(buf[0] == '\n' || buf[0] == '\r')
|
||||
@ -115,7 +115,7 @@ void ClientLogs::EQEmuIO_buf(EQEMuLog::LogIDs id, const char *buf, uint8 size, u
|
||||
client_logs.msg(id, _buffer);
|
||||
}
|
||||
|
||||
void ClientLogs::EQEmuIO_fmt(EQEMuLog::LogIDs id, const char *fmt, va_list ap) {
|
||||
void ClientLogs::EQEmuIO_fmt(EQEmuLog::LogIDs id, const char *fmt, va_list ap) {
|
||||
if(fmt[0] == '\n' || fmt[0] == '\r')
|
||||
return; //skip new lines...
|
||||
vsnprintf(_buffer, MAX_CLIENT_LOG_MESSAGE_LENGTH, fmt, ap);
|
||||
@ -123,7 +123,7 @@ void ClientLogs::EQEmuIO_fmt(EQEMuLog::LogIDs id, const char *fmt, va_list ap) {
|
||||
client_logs.msg(id, _buffer);
|
||||
}
|
||||
|
||||
void ClientLogs::EQEmuIO_pva(EQEMuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap) {
|
||||
void ClientLogs::EQEmuIO_pva(EQEmuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap) {
|
||||
if(fmt[0] == '\n' || fmt[0] == '\r')
|
||||
return; //skip new lines...
|
||||
char *buf = _buffer;
|
||||
|
||||
@ -35,21 +35,21 @@ class Client;
|
||||
|
||||
class ClientLogs {
|
||||
public:
|
||||
static void EQEmuIO_buf(EQEMuLog::LogIDs id, const char *buf, uint8 size, uint32 count);
|
||||
static void EQEmuIO_fmt(EQEMuLog::LogIDs id, const char *fmt, va_list ap);
|
||||
static void EQEmuIO_pva(EQEMuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap);
|
||||
static void EQEmuIO_buf(EQEmuLog::LogIDs id, const char *buf, uint8 size, uint32 count);
|
||||
static void EQEmuIO_fmt(EQEmuLog::LogIDs id, const char *fmt, va_list ap);
|
||||
static void EQEmuIO_pva(EQEmuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap);
|
||||
|
||||
void subscribe(EQEMuLog::LogIDs id, Client *c);
|
||||
void unsubscribe(EQEMuLog::LogIDs id, Client *c);
|
||||
void subscribe(EQEmuLog::LogIDs id, Client *c);
|
||||
void unsubscribe(EQEmuLog::LogIDs id, Client *c);
|
||||
void subscribeAll(Client *c);
|
||||
void unsubscribeAll(Client *c);
|
||||
void clear(); //unsubscribes everybody
|
||||
|
||||
void msg(EQEMuLog::LogIDs id, const char *buf);
|
||||
void msg(EQEmuLog::LogIDs id, const char *buf);
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<Client *> entries[EQEMuLog::MaxLogID];
|
||||
std::vector<Client *> entries[EQEmuLog::MaxLogID];
|
||||
|
||||
static char _buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH+1];
|
||||
};
|
||||
|
||||
@ -825,7 +825,7 @@ int32 Client::acmod() {
|
||||
return (65 + ((agility-300) / 21));
|
||||
}
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Error, "Error in Client::acmod(): Agility: %i, Level: %i",agility,level);
|
||||
LogFile->write(EQEmuLog::Error, "Error in Client::acmod(): Agility: %i, Level: %i",agility,level);
|
||||
#endif
|
||||
return 0;
|
||||
};
|
||||
@ -934,7 +934,7 @@ int32 Client::CalcMaxMana()
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogFile->write(EQEMuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
|
||||
LogFile->write(EQEmuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
@ -955,7 +955,7 @@ int32 Client::CalcMaxMana()
|
||||
}
|
||||
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Debug, "Client::CalcMaxMana() called for %s - returning %d", GetName(), max_mana);
|
||||
LogFile->write(EQEmuLog::Debug, "Client::CalcMaxMana() called for %s - returning %d", GetName(), max_mana);
|
||||
#endif
|
||||
return max_mana;
|
||||
}
|
||||
@ -1045,14 +1045,14 @@ int32 Client::CalcBaseMana()
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogFile->write(EQEMuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
|
||||
LogFile->write(EQEmuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
|
||||
max_m = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if EQDEBUG >= 11
|
||||
LogFile->write(EQEMuLog::Debug, "Client::CalcBaseMana() called for %s - returning %d", GetName(), max_m);
|
||||
LogFile->write(EQEmuLog::Debug, "Client::CalcBaseMana() called for %s - returning %d", GetName(), max_m);
|
||||
#endif
|
||||
return max_m;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1023,7 +1023,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
// Account for merchant lists with gaps.
|
||||
if (ml.slot >= i) {
|
||||
if (ml.slot > i)
|
||||
LogFile->write(EQEMuLog::Debug, "(WARNING) Merchantlist contains gap at slot %d. Merchant: %d, NPC: %d", i, merchant_id, npcid);
|
||||
LogFile->write(EQEmuLog::Debug, "(WARNING) Merchantlist contains gap at slot %d. Merchant: %d, NPC: %d", i, merchant_id, npcid);
|
||||
i = ml.slot + 1;
|
||||
}
|
||||
}
|
||||
@ -1187,7 +1187,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
|
||||
{
|
||||
if(app->size != sizeof(MemorizeSpell_Struct))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error,"Wrong size on OP_MemorizeSpell. Got: %i, Expected: %i", app->size, sizeof(MemorizeSpell_Struct));
|
||||
LogFile->write(EQEmuLog::Error,"Wrong size on OP_MemorizeSpell. Got: %i, Expected: %i", app->size, sizeof(MemorizeSpell_Struct));
|
||||
DumpPacket(app);
|
||||
return;
|
||||
}
|
||||
|
||||
1067
zone/command.cpp
1067
zone/command.cpp
File diff suppressed because it is too large
Load Diff
@ -135,7 +135,8 @@ enum {
|
||||
NPC_CHASE_DISTANCE = 40,
|
||||
ALLOW_TO_TANK = 41,
|
||||
IGNORE_ROOT_AGGRO_RULES = 42,
|
||||
MAX_SPECIAL_ATTACK = 43
|
||||
CASTING_RESIST_DIFF = 43,
|
||||
MAX_SPECIAL_ATTACK = 44
|
||||
};
|
||||
|
||||
typedef enum { //fear states
|
||||
|
||||
@ -781,7 +781,7 @@ bool Corpse::Process() {
|
||||
spc->zone_id = zone->graveyard_zoneid();
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
LogFile->write(EQEMuLog::Debug, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid()));
|
||||
LogFile->write(EQEmuLog::Debug, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid()));
|
||||
corpse_db_id = 0;
|
||||
}
|
||||
|
||||
@ -811,10 +811,10 @@ bool Corpse::Process() {
|
||||
Save();
|
||||
player_corpse_depop = true;
|
||||
corpse_db_id = 0;
|
||||
LogFile->write(EQEMuLog::Debug, "Tagged %s player corpse has burried.", this->GetName());
|
||||
LogFile->write(EQEmuLog::Debug, "Tagged %s player corpse has burried.", this->GetName());
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Unable to bury %s player corpse.", this->GetName());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to bury %s player corpse.", this->GetName());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1017,7 +1017,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* item_data = *cur;
|
||||
item = database.GetItem(item_data->item_id);
|
||||
LogFile->write(EQEMuLog::Debug, "Corpse Looting: %s was not sent to client loot window (corpse_dbid: %i, charname: %s(%s))", item->Name, GetCorpseDBID(), client->GetName(), client->GetGM() ? "GM" : "Owner");
|
||||
LogFile->write(EQEmuLog::Debug, "Corpse Looting: %s was not sent to client loot window (corpse_dbid: %i, charname: %s(%s))", item->Name, GetCorpseDBID(), client->GetName(), client->GetGM() ? "GM" : "Owner");
|
||||
client->Message(0, "Inaccessable Corpse Item: %s", item->Name);
|
||||
}
|
||||
}
|
||||
@ -1142,7 +1142,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
|
||||
parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0);
|
||||
|
||||
if ((RuleB(Character, EnableDiscoveredItems))) {
|
||||
if (!IsPlayerCorpse() && RuleB(Character, EnableDiscoveredItems)) {
|
||||
if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID))
|
||||
client->DiscoverItem(inst->GetItem()->ID);
|
||||
}
|
||||
@ -1189,33 +1189,31 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
}
|
||||
}
|
||||
|
||||
if (GetPlayerKillItem() != -1){
|
||||
if (GetPlayerKillItem() != -1) {
|
||||
SetPlayerKillItemID(0);
|
||||
}
|
||||
|
||||
/* Send message with item link to groups and such */
|
||||
char *link = 0, *link2 = 0; //just like a db query :-)
|
||||
client->MakeItemLink(link2, inst);
|
||||
MakeAnyLenString(&link, "%c" "%s" "%s" "%c",
|
||||
0x12,
|
||||
link2,
|
||||
item->Name,
|
||||
0x12);
|
||||
safe_delete_array(link2);
|
||||
/* Send message with item link to groups and such */
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemInst);
|
||||
linker.SetItemInst(inst);
|
||||
|
||||
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, link);
|
||||
if(!IsPlayerCorpse()) {
|
||||
auto item_link = linker.GenerateLink();
|
||||
|
||||
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());
|
||||
|
||||
if (!IsPlayerCorpse()) {
|
||||
Group *g = client->GetGroup();
|
||||
if(g != nullptr) {
|
||||
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), link);
|
||||
} else {
|
||||
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
|
||||
}
|
||||
else {
|
||||
Raid *r = client->GetRaid();
|
||||
if(r != nullptr) {
|
||||
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), link);
|
||||
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
safe_delete_array(link);
|
||||
}
|
||||
else {
|
||||
SendEndLootErrorPacket(client);
|
||||
|
||||
@ -290,7 +290,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
sender->CheckIncreaseSkill(SkillPickLock, nullptr, 1);
|
||||
|
||||
#if EQDEBUG>=5
|
||||
LogFile->write(EQEMuLog::Debug, "Client has lockpicks: skill=%f", modskill);
|
||||
LogFile->write(EQEmuLog::Debug, "Client has lockpicks: skill=%f", modskill);
|
||||
#endif
|
||||
|
||||
if(GetLockpick() <= modskill)
|
||||
@ -547,13 +547,13 @@ void Doors::ToggleState(Mob *sender)
|
||||
}
|
||||
|
||||
void Doors::DumpDoor(){
|
||||
LogFile->write(EQEMuLog::Debug,
|
||||
LogFile->write(EQEmuLog::Debug,
|
||||
"db_id:%i door_id:%i zone_name:%s door_name:%s %s",
|
||||
db_id, door_id, zone_name, door_name, to_string(m_Position).c_str());
|
||||
LogFile->write(EQEMuLog::Debug,
|
||||
LogFile->write(EQEmuLog::Debug,
|
||||
"opentype:%i guild_id:%i lockpick:%i keyitem:%i nokeyring:%i trigger_door:%i trigger_type:%i door_param:%i open:%s",
|
||||
opentype, guild_id, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param, (isopen) ? "open":"closed");
|
||||
LogFile->write(EQEMuLog::Debug,
|
||||
LogFile->write(EQEmuLog::Debug,
|
||||
"dest_zone:%s destination:%s ",
|
||||
dest_zone, to_string(m_Destination).c_str());
|
||||
}
|
||||
@ -632,7 +632,7 @@ int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version)
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) {
|
||||
LogFile->write(EQEMuLog::Status, "Loading Doors from database...");
|
||||
LogFile->write(EQEmuLog::Status, "Loading Doors from database...");
|
||||
|
||||
|
||||
// Door tmpDoor;
|
||||
|
||||
@ -460,7 +460,7 @@ bool Client::TrainDiscipline(uint32 itemid) {
|
||||
const Item_Struct *item = database.GetItem(itemid);
|
||||
if(item == nullptr) {
|
||||
Message(13, "Unable to find the tome you turned in!");
|
||||
LogFile->write(EQEMuLog::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
|
||||
LogFile->write(EQEmuLog::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
@ -140,7 +140,7 @@ void PerlembParser::ReloadQuests() {
|
||||
perl = nullptr;
|
||||
}
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "Error re-initializing perlembed: %s", e.what());
|
||||
LogFile->write(EQEmuLog::Status, "Error re-initializing perlembed: %s", e.what());
|
||||
throw e.what();
|
||||
}
|
||||
|
||||
@ -232,6 +232,7 @@ int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::stri
|
||||
|
||||
int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
// needs pointer validation on 'item' argument
|
||||
return EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers);
|
||||
}
|
||||
|
||||
@ -335,6 +336,9 @@ bool PerlembParser::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
|
||||
if(!perl)
|
||||
return false;
|
||||
|
||||
if (itm == nullptr)
|
||||
return false;
|
||||
|
||||
if(evt >= _LargestEventID)
|
||||
return false;
|
||||
|
||||
@ -449,6 +453,9 @@ void PerlembParser::LoadGlobalPlayerScript(std::string filename) {
|
||||
}
|
||||
|
||||
void PerlembParser::LoadItemScript(std::string filename, ItemInst *item) {
|
||||
if (item == nullptr)
|
||||
return;
|
||||
|
||||
std::stringstream package_name;
|
||||
package_name << "qst_item_" << item->GetID();
|
||||
|
||||
@ -855,6 +862,7 @@ void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlaye
|
||||
}
|
||||
}
|
||||
else if(isItemQuest) {
|
||||
// need a valid ItemInst pointer check here..unsure how to cancel this process -U
|
||||
const Item_Struct* item = iteminst->GetItem();
|
||||
package_name = "qst_item_";
|
||||
package_name += itoa(item->ID);
|
||||
@ -1292,6 +1300,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
|
||||
case EVENT_SCALE_CALC:
|
||||
case EVENT_ITEM_ENTER_ZONE: {
|
||||
// need a valid ItemInst pointer check here..unsure how to cancel this process -U
|
||||
ExportVar(package_name.c_str(), "itemid", objid);
|
||||
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
|
||||
break;
|
||||
@ -1299,6 +1308,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
|
||||
case EVENT_ITEM_CLICK_CAST:
|
||||
case EVENT_ITEM_CLICK: {
|
||||
// need a valid ItemInst pointer check here..unsure how to cancel this process -U
|
||||
ExportVar(package_name.c_str(), "itemid", objid);
|
||||
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
|
||||
ExportVar(package_name.c_str(), "slotid", extradata);
|
||||
|
||||
@ -270,7 +270,6 @@ XS(XS__unique_spawn)
|
||||
if(items == 7)
|
||||
heading = (float)SvNV(ST(6));
|
||||
|
||||
|
||||
Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, xyz_heading(x, y, z, heading));
|
||||
RETVAL = (r != nullptr) ? r->GetID() : 0;
|
||||
|
||||
@ -2267,18 +2266,22 @@ XS(XS__updatetaskactivity)
|
||||
dXSARGS;
|
||||
unsigned int task, activity;
|
||||
int count = 1;
|
||||
bool ignore_quest_update = false;
|
||||
if(items == 2) {
|
||||
task = (int)SvIV(ST(0));
|
||||
activity = (int)SvIV(ST(1));
|
||||
quest_manager.updatetaskactivity(task, activity, count);
|
||||
quest_manager.updatetaskactivity(task, activity, count, false);
|
||||
}
|
||||
else if(items == 3) {
|
||||
else if (items == 3 || items == 4) {
|
||||
task = (int)SvIV(ST(0));
|
||||
activity = (int)SvIV(ST(1));
|
||||
count = (int)SvIV(ST(2));
|
||||
quest_manager.updatetaskactivity(task, activity, count);
|
||||
if (items == 4){
|
||||
bool ignore_quest_update = (bool)SvTRUE(ST(3));
|
||||
}
|
||||
quest_manager.updatetaskactivity(task, activity, count, ignore_quest_update);
|
||||
} else {
|
||||
Perl_croak(aTHX_ "Usage: updatetaskactivity(task, activity [,count])");
|
||||
Perl_croak(aTHX_ "Usage: updatetaskactivity(task, activity, [count], [ignore_quest_update])");
|
||||
}
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
@ -3503,221 +3506,222 @@ EXTERN_C XS(boot_quest)
|
||||
file[255] = '\0';
|
||||
|
||||
if(items != 1)
|
||||
LogFile->write(EQEMuLog::Error, "boot_quest does not take any arguments.");
|
||||
LogFile->write(EQEmuLog::Error, "boot_quest does not take any arguments.");
|
||||
|
||||
char buf[128]; //shouldent have any function names longer than this.
|
||||
|
||||
//add the strcpy stuff to get rid of const warnings....
|
||||
|
||||
XS_VERSION_BOOTCHECK ;
|
||||
newXS(strcpy(buf, "echo"), XS__echo, file);
|
||||
newXS(strcpy(buf, "say"), XS__say, file);
|
||||
newXS(strcpy(buf, "me"), XS__me, file);
|
||||
newXS(strcpy(buf, "summonitem"), XS__summonitem, file);
|
||||
newXS(strcpy(buf, "write"), XS__write, file);
|
||||
newXS(strcpy(buf, "spawn"), XS__spawn, file);
|
||||
newXS(strcpy(buf, "spawn2"), XS__spawn2, file);
|
||||
newXS(strcpy(buf, "unique_spawn"), XS__unique_spawn, file);
|
||||
newXS(strcpy(buf, "spawn_from_spawn2"), XS__spawn_from_spawn2, file);
|
||||
newXS(strcpy(buf, "enable_spawn2"), XS__enable_spawn2, file);
|
||||
newXS(strcpy(buf, "disable_spawn2"), XS__disable_spawn2, file);
|
||||
newXS(strcpy(buf, "setstat"), XS__setstat, file);
|
||||
newXS(strcpy(buf, "incstat"), XS__incstat, file);
|
||||
newXS(strcpy(buf, "castspell"), XS__castspell, file);
|
||||
newXS(strcpy(buf, "selfcast"), XS__selfcast, file);
|
||||
|
||||
#ifdef BOTS
|
||||
newXS(strcpy(buf, "botquest"), XS__botquest, file);
|
||||
newXS(strcpy(buf, "spawnbotcount"), XS__spawnbotcount, file);
|
||||
newXS(strcpy(buf, "createbotcount"), XS__createbotcount, file);
|
||||
newXS(strcpy(buf, "createBot"), XS__createBot, file);
|
||||
#endif //BOTS
|
||||
|
||||
newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file);
|
||||
newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file);
|
||||
newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file);
|
||||
newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file);
|
||||
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
|
||||
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
|
||||
newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file);
|
||||
newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file);
|
||||
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
|
||||
newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file);
|
||||
newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file);
|
||||
newXS(strcpy(buf, "GetSpellResistType"), XS__GetSpellResistType, file);
|
||||
newXS(strcpy(buf, "GetSpellTargetType"), XS__GetSpellTargetType, file);
|
||||
newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file);
|
||||
newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file);
|
||||
newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file);
|
||||
newXS(strcpy(buf, "IsBeneficialSpell"), XS__IsBeneficialSpell, file);
|
||||
newXS(strcpy(buf, "IsEffectInSpell"), XS__IsEffectInSpell, file);
|
||||
newXS(strcpy(buf, "IsRunning"), XS__IsRunning, file);
|
||||
newXS(strcpy(buf, "LearnRecipe"), XS__LearnRecipe, file);
|
||||
newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file);
|
||||
newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file);
|
||||
newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file);
|
||||
newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file);
|
||||
newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file);
|
||||
newXS(strcpy(buf, "SendMail"), XS__SendMail, file);
|
||||
newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file);
|
||||
newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file);
|
||||
newXS(strcpy(buf, "activespeaktask"), XS__activespeaktask, file);
|
||||
newXS(strcpy(buf, "activetasksinset"), XS__activetasksinset, file);
|
||||
newXS(strcpy(buf, "addldonloss"), XS__addldonpoints, file);
|
||||
newXS(strcpy(buf, "addldonpoints"), XS__addldonpoints, file);
|
||||
newXS(strcpy(buf, "addldonwin"), XS__addldonpoints, file);
|
||||
newXS(strcpy(buf, "addloot"), XS__addloot, file);
|
||||
newXS(strcpy(buf, "zone"), XS__zone, file);
|
||||
newXS(strcpy(buf, "settimer"), XS__settimer, file);
|
||||
newXS(strcpy(buf, "settimerMS"), XS__settimerMS, file);
|
||||
newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file);
|
||||
newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file);
|
||||
newXS(strcpy(buf, "emote"), XS__emote, file);
|
||||
newXS(strcpy(buf, "shout"), XS__shout, file);
|
||||
newXS(strcpy(buf, "shout2"), XS__shout2, file);
|
||||
newXS(strcpy(buf, "gmsay"), XS__gmsay, file);
|
||||
newXS(strcpy(buf, "depop"), XS__depop, file);
|
||||
newXS(strcpy(buf, "depop_withtimer"), XS__depop_withtimer, file);
|
||||
newXS(strcpy(buf, "settarget"), XS__settarget, file);
|
||||
newXS(strcpy(buf, "follow"), XS__follow, file);
|
||||
newXS(strcpy(buf, "sfollow"), XS__sfollow, file);
|
||||
newXS(strcpy(buf, "changedeity"), XS__changedeity, file);
|
||||
newXS(strcpy(buf, "exp"), XS__exp, file);
|
||||
newXS(strcpy(buf, "level"), XS__level, file);
|
||||
newXS(strcpy(buf, "traindisc"), XS__traindisc, file);
|
||||
newXS(strcpy(buf, "isdisctome"), XS__isdisctome, file);
|
||||
newXS(strcpy(buf, "safemove"), XS__safemove, file);
|
||||
newXS(strcpy(buf, "rain"), XS__rain, file);
|
||||
newXS(strcpy(buf, "snow"), XS__snow, file);
|
||||
newXS(strcpy(buf, "surname"), XS__surname, file);
|
||||
newXS(strcpy(buf, "permaclass"), XS__permaclass, file);
|
||||
newXS(strcpy(buf, "permarace"), XS__permarace, file);
|
||||
newXS(strcpy(buf, "permagender"), XS__permagender, file);
|
||||
newXS(strcpy(buf, "scribespells"), XS__scribespells, file);
|
||||
newXS(strcpy(buf, "traindiscs"), XS__traindiscs, file);
|
||||
newXS(strcpy(buf, "unscribespells"), XS__unscribespells, file);
|
||||
newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file);
|
||||
newXS(strcpy(buf, "givecash"), XS__givecash, file);
|
||||
newXS(strcpy(buf, "pvp"), XS__pvp, file);
|
||||
newXS(strcpy(buf, "movepc"), XS__movepc, file);
|
||||
newXS(strcpy(buf, "gmmove"), XS__gmmove, file);
|
||||
newXS(strcpy(buf, "movegrp"), XS__movegrp, file);
|
||||
newXS(strcpy(buf, "doanim"), XS__doanim, file);
|
||||
newXS(strcpy(buf, "addskill"), XS__addskill, file);
|
||||
newXS(strcpy(buf, "setlanguage"), XS__setlanguage, file);
|
||||
newXS(strcpy(buf, "setskill"), XS__setskill, file);
|
||||
newXS(strcpy(buf, "setallskill"), XS__setallskill, file);
|
||||
newXS(strcpy(buf, "assigntask"), XS__assigntask, file);
|
||||
newXS(strcpy(buf, "attack"), XS__attack, file);
|
||||
newXS(strcpy(buf, "attacknpc"), XS__attacknpc, file);
|
||||
newXS(strcpy(buf, "attacknpctype"), XS__attacknpctype, file);
|
||||
newXS(strcpy(buf, "save"), XS__save, file);
|
||||
newXS(strcpy(buf, "faction"), XS__faction, file);
|
||||
newXS(strcpy(buf, "setsky"), XS__setsky, file);
|
||||
newXS(strcpy(buf, "setguild"), XS__setguild, file);
|
||||
newXS(strcpy(buf, "createguild"), XS__createguild, file);
|
||||
newXS(strcpy(buf, "settime"), XS__settime, file);
|
||||
newXS(strcpy(buf, "itemlink"), XS__itemlink, file);
|
||||
newXS(strcpy(buf, "signal"), XS__signal, file);
|
||||
newXS(strcpy(buf, "signalwith"), XS__signalwith, file);
|
||||
newXS(strcpy(buf, "setglobal"), XS__setglobal, file);
|
||||
newXS(strcpy(buf, "targlobal"), XS__targlobal, file);
|
||||
newXS(strcpy(buf, "delglobal"), XS__delglobal, file);
|
||||
newXS(strcpy(buf, "ding"), XS__ding, file);
|
||||
newXS(strcpy(buf, "rebind"), XS__rebind, file);
|
||||
newXS(strcpy(buf, "start"), XS__start, file);
|
||||
newXS(strcpy(buf, "stop"), XS__stop, file);
|
||||
newXS(strcpy(buf, "pause"), XS__pause, file);
|
||||
newXS(strcpy(buf, "moveto"), XS__moveto, file);
|
||||
newXS(strcpy(buf, "resume"), XS__resume, file);
|
||||
newXS(strcpy(buf, "addldonpoints"), XS__addldonpoints, file);
|
||||
newXS(strcpy(buf, "addldonwin"), XS__addldonpoints, file);
|
||||
newXS(strcpy(buf, "addldonloss"), XS__addldonpoints, file);
|
||||
newXS(strcpy(buf, "setnexthpevent"), XS__setnexthpevent, file);
|
||||
newXS(strcpy(buf, "setnextinchpevent"), XS__setnextinchpevent, file);
|
||||
newXS(strcpy(buf, "sethp"), XS__sethp, file);
|
||||
newXS(strcpy(buf, "respawn"), XS__respawn, file);
|
||||
newXS(strcpy(buf, "getItemName"), XS_qc_getItemName, file);
|
||||
newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file);
|
||||
newXS(strcpy(buf, "set_proximity"), XS__set_proximity, file);
|
||||
newXS(strcpy(buf, "clear_proximity"), XS__clear_proximity, file);
|
||||
newXS(strcpy(buf, "enable_proximity_say"), XS__enable_proximity_say, file);
|
||||
newXS(strcpy(buf, "disable_proximity_say"), XS__disable_proximity_say, file);
|
||||
newXS(strcpy(buf, "setanim"), XS__setanim, file);
|
||||
newXS(strcpy(buf, "showgrid"), XS__showgrid, file);
|
||||
newXS(strcpy(buf, "spawn_condition"), XS__spawn_condition, file);
|
||||
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
|
||||
newXS(strcpy(buf, "toggle_spawn_event"), XS__toggle_spawn_event, file);
|
||||
newXS(strcpy(buf, "has_zone_flag"), XS__has_zone_flag, file);
|
||||
newXS(strcpy(buf, "set_zone_flag"), XS__set_zone_flag, file);
|
||||
newXS(strcpy(buf, "clear_zone_flag"), XS__clear_zone_flag, file);
|
||||
newXS(strcpy(buf, "summonburriedplayercorpse"), XS__summonburriedplayercorpse, file);
|
||||
newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file);
|
||||
newXS(strcpy(buf, "getplayerburriedcorpsecount"), XS__getplayerburriedcorpsecount, file);
|
||||
newXS(strcpy(buf, "buryplayercorpse"), XS__buryplayercorpse, file);
|
||||
newXS(strcpy(buf, "forcedooropen"), XS__forcedooropen, file);
|
||||
newXS(strcpy(buf, "forcedoorclose"), XS__forcedoorclose, file);
|
||||
newXS(strcpy(buf, "toggledoorstate"), XS__toggledoorstate, file);
|
||||
newXS(strcpy(buf, "isdooropen"), XS__isdooropen, file);
|
||||
newXS(strcpy(buf, "depopall"), XS__depopall, file);
|
||||
newXS(strcpy(buf, "depopzone"), XS__depopzone, file);
|
||||
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
|
||||
newXS(strcpy(buf, "npcrace"), XS__npcrace, file);
|
||||
newXS(strcpy(buf, "npcgender"), XS__npcgender, file);
|
||||
newXS(strcpy(buf, "npcsize"), XS__npcsize, file);
|
||||
newXS(strcpy(buf, "npctexture"), XS__npctexture, file);
|
||||
newXS(strcpy(buf, "playerrace"), XS__playerrace, file);
|
||||
newXS(strcpy(buf, "playergender"), XS__playergender, file);
|
||||
newXS(strcpy(buf, "playersize"), XS__playersize, file);
|
||||
newXS(strcpy(buf, "playertexture"), XS__playertexture, file);
|
||||
newXS(strcpy(buf, "playerfeature"), XS__playerfeature, file);
|
||||
newXS(strcpy(buf, "npcfeature"), XS__npcfeature, file);
|
||||
|
||||
#ifdef BOTS
|
||||
newXS(strcpy(buf, "botquest"), XS__botquest, file);
|
||||
newXS(strcpy(buf, "spawnbotcount"), XS__spawnbotcount, file);
|
||||
newXS(strcpy(buf, "createbotcount"), XS__createbotcount, file);
|
||||
newXS(strcpy(buf, "createBot"), XS__createBot, file);
|
||||
#endif //BOTS
|
||||
|
||||
newXS(strcpy(buf, "taskselector"), XS__taskselector, file);
|
||||
newXS(strcpy(buf, "tasksetselector"), XS__tasksetselector, file);
|
||||
newXS(strcpy(buf, "enabletask"), XS__enabletask, file);
|
||||
newXS(strcpy(buf, "disabletask"), XS__disabletask, file);
|
||||
newXS(strcpy(buf, "istaskenabled"), XS__istaskenabled, file);
|
||||
newXS(strcpy(buf, "istaskactive"), XS__istaskactive, file);
|
||||
newXS(strcpy(buf, "istaskactivityactive"), XS__istaskactivityactive, file);
|
||||
newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file);
|
||||
newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file);
|
||||
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
|
||||
newXS(strcpy(buf, "taskexploredarea"), XS__taskexploredarea, file);
|
||||
newXS(strcpy(buf, "assigntask"), XS__assigntask, file);
|
||||
newXS(strcpy(buf, "failtask"), XS__failtask, file);
|
||||
newXS(strcpy(buf, "tasktimeleft"), XS__tasktimeleft, file);
|
||||
newXS(strcpy(buf, "istaskcompleted"), XS__istaskcompleted, file);
|
||||
newXS(strcpy(buf, "enabledtaskcount"), XS__enabledtaskcount, file);
|
||||
newXS(strcpy(buf, "firsttaskinset"), XS__firsttaskinset, file);
|
||||
newXS(strcpy(buf, "lasttaskinset"), XS__lasttaskinset, file);
|
||||
newXS(strcpy(buf, "nexttaskinset"), XS__nexttaskinset, file);
|
||||
newXS(strcpy(buf, "activespeaktask"), XS__activespeaktask, file);
|
||||
newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file);
|
||||
newXS(strcpy(buf, "activetasksinset"), XS__activetasksinset, file);
|
||||
newXS(strcpy(buf, "completedtasksinset"), XS__completedtasksinset, file);
|
||||
newXS(strcpy(buf, "istaskappropriate"), XS__istaskappropriate, file);
|
||||
newXS(strcpy(buf, "popup"), XS__popup, file);
|
||||
newXS(strcpy(buf, "castspell"), XS__castspell, file);
|
||||
newXS(strcpy(buf, "changedeity"), XS__changedeity, file);
|
||||
newXS(strcpy(buf, "checktitle"), XS__checktitle, file);
|
||||
newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file);
|
||||
newXS(strcpy(buf, "clear_proximity"), XS__clear_proximity, file);
|
||||
newXS(strcpy(buf, "clear_zone_flag"), XS__clear_zone_flag, file);
|
||||
newXS(strcpy(buf, "clearspawntimers"), XS__clearspawntimers, file);
|
||||
newXS(strcpy(buf, "ze"), XS__ze, file);
|
||||
newXS(strcpy(buf, "we"), XS__we, file);
|
||||
newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
|
||||
newXS(strcpy(buf, "collectitems"), XS__collectitems, file);
|
||||
newXS(strcpy(buf, "completedtasksinset"), XS__completedtasksinset, file);
|
||||
newXS(strcpy(buf, "createdoor"), XS__CreateDoor, file);
|
||||
newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file);
|
||||
newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file);
|
||||
newXS(strcpy(buf, "createdoor"), XS__CreateDoor, file);
|
||||
newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file);
|
||||
newXS(strcpy(buf, "collectitems"), XS__collectitems, file);
|
||||
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
|
||||
newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file);
|
||||
newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file);
|
||||
newXS(strcpy(buf, "varlink"), XS__varlink, file);
|
||||
newXS(strcpy(buf, "saylink"), XS__saylink, file);
|
||||
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
|
||||
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
|
||||
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
|
||||
newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file);
|
||||
newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file);
|
||||
newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file);
|
||||
newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file);
|
||||
newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file);
|
||||
newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file);
|
||||
newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file);
|
||||
newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file);
|
||||
newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file);
|
||||
newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file);
|
||||
newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file);
|
||||
newXS(strcpy(buf, "IsRunning"), XS__IsRunning, file);
|
||||
newXS(strcpy(buf, "IsEffectInSpell"), XS__IsEffectInSpell, file);
|
||||
newXS(strcpy(buf, "IsBeneficialSpell"), XS__IsBeneficialSpell, file);
|
||||
newXS(strcpy(buf, "GetSpellResistType"), XS__GetSpellResistType, file);
|
||||
newXS(strcpy(buf, "GetSpellTargetType"), XS__GetSpellTargetType, file);
|
||||
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
|
||||
newXS(strcpy(buf, "factionvalue"), XS_FactionValue, file);
|
||||
newXS(strcpy(buf, "checktitle"), XS__checktitle, file);
|
||||
newXS(strcpy(buf, "enabletitle"), XS__enabletitle, file);
|
||||
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
|
||||
newXS(strcpy(buf, "wearchange"), XS__wearchange, file);
|
||||
newXS(strcpy(buf, "voicetell"), XS__voicetell, file);
|
||||
newXS(strcpy(buf, "LearnRecipe"), XS__LearnRecipe, file);
|
||||
newXS(strcpy(buf, "SendMail"), XS__SendMail, file);
|
||||
newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file);
|
||||
newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file);
|
||||
newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file);
|
||||
newXS(strcpy(buf, "createguild"), XS__createguild, file);
|
||||
newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file);
|
||||
newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file);
|
||||
newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file);
|
||||
newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file);
|
||||
newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file);
|
||||
newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file);
|
||||
newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file);
|
||||
newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file);
|
||||
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
|
||||
newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file);
|
||||
newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file);
|
||||
newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file);
|
||||
newXS(strcpy(buf, "delglobal"), XS__delglobal, file);
|
||||
newXS(strcpy(buf, "depop"), XS__depop, file);
|
||||
newXS(strcpy(buf, "depop_withtimer"), XS__depop_withtimer, file);
|
||||
newXS(strcpy(buf, "depopall"), XS__depopall, file);
|
||||
newXS(strcpy(buf, "depopzone"), XS__depopzone, file);
|
||||
newXS(strcpy(buf, "ding"), XS__ding, file);
|
||||
newXS(strcpy(buf, "disable_proximity_say"), XS__disable_proximity_say, file);
|
||||
newXS(strcpy(buf, "disable_spawn2"), XS__disable_spawn2, file);
|
||||
newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file);
|
||||
newXS(strcpy(buf, "disabletask"), XS__disabletask, file);
|
||||
newXS(strcpy(buf, "doanim"), XS__doanim, file);
|
||||
newXS(strcpy(buf, "echo"), XS__echo, file);
|
||||
newXS(strcpy(buf, "emote"), XS__emote, file);
|
||||
newXS(strcpy(buf, "enable_proximity_say"), XS__enable_proximity_say, file);
|
||||
newXS(strcpy(buf, "enable_spawn2"), XS__enable_spawn2, file);
|
||||
newXS(strcpy(buf, "enabledtaskcount"), XS__enabledtaskcount, file);
|
||||
newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file);
|
||||
newXS(strcpy(buf, "enabletask"), XS__enabletask, file);
|
||||
newXS(strcpy(buf, "enabletitle"), XS__enabletitle, file);
|
||||
newXS(strcpy(buf, "exp"), XS__exp, file);
|
||||
newXS(strcpy(buf, "faction"), XS__faction, file);
|
||||
newXS(strcpy(buf, "factionvalue"), XS_FactionValue, file);
|
||||
newXS(strcpy(buf, "failtask"), XS__failtask, file);
|
||||
newXS(strcpy(buf, "firsttaskinset"), XS__firsttaskinset, file);
|
||||
newXS(strcpy(buf, "follow"), XS__follow, file);
|
||||
newXS(strcpy(buf, "forcedoorclose"), XS__forcedoorclose, file);
|
||||
newXS(strcpy(buf, "forcedooropen"), XS__forcedooropen, file);
|
||||
newXS(strcpy(buf, "getItemName"), XS_qc_getItemName, file);
|
||||
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
|
||||
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
|
||||
newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
|
||||
newXS(strcpy(buf, "getplayerburriedcorpsecount"), XS__getplayerburriedcorpsecount, file);
|
||||
newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file);
|
||||
newXS(strcpy(buf, "givecash"), XS__givecash, file);
|
||||
newXS(strcpy(buf, "gmmove"), XS__gmmove, file);
|
||||
newXS(strcpy(buf, "gmsay"), XS__gmsay, file);
|
||||
newXS(strcpy(buf, "has_zone_flag"), XS__has_zone_flag, file);
|
||||
newXS(strcpy(buf, "incstat"), XS__incstat, file);
|
||||
newXS(strcpy(buf, "isdisctome"), XS__isdisctome, file);
|
||||
newXS(strcpy(buf, "isdooropen"), XS__isdooropen, file);
|
||||
newXS(strcpy(buf, "istaskactive"), XS__istaskactive, file);
|
||||
newXS(strcpy(buf, "istaskactivityactive"), XS__istaskactivityactive, file);
|
||||
newXS(strcpy(buf, "istaskappropriate"), XS__istaskappropriate, file);
|
||||
newXS(strcpy(buf, "istaskcompleted"), XS__istaskcompleted, file);
|
||||
newXS(strcpy(buf, "istaskenabled"), XS__istaskenabled, file);
|
||||
newXS(strcpy(buf, "itemlink"), XS__itemlink, file);
|
||||
newXS(strcpy(buf, "lasttaskinset"), XS__lasttaskinset, file);
|
||||
newXS(strcpy(buf, "level"), XS__level, file);
|
||||
newXS(strcpy(buf, "me"), XS__me, file);
|
||||
newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file);
|
||||
newXS(strcpy(buf, "movegrp"), XS__movegrp, file);
|
||||
newXS(strcpy(buf, "movepc"), XS__movepc, file);
|
||||
newXS(strcpy(buf, "moveto"), XS__moveto, file);
|
||||
newXS(strcpy(buf, "nexttaskinset"), XS__nexttaskinset, file);
|
||||
newXS(strcpy(buf, "npcfeature"), XS__npcfeature, file);
|
||||
newXS(strcpy(buf, "npcgender"), XS__npcgender, file);
|
||||
newXS(strcpy(buf, "npcrace"), XS__npcrace, file);
|
||||
newXS(strcpy(buf, "npcsize"), XS__npcsize, file);
|
||||
newXS(strcpy(buf, "npctexture"), XS__npctexture, file);
|
||||
newXS(strcpy(buf, "pause"), XS__pause, file);
|
||||
newXS(strcpy(buf, "permaclass"), XS__permaclass, file);
|
||||
newXS(strcpy(buf, "permagender"), XS__permagender, file);
|
||||
newXS(strcpy(buf, "permarace"), XS__permarace, file);
|
||||
newXS(strcpy(buf, "playerfeature"), XS__playerfeature, file);
|
||||
newXS(strcpy(buf, "playergender"), XS__playergender, file);
|
||||
newXS(strcpy(buf, "playerrace"), XS__playerrace, file);
|
||||
newXS(strcpy(buf, "playersize"), XS__playersize, file);
|
||||
newXS(strcpy(buf, "playertexture"), XS__playertexture, file);
|
||||
newXS(strcpy(buf, "popup"), XS__popup, file);
|
||||
newXS(strcpy(buf, "pvp"), XS__pvp, file);
|
||||
newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file);
|
||||
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
|
||||
newXS(strcpy(buf, "rain"), XS__rain, file);
|
||||
newXS(strcpy(buf, "rebind"), XS__rebind, file);
|
||||
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
|
||||
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
|
||||
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
|
||||
newXS(strcpy(buf, "respawn"), XS__respawn, file);
|
||||
newXS(strcpy(buf, "resume"), XS__resume, file);
|
||||
newXS(strcpy(buf, "safemove"), XS__safemove, file);
|
||||
newXS(strcpy(buf, "save"), XS__save, file);
|
||||
newXS(strcpy(buf, "say"), XS__say, file);
|
||||
newXS(strcpy(buf, "saylink"), XS__saylink, file);
|
||||
newXS(strcpy(buf, "scribespells"), XS__scribespells, file);
|
||||
newXS(strcpy(buf, "selfcast"), XS__selfcast, file);
|
||||
newXS(strcpy(buf, "set_proximity"), XS__set_proximity, file);
|
||||
newXS(strcpy(buf, "set_zone_flag"), XS__set_zone_flag, file);
|
||||
newXS(strcpy(buf, "setallskill"), XS__setallskill, file);
|
||||
newXS(strcpy(buf, "setanim"), XS__setanim, file);
|
||||
newXS(strcpy(buf, "setglobal"), XS__setglobal, file);
|
||||
newXS(strcpy(buf, "setguild"), XS__setguild, file);
|
||||
newXS(strcpy(buf, "sethp"), XS__sethp, file);
|
||||
newXS(strcpy(buf, "setlanguage"), XS__setlanguage, file);
|
||||
newXS(strcpy(buf, "setnexthpevent"), XS__setnexthpevent, file);
|
||||
newXS(strcpy(buf, "setnextinchpevent"), XS__setnextinchpevent, file);
|
||||
newXS(strcpy(buf, "setskill"), XS__setskill, file);
|
||||
newXS(strcpy(buf, "setsky"), XS__setsky, file);
|
||||
newXS(strcpy(buf, "setstat"), XS__setstat, file);
|
||||
newXS(strcpy(buf, "settarget"), XS__settarget, file);
|
||||
newXS(strcpy(buf, "settime"), XS__settime, file);
|
||||
newXS(strcpy(buf, "settimer"), XS__settimer, file);
|
||||
newXS(strcpy(buf, "settimerMS"), XS__settimerMS, file);
|
||||
newXS(strcpy(buf, "sfollow"), XS__sfollow, file);
|
||||
newXS(strcpy(buf, "shout"), XS__shout, file);
|
||||
newXS(strcpy(buf, "shout2"), XS__shout2, file);
|
||||
newXS(strcpy(buf, "showgrid"), XS__showgrid, file);
|
||||
newXS(strcpy(buf, "signal"), XS__signal, file);
|
||||
newXS(strcpy(buf, "signalwith"), XS__signalwith, file);
|
||||
newXS(strcpy(buf, "snow"), XS__snow, file);
|
||||
newXS(strcpy(buf, "spawn"), XS__spawn, file);
|
||||
newXS(strcpy(buf, "spawn2"), XS__spawn2, file);
|
||||
newXS(strcpy(buf, "spawn_condition"), XS__spawn_condition, file);
|
||||
newXS(strcpy(buf, "spawn_from_spawn2"), XS__spawn_from_spawn2, file);
|
||||
newXS(strcpy(buf, "start"), XS__start, file);
|
||||
newXS(strcpy(buf, "stop"), XS__stop, file);
|
||||
newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file);
|
||||
newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file);
|
||||
newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file);
|
||||
newXS(strcpy(buf, "summonburriedplayercorpse"), XS__summonburriedplayercorpse, file);
|
||||
newXS(strcpy(buf, "summonitem"), XS__summonitem, file);
|
||||
newXS(strcpy(buf, "surname"), XS__surname, file);
|
||||
newXS(strcpy(buf, "targlobal"), XS__targlobal, file);
|
||||
newXS(strcpy(buf, "taskexploredarea"), XS__taskexploredarea, file);
|
||||
newXS(strcpy(buf, "taskselector"), XS__taskselector, file);
|
||||
newXS(strcpy(buf, "tasksetselector"), XS__tasksetselector, file);
|
||||
newXS(strcpy(buf, "tasktimeleft"), XS__tasktimeleft, file);
|
||||
newXS(strcpy(buf, "toggle_spawn_event"), XS__toggle_spawn_event, file);
|
||||
newXS(strcpy(buf, "toggledoorstate"), XS__toggledoorstate, file);
|
||||
newXS(strcpy(buf, "traindisc"), XS__traindisc, file);
|
||||
newXS(strcpy(buf, "traindiscs"), XS__traindiscs, file);
|
||||
newXS(strcpy(buf, "unique_spawn"), XS__unique_spawn, file);
|
||||
newXS(strcpy(buf, "unscribespells"), XS__unscribespells, file);
|
||||
newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file);
|
||||
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
|
||||
newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file);
|
||||
newXS(strcpy(buf, "varlink"), XS__varlink, file);
|
||||
newXS(strcpy(buf, "voicetell"), XS__voicetell, file);
|
||||
newXS(strcpy(buf, "we"), XS__we, file);
|
||||
newXS(strcpy(buf, "wearchange"), XS__wearchange, file);
|
||||
newXS(strcpy(buf, "write"), XS__write, file);
|
||||
newXS(strcpy(buf, "ze"), XS__ze, file);
|
||||
newXS(strcpy(buf, "zone"), XS__zone, file);
|
||||
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
|
||||
@ -139,12 +139,12 @@ void Embperl::DoInit() {
|
||||
catch(const char *err)
|
||||
{
|
||||
//remember... lasterr() is no good if we crap out here, in construction
|
||||
LogFile->write(EQEMuLog::Quest, "perl error: %s", err);
|
||||
LogFile->write(EQEmuLog::Quest, "perl error: %s", err);
|
||||
throw "failed to install eval_file hook";
|
||||
}
|
||||
|
||||
#ifdef EMBPERL_IO_CAPTURE
|
||||
LogFile->write(EQEMuLog::Quest, "Tying perl output to eqemu logs");
|
||||
LogFile->write(EQEmuLog::Quest, "Tying perl output to eqemu logs");
|
||||
//make a tieable class to capture IO and pass it into EQEMuLog
|
||||
eval_pv(
|
||||
"package EQEmuIO; "
|
||||
@ -169,14 +169,14 @@ void Embperl::DoInit() {
|
||||
,FALSE
|
||||
);
|
||||
|
||||
LogFile->write(EQEMuLog::Quest, "Loading perlemb plugins.");
|
||||
LogFile->write(EQEmuLog::Quest, "Loading perlemb plugins.");
|
||||
try
|
||||
{
|
||||
eval_pv("main::eval_file('plugin', 'plugin.pl');", FALSE);
|
||||
}
|
||||
catch(const char *err)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Quest, "Warning - plugin.pl: %s", err);
|
||||
LogFile->write(EQEmuLog::Quest, "Warning - plugin.pl: %s", err);
|
||||
}
|
||||
try
|
||||
{
|
||||
@ -194,7 +194,7 @@ void Embperl::DoInit() {
|
||||
}
|
||||
catch(const char *err)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Quest, "Perl warning: %s", err);
|
||||
LogFile->write(EQEmuLog::Quest, "Perl warning: %s", err);
|
||||
}
|
||||
#endif //EMBPERL_PLUGIN
|
||||
in_use = false;
|
||||
@ -210,6 +210,8 @@ Embperl::~Embperl()
|
||||
" if(tied *STDERR) { untie(*STDERR); }"
|
||||
,FALSE);
|
||||
#endif
|
||||
PL_perl_destruct_level = 1;
|
||||
perl_destruct(my_perl);
|
||||
perl_free(my_perl);
|
||||
PERL_SYS_TERM();
|
||||
my_perl = NULL;
|
||||
|
||||
@ -63,7 +63,7 @@ EXTERN_C XS(boot_qc)
|
||||
file[255] = '\0';
|
||||
|
||||
if(items != 1)
|
||||
LogFile->write(EQEMuLog::Error, "boot_qc does not take any arguments.");
|
||||
LogFile->write(EQEmuLog::Error, "boot_qc does not take any arguments.");
|
||||
|
||||
char buf[128]; //shouldent have any function names longer than this.
|
||||
|
||||
@ -96,7 +96,7 @@ XS(XS_EQEmuIO_PRINT)
|
||||
int len = 0;
|
||||
for(i = 0; *cur != '\0'; i++, cur++) {
|
||||
if(*cur == '\n') {
|
||||
LogFile->writebuf(EQEMuLog::Quest, str + pos, 1, len);
|
||||
LogFile->writebuf(EQEmuLog::Quest, str + pos, 1, len);
|
||||
len = 0;
|
||||
pos = i+1;
|
||||
} else {
|
||||
@ -104,7 +104,7 @@ XS(XS_EQEmuIO_PRINT)
|
||||
}
|
||||
}
|
||||
if(len > 0) {
|
||||
LogFile->writebuf(EQEMuLog::Quest, str + pos, 1, len);
|
||||
LogFile->writebuf(EQEmuLog::Quest, str + pos, 1, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -371,7 +371,7 @@ void EntityList::CheckGroupList (const char *fname, const int fline)
|
||||
{
|
||||
if (*it == nullptr)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "nullptr group, %s:%i", fname, fline);
|
||||
LogFile->write(EQEmuLog::Error, "nullptr group, %s:%i", fname, fline);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -529,12 +529,12 @@ void EntityList::MobProcess()
|
||||
zone->StartShutdownTimer();
|
||||
Group *g = GetGroupByMob(mob);
|
||||
if(g) {
|
||||
LogFile->write(EQEMuLog::Error, "About to delete a client still in a group.");
|
||||
LogFile->write(EQEmuLog::Error, "About to delete a client still in a group.");
|
||||
g->DelMember(mob);
|
||||
}
|
||||
Raid *r = entity_list.GetRaidByClient(mob->CastToClient());
|
||||
if(r) {
|
||||
LogFile->write(EQEMuLog::Error, "About to delete a client still in a raid.");
|
||||
LogFile->write(EQEmuLog::Error, "About to delete a client still in a raid.");
|
||||
r->MemberZoned(mob->CastToClient());
|
||||
}
|
||||
entity_list.RemoveClient(id);
|
||||
@ -566,7 +566,7 @@ void EntityList::AddGroup(Group *group)
|
||||
|
||||
uint32 gid = worldserver.NextGroupID();
|
||||
if (gid == 0) {
|
||||
LogFile->write(EQEMuLog::Error,
|
||||
LogFile->write(EQEmuLog::Error,
|
||||
"Unable to get new group ID from world server. group is going to be broken.");
|
||||
return;
|
||||
}
|
||||
@ -595,7 +595,7 @@ void EntityList::AddRaid(Raid *raid)
|
||||
|
||||
uint32 gid = worldserver.NextGroupID();
|
||||
if (gid == 0) {
|
||||
LogFile->write(EQEMuLog::Error,
|
||||
LogFile->write(EQEmuLog::Error,
|
||||
"Unable to get new group ID from world server. group is going to be broken.");
|
||||
return;
|
||||
}
|
||||
@ -2025,13 +2025,16 @@ void EntityList::RemoveAllNPCs()
|
||||
|
||||
void EntityList::RemoveAllMercs()
|
||||
{
|
||||
// doesn't clear the data
|
||||
merc_list.clear();
|
||||
}
|
||||
|
||||
void EntityList::RemoveAllGroups()
|
||||
{
|
||||
while (group_list.size())
|
||||
while (group_list.size()) {
|
||||
safe_delete(group_list.front());
|
||||
group_list.pop_front();
|
||||
}
|
||||
#if EQDEBUG >= 5
|
||||
CheckGroupList (__FILE__, __LINE__);
|
||||
#endif
|
||||
@ -2039,8 +2042,10 @@ void EntityList::RemoveAllGroups()
|
||||
|
||||
void EntityList::RemoveAllRaids()
|
||||
{
|
||||
while (raid_list.size())
|
||||
while (raid_list.size()) {
|
||||
safe_delete(raid_list.front());
|
||||
raid_list.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::RemoveAllDoors()
|
||||
@ -2250,7 +2255,8 @@ bool EntityList::RemoveGroup(uint32 delete_id)
|
||||
while(iterator != group_list.end())
|
||||
{
|
||||
if((*iterator)->GetID() == delete_id) {
|
||||
group_list.remove (*iterator);
|
||||
safe_delete(*iterator);
|
||||
group_list.remove(*iterator);
|
||||
#if EQDEBUG >= 5
|
||||
CheckGroupList (__FILE__, __LINE__);
|
||||
#endif
|
||||
@ -2273,7 +2279,8 @@ bool EntityList::RemoveRaid(uint32 delete_id)
|
||||
while(iterator != raid_list.end())
|
||||
{
|
||||
if((*iterator)->GetID() == delete_id) {
|
||||
raid_list.remove (*iterator);
|
||||
safe_delete(*iterator);
|
||||
raid_list.remove(*iterator);
|
||||
return true;
|
||||
}
|
||||
++iterator;
|
||||
@ -2433,7 +2440,7 @@ void EntityList::RemoveFromHateLists(Mob *mob, bool settoone)
|
||||
if (!settoone)
|
||||
it->second->RemoveFromHateList(mob);
|
||||
else
|
||||
it->second->SetHate(mob, 1);
|
||||
it->second->SetHateAmountOnEnt(mob, 1);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
@ -2522,7 +2529,7 @@ char *EntityList::MakeNameUnique(char *name)
|
||||
return name;
|
||||
}
|
||||
}
|
||||
LogFile->write(EQEMuLog::Error, "Fatal error in EntityList::MakeNameUnique: Unable to find unique name for '%s'", name);
|
||||
LogFile->write(EQEmuLog::Error, "Fatal error in EntityList::MakeNameUnique: Unable to find unique name for '%s'", name);
|
||||
char tmp[64] = "!";
|
||||
strn0cpy(&tmp[1], name, sizeof(tmp) - 1);
|
||||
strcpy(name, tmp);
|
||||
@ -2817,7 +2824,7 @@ void EntityList::DoubleAggro(Mob *who)
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
if (it->second->CheckAggro(who))
|
||||
it->second->SetHate(who, it->second->CastToNPC()->GetHateAmount(who),
|
||||
it->second->SetHateAmountOnEnt(who, it->second->CastToNPC()->GetHateAmount(who),
|
||||
it->second->CastToNPC()->GetHateAmount(who) * 2);
|
||||
++it;
|
||||
}
|
||||
@ -2828,7 +2835,7 @@ void EntityList::HalveAggro(Mob *who)
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
if (it->second->CastToNPC()->CheckAggro(who))
|
||||
it->second->CastToNPC()->SetHate(who, it->second->CastToNPC()->GetHateAmount(who) / 2);
|
||||
it->second->CastToNPC()->SetHateAmountOnEnt(who, it->second->CastToNPC()->GetHateAmount(who) / 2);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
@ -2843,9 +2850,9 @@ void EntityList::Evade(Mob *who)
|
||||
amt = it->second->CastToNPC()->GetHateAmount(who);
|
||||
amt -= flatval;
|
||||
if (amt > 0)
|
||||
it->second->CastToNPC()->SetHate(who, amt);
|
||||
it->second->CastToNPC()->SetHateAmountOnEnt(who, amt);
|
||||
else
|
||||
it->second->CastToNPC()->SetHate(who, 0);
|
||||
it->second->CastToNPC()->SetHateAmountOnEnt(who, 0);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
@ -2913,7 +2920,7 @@ void EntityList::ClearZoneFeignAggro(Client *targ)
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::AggroZone(Mob *who, int hate)
|
||||
void EntityList::AggroZone(Mob *who, uint32 hate)
|
||||
{
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
@ -2934,11 +2941,6 @@ void EntityList::SignalMobsByNPCID(uint32 snpc, int signal_id)
|
||||
}
|
||||
}
|
||||
|
||||
bool tracking_compare(const std::pair<Mob *, float> &a, const std::pair<Mob *, float> &b)
|
||||
{
|
||||
return a.first->GetSpawnTimeStamp() > b.first->GetSpawnTimeStamp();
|
||||
}
|
||||
|
||||
bool EntityList::MakeTrackPacket(Client *client)
|
||||
{
|
||||
std::list<std::pair<Mob *, float> > tracking_list;
|
||||
@ -2956,8 +2958,6 @@ bool EntityList::MakeTrackPacket(Client *client)
|
||||
if (distance < 300)
|
||||
distance = 300;
|
||||
|
||||
Group *g = client->GetGroup();
|
||||
|
||||
for (auto it = mob_list.cbegin(); it != mob_list.cend(); ++it) {
|
||||
if (!it->second || it->second == client || !it->second->IsTrackable() ||
|
||||
it->second->IsInvisible(client))
|
||||
@ -2970,7 +2970,10 @@ bool EntityList::MakeTrackPacket(Client *client)
|
||||
tracking_list.push_back(std::make_pair(it->second, MobDistance));
|
||||
}
|
||||
|
||||
tracking_list.sort(tracking_compare);
|
||||
tracking_list.sort(
|
||||
[](const std::pair<Mob *, float> &a, const std::pair<Mob *, float> &b) {
|
||||
return a.first->GetSpawnTimeStamp() > b.first->GetSpawnTimeStamp();
|
||||
});
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_Track, sizeof(Track_Struct) * tracking_list.size());
|
||||
Tracking_Struct *outtrack = (Tracking_Struct *)outapp->pBuffer;
|
||||
outapp->priority = 6;
|
||||
@ -2978,15 +2981,13 @@ bool EntityList::MakeTrackPacket(Client *client)
|
||||
int index = 0;
|
||||
for (auto it = tracking_list.cbegin(); it != tracking_list.cend(); ++it, ++index) {
|
||||
Mob *cur_entity = it->first;
|
||||
outtrack->Entrys[index].entityid = cur_entity->GetID();
|
||||
outtrack->Entrys[index].entityid = (uint32)cur_entity->GetID();
|
||||
outtrack->Entrys[index].distance = it->second;
|
||||
outtrack->Entrys[index].level = cur_entity->GetLevel();
|
||||
outtrack->Entrys[index].NPC = !cur_entity->IsClient();
|
||||
if (g && cur_entity->IsClient() && g->IsGroupMember(cur_entity->CastToMob()))
|
||||
outtrack->Entrys[index].GroupMember = 1;
|
||||
else
|
||||
outtrack->Entrys[index].GroupMember = 0;
|
||||
outtrack->Entrys[index].is_npc = !cur_entity->IsClient();
|
||||
strn0cpy(outtrack->Entrys[index].name, cur_entity->GetName(), sizeof(outtrack->Entrys[index].name));
|
||||
outtrack->Entrys[index].is_pet = cur_entity->IsPet();
|
||||
outtrack->Entrys[index].is_merc = cur_entity->IsMerc();
|
||||
}
|
||||
|
||||
client->QueuePacket(outapp);
|
||||
@ -3641,7 +3642,7 @@ void EntityList::AddTempPetsToHateList(Mob *owner, Mob* other, bool bFrenzy)
|
||||
if (n->GetSwarmInfo()) {
|
||||
if (n->GetSwarmInfo()->owner_id == owner->GetID()) {
|
||||
if (!n->GetSpecialAbility(IMMUNE_AGGRO))
|
||||
n->hate_list.Add(other, 0, 0, bFrenzy);
|
||||
n->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
|
||||
}
|
||||
}
|
||||
++it;
|
||||
|
||||
@ -356,7 +356,7 @@ public:
|
||||
void ClearAggro(Mob* targ);
|
||||
void ClearFeignAggro(Mob* targ);
|
||||
void ClearZoneFeignAggro(Client* targ);
|
||||
void AggroZone(Mob* who, int hate = 0);
|
||||
void AggroZone(Mob* who, uint32 hate = 0);
|
||||
|
||||
bool Fighting(Mob* targ);
|
||||
void RemoveFromHateLists(Mob* mob, bool settoone = false);
|
||||
|
||||
@ -430,7 +430,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
void Client::SetLevel(uint8 set_level, bool command)
|
||||
{
|
||||
if (GetEXPForLevel(set_level) == 0xFFFFFFFF) {
|
||||
LogFile->write(EQEMuLog::Error,"Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
|
||||
LogFile->write(EQEmuLog::Error,"Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -488,7 +488,7 @@ void Client::SetLevel(uint8 set_level, bool command)
|
||||
safe_delete(outapp);
|
||||
this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change
|
||||
|
||||
LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
|
||||
LogFile->write(EQEmuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
|
||||
|
||||
CalcBonuses();
|
||||
|
||||
|
||||
@ -58,7 +58,7 @@ uint32 ZoneDatabase::GetZoneForage(uint32 ZoneID, uint8 skill) {
|
||||
"LIMIT %i", ZoneID, skill, FORAGE_ITEM_LIMIT);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Forage query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in Forage query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ uint32 ZoneDatabase::GetZoneForage(uint32 ZoneID, uint8 skill) {
|
||||
|
||||
item[index] = atoi(row[0]);
|
||||
chance[index] = atoi(row[1]) + chancepool;
|
||||
LogFile->write(EQEMuLog::Error, "Possible Forage: %d with a %d chance", item[index], chance[index]);
|
||||
LogFile->write(EQEmuLog::Error, "Possible Forage: %d with a %d chance", item[index], chance[index]);
|
||||
chancepool = chance[index];
|
||||
}
|
||||
|
||||
@ -250,7 +250,7 @@ void Client::GoFish()
|
||||
Bait = m_inv.GetItem(bslot);
|
||||
|
||||
//if the bait isnt equipped, need to add its skill bonus
|
||||
if(bslot >= EmuConstants::GENERAL_BEGIN && Bait->GetItem()->SkillModType == SkillFishing) {
|
||||
if(bslot >= EmuConstants::GENERAL_BEGIN && Bait != nullptr && Bait->GetItem()->SkillModType == SkillFishing) {
|
||||
fishing_skill += Bait->GetItem()->SkillModValue;
|
||||
}
|
||||
|
||||
@ -391,7 +391,7 @@ void Client::ForageItem(bool guarantee) {
|
||||
const Item_Struct* food_item = database.GetItem(foragedfood);
|
||||
|
||||
if(!food_item) {
|
||||
LogFile->write(EQEMuLog::Error, "nullptr returned from database.GetItem in ClientForageItem");
|
||||
LogFile->write(EQEmuLog::Error, "nullptr returned from database.GetItem in ClientForageItem");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
108
zone/groups.cpp
108
zone/groups.cpp
@ -26,23 +26,16 @@
|
||||
extern EntityList entity_list;
|
||||
extern WorldServer worldserver;
|
||||
|
||||
//
|
||||
// Xorlac: This will need proper synchronization to make it work correctly.
|
||||
// Also, should investigate client ack for packet to ensure proper synch.
|
||||
//
|
||||
|
||||
/*
|
||||
|
||||
note about how groups work:
|
||||
A group contains 2 list, a list of pointers to members and a
|
||||
list of member names. All members of a group should have their
|
||||
name in the membername array, wether they are in the zone or not.
|
||||
name in the membername array, whether they are in the zone or not.
|
||||
Only members in this zone will have non-null pointers in the
|
||||
members array.
|
||||
|
||||
*/
|
||||
|
||||
//create a group which should allready exist in the database
|
||||
//create a group which should already exist in the database
|
||||
Group::Group(uint32 gid)
|
||||
: GroupIDConsumer(gid)
|
||||
{
|
||||
@ -112,8 +105,7 @@ Group::~Group()
|
||||
}
|
||||
}
|
||||
|
||||
//Cofruben:Split money used in OP_Split.
|
||||
//Rewritten by Father Nitwit
|
||||
//Split money used in OP_Split (/split and /autosplit).
|
||||
void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter) {
|
||||
//avoid unneeded work
|
||||
if(copper == 0 && silver == 0 && gold == 0 && platinum == 0)
|
||||
@ -122,7 +114,8 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
|
||||
uint32 i;
|
||||
uint8 membercount = 0;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (members[i] != nullptr) {
|
||||
// Don't split with Mercs or Bots
|
||||
if (members[i] != nullptr && members[i]->IsClient()) {
|
||||
membercount++;
|
||||
}
|
||||
}
|
||||
@ -196,7 +189,7 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
|
||||
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (members[i] != nullptr && members[i]->IsClient()) { // If Group Member is Client
|
||||
Client *c = members[i]->CastToClient();
|
||||
Client *c = members[i]->CastToClient();
|
||||
//I could not get MoneyOnCorpse to work, so we use this
|
||||
c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true);
|
||||
c->Message(2, msg.c_str());
|
||||
@ -367,7 +360,6 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
||||
void Group::AddMember(const char *NewMemberName)
|
||||
{
|
||||
// This method should be called when both the new member and the group leader are in a different zone to this one.
|
||||
//
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
if(!strcasecmp(membername[i], NewMemberName))
|
||||
{
|
||||
@ -394,9 +386,8 @@ void Group::QueuePacket(const EQApplicationPacket *app, bool ack_req)
|
||||
members[i]->CastToClient()->QueuePacket(app, ack_req);
|
||||
}
|
||||
|
||||
// solar: sends the rest of the group's hps to member. this is useful when
|
||||
// someone first joins a group, but otherwise there shouldn't be a need to
|
||||
// call it
|
||||
// Sends the rest of the group's hps to member. this is useful when someone
|
||||
// first joins a group, but otherwise there shouldn't be a need to call it
|
||||
void Group::SendHPPacketsTo(Mob *member)
|
||||
{
|
||||
if(member && member->IsClient())
|
||||
@ -458,9 +449,11 @@ void Group::SendHPPacketsFrom(Mob *member)
|
||||
}
|
||||
|
||||
//updates a group member's client pointer when they zone in
|
||||
//if the group was in the zone allready
|
||||
//if the group was in the zone already
|
||||
bool Group::UpdatePlayer(Mob* update){
|
||||
|
||||
bool updateSuccess = false;
|
||||
|
||||
VerifyGroup();
|
||||
|
||||
uint32 i=0;
|
||||
@ -486,7 +479,8 @@ bool Group::UpdatePlayer(Mob* update){
|
||||
{
|
||||
members[i] = update;
|
||||
members[i]->SetGrouped(true);
|
||||
return true;
|
||||
updateSuccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -494,7 +488,7 @@ bool Group::UpdatePlayer(Mob* update){
|
||||
if (update->IsClient() && !mentoree && mentoree_name.length() && !mentoree_name.compare(update->GetName()))
|
||||
mentoree = update->CastToClient();
|
||||
|
||||
return false;
|
||||
return updateSuccess;
|
||||
}
|
||||
|
||||
|
||||
@ -519,6 +513,7 @@ void Group::MemberZoned(Mob* removemob) {
|
||||
}
|
||||
#endif //BOTS
|
||||
}
|
||||
|
||||
if(removemob->IsClient() && HasRole(removemob, RoleAssist))
|
||||
SetGroupAssistTarget(0);
|
||||
|
||||
@ -591,7 +586,7 @@ bool Group::DelMemberOOZ(const char *Name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Group::DelMember(Mob* oldmember,bool ignoresender)
|
||||
bool Group::DelMember(Mob* oldmember, bool ignoresender)
|
||||
{
|
||||
if (oldmember == nullptr)
|
||||
{
|
||||
@ -688,6 +683,8 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
|
||||
if(oldmember->IsClient())
|
||||
oldmember->CastToClient()->QueuePacket(outapp);
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
if(oldmember->IsClient())
|
||||
{
|
||||
@ -706,8 +703,6 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
|
||||
oldmember->SetGrouped(false);
|
||||
disbandcheck = true;
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
if(HasRole(oldmember, RoleTank))
|
||||
{
|
||||
SetGroupTankTarget(0);
|
||||
@ -997,24 +992,21 @@ void Group::SendLeadershipAAUpdate()
|
||||
// aware of it until they are next in the same zone as the leader.
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
|
||||
GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer;
|
||||
|
||||
gu->action = groupActAAUpdate;
|
||||
|
||||
uint32 i = 0;
|
||||
|
||||
gu->leader_aas = LeaderAbilities;
|
||||
|
||||
gu->NPCMarkerID = GetNPCMarkerID();
|
||||
|
||||
uint32 i = 0;
|
||||
for (i = 0;i < MAX_GROUP_MEMBERS; ++i)
|
||||
{
|
||||
if(members[i] && members[i]->IsClient())
|
||||
{
|
||||
strcpy(gu->yourname, members[i]->GetName());
|
||||
strcpy(gu->membername, members[i]->GetName());
|
||||
members[i]->CastToClient()->QueuePacket(outapp);
|
||||
}
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
}
|
||||
@ -1036,8 +1028,8 @@ uint8 Group::GroupCount() {
|
||||
|
||||
uint32 Group::GetHighestLevel()
|
||||
{
|
||||
uint32 level = 1;
|
||||
uint32 i;
|
||||
uint32 level = 1;
|
||||
uint32 i;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
|
||||
{
|
||||
if (members[i])
|
||||
@ -1048,10 +1040,11 @@ uint32 i;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
uint32 Group::GetLowestLevel()
|
||||
{
|
||||
uint32 level = 255;
|
||||
uint32 i;
|
||||
uint32 level = 255;
|
||||
uint32 i;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
|
||||
{
|
||||
if (members[i])
|
||||
@ -1082,7 +1075,7 @@ bool Group::LearnMembers() {
|
||||
return false;
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
LogFile->write(EQEMuLog::Error, "Error getting group members for group %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error getting group members for group %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1111,18 +1104,16 @@ void Group::VerifyGroup() {
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (membername[i][0] == '\0') {
|
||||
#if EQDEBUG >= 7
|
||||
LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long)GetID(), i);
|
||||
LogFile->write(EQEmuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long)GetID(), i);
|
||||
#endif
|
||||
members[i] = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
//it should be safe to use GetClientByName, but Group is trying
|
||||
//to be generic, so we'll go for general Mob
|
||||
Mob *them = entity_list.GetMob(membername[i]);
|
||||
if(them == nullptr && members[i] != nullptr) { //they arnt here anymore....
|
||||
if(them == nullptr && members[i] != nullptr) { //they aren't in zone
|
||||
#if EQDEBUG >= 6
|
||||
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' has disappeared!!", (unsigned long)GetID(), membername[i]);
|
||||
LogFile->write(EQEmuLog::Debug, "Member of group %lu named '%s' has disappeared!!", (unsigned long)GetID(), membername[i]);
|
||||
#endif
|
||||
membername[i][0] = '\0';
|
||||
members[i] = nullptr;
|
||||
@ -1131,18 +1122,17 @@ LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long
|
||||
|
||||
if(them != nullptr && members[i] != them) { //our pointer is out of date... not so good.
|
||||
#if EQDEBUG >= 5
|
||||
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' had an out of date pointer!!", (unsigned long)GetID(), membername[i]);
|
||||
LogFile->write(EQEmuLog::Debug, "Member of group %lu named '%s' had an out of date pointer!!", (unsigned long)GetID(), membername[i]);
|
||||
#endif
|
||||
members[i] = them;
|
||||
continue;
|
||||
}
|
||||
#if EQDEBUG >= 8
|
||||
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' is valid.", (unsigned long)GetID(), membername[i]);
|
||||
LogFile->write(EQEmuLog::Debug, "Member of group %lu named '%s' is valid.", (unsigned long)GetID(), membername[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) {
|
||||
uint32 i;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
@ -1151,13 +1141,14 @@ void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, co
|
||||
|
||||
if(members[i] == sender)
|
||||
continue;
|
||||
|
||||
if(!members[i]->IsClient())
|
||||
continue;
|
||||
|
||||
members[i]->Message_StringID(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Client::LeaveGroup() {
|
||||
Group *g = GetGroup();
|
||||
|
||||
@ -1177,7 +1168,7 @@ void Client::LeaveGroup() {
|
||||
else
|
||||
{
|
||||
g->DelMember(this);
|
||||
if (GetMerc() && GetMerc()->HasGroup() && GetMerc()->GetGroup() == g)
|
||||
if (GetMerc() != nullptr && g == GetMerc()->GetGroup() )
|
||||
{
|
||||
GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup());
|
||||
}
|
||||
@ -1362,7 +1353,7 @@ void Group::MarkNPC(Mob* Target, int Number)
|
||||
// Send a packet to all group members in this zone causing the client to prefix the Target mob's name
|
||||
// with the specified Number.
|
||||
//
|
||||
if(!Target || Target->IsClient())
|
||||
if(!Target || Target->IsClient() || Target->IsMerc())
|
||||
return;
|
||||
|
||||
if((Number < 1) || (Number > MAX_MARKED_NPCS))
|
||||
@ -1472,7 +1463,7 @@ void Group::DelegateMainTank(const char *NewMainTankName, uint8 toggle)
|
||||
MainTankName.c_str(), GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group main tank: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to set group main tank: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1518,7 +1509,7 @@ void Group::DelegateMainAssist(const char *NewMainAssistName, uint8 toggle)
|
||||
MainAssistName.c_str(), GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group main assist: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to set group main assist: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
}
|
||||
@ -1565,7 +1556,7 @@ void Group::DelegatePuller(const char *NewPullerName, uint8 toggle)
|
||||
PullerName.c_str(), GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group main puller: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to set group main puller: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
@ -1716,7 +1707,7 @@ void Group::UnDelegateMainTank(const char *OldMainTankName, uint8 toggle)
|
||||
std::string query = StringFormat("UPDATE group_leaders SET maintank = '' WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main tank: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to clear group main tank: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
if(!toggle) {
|
||||
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
@ -1765,7 +1756,7 @@ void Group::UnDelegateMainAssist(const char *OldMainAssistName, uint8 toggle)
|
||||
std::string query = StringFormat("UPDATE group_leaders SET assist = '' WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main assist: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to clear group main assist: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
if(!toggle)
|
||||
{
|
||||
@ -1793,7 +1784,7 @@ void Group::UnDelegatePuller(const char *OldPullerName, uint8 toggle)
|
||||
std::string query = StringFormat("UPDATE group_leaders SET puller = '' WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main puller: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to clear group main puller: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
if(!toggle) {
|
||||
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
@ -1876,7 +1867,7 @@ void Group::SetGroupMentor(int percent, char *name)
|
||||
mentoree_name.c_str(), mentor_percent, GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to set group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Group::ClearGroupMentor()
|
||||
@ -1887,7 +1878,7 @@ void Group::ClearGroupMentor()
|
||||
std::string query = StringFormat("UPDATE group_leaders SET mentoree = '', mentor_percent = 0 WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to clear group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Group::NotifyAssistTarget(Client *c)
|
||||
@ -1957,7 +1948,7 @@ void Group::DelegateMarkNPC(const char *NewNPCMarkerName)
|
||||
NewNPCMarkerName, GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set group mark npc: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to set group mark npc: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Group::NotifyMarkNPC(Client *c)
|
||||
@ -2038,7 +2029,7 @@ void Group::UnDelegateMarkNPC(const char *OldNPCMarkerName)
|
||||
std::string query = StringFormat("UPDATE group_leaders SET marknpc = '' WHERE gid = %i LIMIT 1", GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear group marknpc: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to clear group marknpc: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
@ -2055,7 +2046,7 @@ void Group::SaveGroupLeaderAA()
|
||||
safe_delete_array(queryBuffer);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
@ -2165,7 +2156,6 @@ int8 Group::GetNumberNeedingHealedInGroup(int8 hpr, bool includePets) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return needHealed;
|
||||
}
|
||||
|
||||
@ -2227,7 +2217,7 @@ void Group::ChangeLeader(Mob* newleader)
|
||||
// this changes the current group leader, notifies other members, and updates leadship AA
|
||||
|
||||
// if the new leader is invalid, do nothing
|
||||
if (!newleader)
|
||||
if (!newleader || !newleader->IsClient())
|
||||
return;
|
||||
|
||||
Mob* oldleader = GetLeader();
|
||||
|
||||
@ -413,7 +413,7 @@ bool ZoneDatabase::CheckGuildDoor(uint8 doorid, uint16 guild_id, const char* zon
|
||||
doorid-128, zone);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in CheckGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in CheckGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -433,7 +433,7 @@ bool ZoneDatabase::SetGuildDoor(uint8 doorid,uint16 guild_id, const char* zone)
|
||||
guild_id, doorid, zone);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in SetGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in SetGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
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 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.
|
||||
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
|
||||
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 "client.h"
|
||||
@ -36,7 +36,7 @@ extern Zone *zone;
|
||||
|
||||
HateList::HateList()
|
||||
{
|
||||
owner = nullptr;
|
||||
hate_owner = nullptr;
|
||||
}
|
||||
|
||||
HateList::~HateList()
|
||||
@ -45,29 +45,29 @@ HateList::~HateList()
|
||||
|
||||
// added for frenzy support
|
||||
// checks if target still is in frenzy mode
|
||||
void HateList::CheckFrenzyHate()
|
||||
void HateList::IsEntityInFrenzyMode()
|
||||
{
|
||||
auto iterator = list.begin();
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
if ((*iterator)->ent->GetHPRatio() >= 20)
|
||||
(*iterator)->bFrenzy = false;
|
||||
if ((*iterator)->entity_on_hatelist->GetHPRatio() >= 20)
|
||||
(*iterator)->is_entity_frenzy = false;
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
|
||||
void HateList::Wipe()
|
||||
void HateList::WipeHateList()
|
||||
{
|
||||
auto iterator = list.begin();
|
||||
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
Mob* m = (*iterator)->ent;
|
||||
if(m)
|
||||
Mob* m = (*iterator)->entity_on_hatelist;
|
||||
if (m)
|
||||
{
|
||||
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), m, "0", 0);
|
||||
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), m, "0", 0);
|
||||
|
||||
if(m->IsClient())
|
||||
if (m->IsClient())
|
||||
m->CastToClient()->DecrementAggroCount();
|
||||
}
|
||||
delete (*iterator);
|
||||
@ -76,38 +76,38 @@ void HateList::Wipe()
|
||||
}
|
||||
}
|
||||
|
||||
bool HateList::IsOnHateList(Mob *mob)
|
||||
bool HateList::IsEntOnHateList(Mob *mob)
|
||||
{
|
||||
if(Find(mob))
|
||||
if (Find(mob))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
tHateEntry *HateList::Find(Mob *ent)
|
||||
struct_HateList *HateList::Find(Mob *in_entity)
|
||||
{
|
||||
auto iterator = list.begin();
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
if((*iterator)->ent == ent)
|
||||
if ((*iterator)->entity_on_hatelist == in_entity)
|
||||
return (*iterator);
|
||||
++iterator;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void HateList::Set(Mob* other, uint32 in_hate, uint32 in_dam)
|
||||
void HateList::SetHateAmountOnEnt(Mob* other, uint32 in_hate, uint32 in_damage)
|
||||
{
|
||||
tHateEntry *p = Find(other);
|
||||
if(p)
|
||||
struct_HateList *entity = Find(other);
|
||||
if (entity)
|
||||
{
|
||||
if(in_dam > 0)
|
||||
p->damage = in_dam;
|
||||
if(in_hate > 0)
|
||||
p->hate = in_hate;
|
||||
if (in_damage > 0)
|
||||
entity->hatelist_damage = in_damage;
|
||||
if (in_hate > 0)
|
||||
entity->stored_hate_amount = in_hate;
|
||||
}
|
||||
}
|
||||
|
||||
Mob* HateList::GetDamageTop(Mob* hater)
|
||||
Mob* HateList::GetDamageTopOnHateList(Mob* hater)
|
||||
{
|
||||
Mob* current = nullptr;
|
||||
Group* grp = nullptr;
|
||||
@ -115,119 +115,117 @@ Mob* HateList::GetDamageTop(Mob* hater)
|
||||
uint32 dmg_amt = 0;
|
||||
|
||||
auto iterator = list.begin();
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
grp = nullptr;
|
||||
r = nullptr;
|
||||
|
||||
if((*iterator)->ent && (*iterator)->ent->IsClient()){
|
||||
r = entity_list.GetRaidByClient((*iterator)->ent->CastToClient());
|
||||
if ((*iterator)->entity_on_hatelist && (*iterator)->entity_on_hatelist->IsClient()){
|
||||
r = entity_list.GetRaidByClient((*iterator)->entity_on_hatelist->CastToClient());
|
||||
}
|
||||
|
||||
grp = entity_list.GetGroupByMob((*iterator)->ent);
|
||||
grp = entity_list.GetGroupByMob((*iterator)->entity_on_hatelist);
|
||||
|
||||
if((*iterator)->ent && r){
|
||||
if(r->GetTotalRaidDamage(hater) >= dmg_amt)
|
||||
if ((*iterator)->entity_on_hatelist && r){
|
||||
if (r->GetTotalRaidDamage(hater) >= dmg_amt)
|
||||
{
|
||||
current = (*iterator)->ent;
|
||||
current = (*iterator)->entity_on_hatelist;
|
||||
dmg_amt = r->GetTotalRaidDamage(hater);
|
||||
}
|
||||
}
|
||||
else if ((*iterator)->ent != nullptr && grp != nullptr)
|
||||
else if ((*iterator)->entity_on_hatelist != nullptr && grp != nullptr)
|
||||
{
|
||||
if (grp->GetTotalGroupDamage(hater) >= dmg_amt)
|
||||
{
|
||||
current = (*iterator)->ent;
|
||||
current = (*iterator)->entity_on_hatelist;
|
||||
dmg_amt = grp->GetTotalGroupDamage(hater);
|
||||
}
|
||||
}
|
||||
else if ((*iterator)->ent != nullptr && (uint32)(*iterator)->damage >= dmg_amt)
|
||||
else if ((*iterator)->entity_on_hatelist != nullptr && (uint32)(*iterator)->hatelist_damage >= dmg_amt)
|
||||
{
|
||||
current = (*iterator)->ent;
|
||||
dmg_amt = (*iterator)->damage;
|
||||
current = (*iterator)->entity_on_hatelist;
|
||||
dmg_amt = (*iterator)->hatelist_damage;
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
Mob* HateList::GetClosest(Mob *hater) {
|
||||
Mob* close = nullptr;
|
||||
float closedist = 99999.9f;
|
||||
float thisdist;
|
||||
Mob* HateList::GetClosestEntOnHateList(Mob *hater) {
|
||||
Mob* close_entity = nullptr;
|
||||
float close_distance = 99999.9f;
|
||||
float this_distance;
|
||||
|
||||
auto iterator = list.begin();
|
||||
while(iterator != list.end()) {
|
||||
thisdist = (*iterator)->ent->DistNoRootNoZ(*hater);
|
||||
if((*iterator)->ent != nullptr && thisdist <= closedist) {
|
||||
closedist = thisdist;
|
||||
close = (*iterator)->ent;
|
||||
while (iterator != list.end()) {
|
||||
this_distance = (*iterator)->entity_on_hatelist->DistNoRootNoZ(*hater);
|
||||
if ((*iterator)->entity_on_hatelist != nullptr && this_distance <= close_distance) {
|
||||
close_distance = this_distance;
|
||||
close_entity = (*iterator)->entity_on_hatelist;
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
|
||||
if ((!close && hater->IsNPC()) || (close && close->DivineAura()))
|
||||
close = hater->CastToNPC()->GetHateTop();
|
||||
if ((!close_entity && hater->IsNPC()) || (close_entity && close_entity->DivineAura()))
|
||||
close_entity = hater->CastToNPC()->GetHateTop();
|
||||
|
||||
return close;
|
||||
return close_entity;
|
||||
}
|
||||
|
||||
|
||||
// a few comments added, rearranged code for readability
|
||||
void HateList::Add(Mob *ent, int32 in_hate, int32 in_dam, bool bFrenzy, bool iAddIfNotExist)
|
||||
void HateList::AddEntToHateList(Mob *in_entity, int32 in_hate, int32 in_damage, bool in_is_entity_frenzied, bool iAddIfNotExist)
|
||||
{
|
||||
if(!ent)
|
||||
if (!in_entity)
|
||||
return;
|
||||
|
||||
if(ent->IsCorpse())
|
||||
if (in_entity->IsCorpse())
|
||||
return;
|
||||
|
||||
if(ent->IsClient() && ent->CastToClient()->IsDead())
|
||||
if (in_entity->IsClient() && in_entity->CastToClient()->IsDead())
|
||||
return;
|
||||
|
||||
tHateEntry *p = Find(ent);
|
||||
if (p)
|
||||
struct_HateList *entity = Find(in_entity);
|
||||
if (entity)
|
||||
{
|
||||
p->damage+=(in_dam>=0)?in_dam:0;
|
||||
p->hate+=in_hate;
|
||||
p->bFrenzy = bFrenzy;
|
||||
entity->hatelist_damage += (in_damage >= 0) ? in_damage : 0;
|
||||
entity->stored_hate_amount += in_hate;
|
||||
entity->is_entity_frenzy = in_is_entity_frenzied;
|
||||
}
|
||||
else if (iAddIfNotExist) {
|
||||
p = new tHateEntry;
|
||||
p->ent = ent;
|
||||
p->damage = (in_dam>=0)?in_dam:0;
|
||||
p->hate = in_hate;
|
||||
p->bFrenzy = bFrenzy;
|
||||
list.push_back(p);
|
||||
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), ent, "1", 0);
|
||||
entity = new struct_HateList;
|
||||
entity->entity_on_hatelist = in_entity;
|
||||
entity->hatelist_damage = (in_damage >= 0) ? in_damage : 0;
|
||||
entity->stored_hate_amount = in_hate;
|
||||
entity->is_entity_frenzy = in_is_entity_frenzied;
|
||||
list.push_back(entity);
|
||||
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), in_entity, "1", 0);
|
||||
|
||||
if (ent->IsClient()) {
|
||||
if (owner->CastToNPC()->IsRaidTarget())
|
||||
ent->CastToClient()->SetEngagedRaidTarget(true);
|
||||
ent->CastToClient()->IncrementAggroCount();
|
||||
if (in_entity->IsClient()) {
|
||||
if (hate_owner->CastToNPC()->IsRaidTarget())
|
||||
in_entity->CastToClient()->SetEngagedRaidTarget(true);
|
||||
in_entity->CastToClient()->IncrementAggroCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HateList::RemoveEnt(Mob *ent)
|
||||
bool HateList::RemoveEntFromHateList(Mob *in_entity)
|
||||
{
|
||||
if (!ent)
|
||||
if (!in_entity)
|
||||
return false;
|
||||
|
||||
bool found = false;
|
||||
bool is_found = false;
|
||||
auto iterator = list.begin();
|
||||
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
if((*iterator)->ent == ent)
|
||||
if ((*iterator)->entity_on_hatelist == in_entity)
|
||||
{
|
||||
if(ent)
|
||||
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), ent, "0", 0);
|
||||
found = true;
|
||||
if (in_entity)
|
||||
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), in_entity, "0", 0);
|
||||
is_found = true;
|
||||
|
||||
|
||||
if(ent && ent->IsClient())
|
||||
ent->CastToClient()->DecrementAggroCount();
|
||||
if (in_entity && in_entity->IsClient())
|
||||
in_entity->CastToClient()->DecrementAggroCount();
|
||||
|
||||
delete (*iterator);
|
||||
iterator = list.erase(iterator);
|
||||
@ -236,124 +234,128 @@ bool HateList::RemoveEnt(Mob *ent)
|
||||
else
|
||||
++iterator;
|
||||
}
|
||||
return found;
|
||||
return is_found;
|
||||
}
|
||||
|
||||
void HateList::DoFactionHits(int32 nfl_id) {
|
||||
if (nfl_id <= 0)
|
||||
void HateList::DoFactionHits(int32 npc_faction_level_id) {
|
||||
if (npc_faction_level_id <= 0)
|
||||
return;
|
||||
auto iterator = list.begin();
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
Client *p;
|
||||
Client *client;
|
||||
|
||||
if ((*iterator)->ent && (*iterator)->ent->IsClient())
|
||||
p = (*iterator)->ent->CastToClient();
|
||||
if ((*iterator)->entity_on_hatelist && (*iterator)->entity_on_hatelist->IsClient())
|
||||
client = (*iterator)->entity_on_hatelist->CastToClient();
|
||||
else
|
||||
p = nullptr;
|
||||
client = nullptr;
|
||||
|
||||
if (p)
|
||||
p->SetFactionLevel(p->CharacterID(), nfl_id, p->GetBaseClass(), p->GetBaseRace(), p->GetDeity());
|
||||
if (client)
|
||||
client->SetFactionLevel(client->CharacterID(), npc_faction_level_id, client->GetBaseClass(), client->GetBaseRace(), client->GetDeity());
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
|
||||
int HateList::SummonedPetCount(Mob *hater) {
|
||||
int HateList::GetSummonedPetCountOnHateList(Mob *hater) {
|
||||
|
||||
//Function to get number of 'Summoned' pets on a targets hate list to allow calculations for certian spell effects.
|
||||
//Unclear from description that pets are required to be 'summoned body type'. Will not require at this time.
|
||||
int petcount = 0;
|
||||
int pet_count = 0;
|
||||
auto iterator = list.begin();
|
||||
while(iterator != list.end()) {
|
||||
while (iterator != list.end()) {
|
||||
|
||||
if((*iterator)->ent != nullptr && (*iterator)->ent->IsNPC() && ((*iterator)->ent->CastToNPC()->IsPet() || ((*iterator)->ent->CastToNPC()->GetSwarmOwner() > 0)))
|
||||
if ((*iterator)->entity_on_hatelist != nullptr && (*iterator)->entity_on_hatelist->IsNPC() && ((*iterator)->entity_on_hatelist->CastToNPC()->IsPet() || ((*iterator)->entity_on_hatelist->CastToNPC()->GetSwarmOwner() > 0)))
|
||||
{
|
||||
++petcount;
|
||||
++pet_count;
|
||||
}
|
||||
|
||||
++iterator;
|
||||
}
|
||||
|
||||
return petcount;
|
||||
return pet_count;
|
||||
}
|
||||
|
||||
Mob *HateList::GetTop(Mob *center)
|
||||
Mob *HateList::GetEntWithMostHateOnList(Mob *center)
|
||||
{
|
||||
Mob* top = nullptr;
|
||||
int32 hate = -1;
|
||||
|
||||
if(center == nullptr)
|
||||
// hack fix for zone shutdown crashes on some servers
|
||||
if (!zone->IsLoaded())
|
||||
return nullptr;
|
||||
|
||||
if (RuleB(Aggro,SmartAggroList)){
|
||||
Mob* topClientTypeInRange = nullptr;
|
||||
int32 hateClientTypeInRange = -1;
|
||||
Mob* top_hate = nullptr;
|
||||
int32 hate = -1;
|
||||
|
||||
if (center == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (RuleB(Aggro, SmartAggroList)){
|
||||
Mob* top_client_type_in_range = nullptr;
|
||||
int32 hate_client_type_in_range = -1;
|
||||
int skipped_count = 0;
|
||||
|
||||
auto iterator = list.begin();
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
tHateEntry *cur = (*iterator);
|
||||
int16 aggroMod = 0;
|
||||
struct_HateList *cur = (*iterator);
|
||||
int16 aggro_mod = 0;
|
||||
|
||||
if(!cur){
|
||||
if (!cur){
|
||||
++iterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!cur->ent){
|
||||
if (!cur->entity_on_hatelist){
|
||||
++iterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto hateEntryPosition = xyz_location(cur->ent->GetX(), cur->ent->GetY(), cur->ent->GetZ());
|
||||
if(center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if(!zone->watermap->InLiquid(hateEntryPosition)) {
|
||||
auto hateEntryPosition = xyz_location(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ());
|
||||
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if (!zone->watermap->InLiquid(hateEntryPosition)) {
|
||||
skipped_count++;
|
||||
++iterator;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur->ent->Sanctuary()) {
|
||||
if(hate == -1)
|
||||
if (cur->entity_on_hatelist->Sanctuary()) {
|
||||
if (hate == -1)
|
||||
{
|
||||
top = cur->ent;
|
||||
top_hate = cur->entity_on_hatelist;
|
||||
hate = 1;
|
||||
}
|
||||
++iterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cur->ent->DivineAura() || cur->ent->IsMezzed() || cur->ent->IsFeared()){
|
||||
if(hate == -1)
|
||||
if (cur->entity_on_hatelist->DivineAura() || cur->entity_on_hatelist->IsMezzed() || cur->entity_on_hatelist->IsFeared()){
|
||||
if (hate == -1)
|
||||
{
|
||||
top = cur->ent;
|
||||
top_hate = cur->entity_on_hatelist;
|
||||
hate = 0;
|
||||
}
|
||||
++iterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
int32 currentHate = cur->hate;
|
||||
int32 current_hate = cur->stored_hate_amount;
|
||||
|
||||
if(cur->ent->IsClient()){
|
||||
if (cur->entity_on_hatelist->IsClient()){
|
||||
|
||||
if(cur->ent->CastToClient()->IsSitting()){
|
||||
aggroMod += RuleI(Aggro, SittingAggroMod);
|
||||
if (cur->entity_on_hatelist->CastToClient()->IsSitting()){
|
||||
aggro_mod += RuleI(Aggro, SittingAggroMod);
|
||||
}
|
||||
|
||||
if(center){
|
||||
if(center->GetTarget() == cur->ent)
|
||||
aggroMod += RuleI(Aggro, CurrentTargetAggroMod);
|
||||
if(RuleI(Aggro, MeleeRangeAggroMod) != 0)
|
||||
if (center){
|
||||
if (center->GetTarget() == cur->entity_on_hatelist)
|
||||
aggro_mod += RuleI(Aggro, CurrentTargetAggroMod);
|
||||
if (RuleI(Aggro, MeleeRangeAggroMod) != 0)
|
||||
{
|
||||
if(center->CombatRange(cur->ent)){
|
||||
aggroMod += RuleI(Aggro, MeleeRangeAggroMod);
|
||||
if (center->CombatRange(cur->entity_on_hatelist)){
|
||||
aggro_mod += RuleI(Aggro, MeleeRangeAggroMod);
|
||||
|
||||
if(currentHate > hateClientTypeInRange || cur->bFrenzy){
|
||||
hateClientTypeInRange = currentHate;
|
||||
topClientTypeInRange = cur->ent;
|
||||
if (current_hate > hate_client_type_in_range || cur->is_entity_frenzy){
|
||||
hate_client_type_in_range = current_hate;
|
||||
top_client_type_in_range = cur->entity_on_hatelist;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -361,113 +363,112 @@ Mob *HateList::GetTop(Mob *center)
|
||||
|
||||
}
|
||||
else{
|
||||
if(center){
|
||||
if(center->GetTarget() == cur->ent)
|
||||
aggroMod += RuleI(Aggro, CurrentTargetAggroMod);
|
||||
if(RuleI(Aggro, MeleeRangeAggroMod) != 0)
|
||||
if (center){
|
||||
if (center->GetTarget() == cur->entity_on_hatelist)
|
||||
aggro_mod += RuleI(Aggro, CurrentTargetAggroMod);
|
||||
if (RuleI(Aggro, MeleeRangeAggroMod) != 0)
|
||||
{
|
||||
if(center->CombatRange(cur->ent)){
|
||||
aggroMod += RuleI(Aggro, MeleeRangeAggroMod);
|
||||
if (center->CombatRange(cur->entity_on_hatelist)){
|
||||
aggro_mod += RuleI(Aggro, MeleeRangeAggroMod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cur->ent->GetMaxHP() != 0 && ((cur->ent->GetHP()*100/cur->ent->GetMaxHP()) < 20)){
|
||||
aggroMod += RuleI(Aggro, CriticallyWoundedAggroMod);
|
||||
if (cur->entity_on_hatelist->GetMaxHP() != 0 && ((cur->entity_on_hatelist->GetHP() * 100 / cur->entity_on_hatelist->GetMaxHP()) < 20)){
|
||||
aggro_mod += RuleI(Aggro, CriticallyWoundedAggroMod);
|
||||
}
|
||||
|
||||
if(aggroMod){
|
||||
currentHate += (currentHate * aggroMod / 100);
|
||||
if (aggro_mod){
|
||||
current_hate += (current_hate * aggro_mod / 100);
|
||||
}
|
||||
|
||||
if(currentHate > hate || cur->bFrenzy){
|
||||
hate = currentHate;
|
||||
top = cur->ent;
|
||||
if (current_hate > hate || cur->is_entity_frenzy){
|
||||
hate = current_hate;
|
||||
top_hate = cur->entity_on_hatelist;
|
||||
}
|
||||
|
||||
++iterator;
|
||||
}
|
||||
|
||||
if(topClientTypeInRange != nullptr && top != nullptr) {
|
||||
bool isTopClientType = top->IsClient();
|
||||
if (top_client_type_in_range != nullptr && top_hate != nullptr) {
|
||||
bool isTopClientType = top_hate->IsClient();
|
||||
#ifdef BOTS
|
||||
if(!isTopClientType) {
|
||||
if(top->IsBot()) {
|
||||
if (!isTopClientType) {
|
||||
if (top_hate->IsBot()) {
|
||||
isTopClientType = true;
|
||||
topClientTypeInRange = top;
|
||||
top_client_type_in_range = top_hate;
|
||||
}
|
||||
}
|
||||
#endif //BOTS
|
||||
|
||||
if(!isTopClientType) {
|
||||
if(top->IsMerc()) {
|
||||
if (!isTopClientType) {
|
||||
if (top_hate->IsMerc()) {
|
||||
isTopClientType = true;
|
||||
topClientTypeInRange = top;
|
||||
top_client_type_in_range = top_hate;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isTopClientType) {
|
||||
if (top->GetSpecialAbility(ALLOW_TO_TANK)){
|
||||
if (top_hate->GetSpecialAbility(ALLOW_TO_TANK)){
|
||||
isTopClientType = true;
|
||||
topClientTypeInRange = top;
|
||||
top_client_type_in_range = top_hate;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isTopClientType)
|
||||
return topClientTypeInRange ? topClientTypeInRange : nullptr;
|
||||
if (!isTopClientType)
|
||||
return top_client_type_in_range ? top_client_type_in_range : nullptr;
|
||||
|
||||
return top ? top : nullptr;
|
||||
return top_hate ? top_hate : nullptr;
|
||||
}
|
||||
else {
|
||||
if(top == nullptr && skipped_count > 0) {
|
||||
if (top_hate == nullptr && skipped_count > 0) {
|
||||
return center->GetTarget() ? center->GetTarget() : nullptr;
|
||||
}
|
||||
return top ? top : nullptr;
|
||||
return top_hate ? top_hate : nullptr;
|
||||
}
|
||||
}
|
||||
else{
|
||||
auto iterator = list.begin();
|
||||
int skipped_count = 0;
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
tHateEntry *cur = (*iterator);
|
||||
auto hateEntryPosition = xyz_location(cur->ent->GetX(), cur->ent->GetY(), cur->ent->GetZ());
|
||||
if(center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if(!zone->watermap->InLiquid(hateEntryPosition)) {
|
||||
struct_HateList *cur = (*iterator);
|
||||
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetPosition())) {
|
||||
skipped_count++;
|
||||
++iterator;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(cur->ent != nullptr && ((cur->hate > hate) || cur->bFrenzy ))
|
||||
if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy))
|
||||
{
|
||||
top = cur->ent;
|
||||
hate = cur->hate;
|
||||
top_hate = cur->entity_on_hatelist;
|
||||
hate = cur->stored_hate_amount;
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
if(top == nullptr && skipped_count > 0) {
|
||||
if (top_hate == nullptr && skipped_count > 0) {
|
||||
return center->GetTarget() ? center->GetTarget() : nullptr;
|
||||
}
|
||||
return top ? top : nullptr;
|
||||
return top_hate ? top_hate : nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mob *HateList::GetMostHate(){
|
||||
Mob *HateList::GetEntWithMostHateOnList(){
|
||||
Mob* top = nullptr;
|
||||
int32 hate = -1;
|
||||
|
||||
auto iterator = list.begin();
|
||||
while(iterator != list.end())
|
||||
while (iterator != list.end())
|
||||
{
|
||||
tHateEntry *cur = (*iterator);
|
||||
if(cur->ent != nullptr && (cur->hate > hate))
|
||||
struct_HateList *cur = (*iterator);
|
||||
if (cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate))
|
||||
{
|
||||
top = cur->ent;
|
||||
hate = cur->hate;
|
||||
top = cur->entity_on_hatelist;
|
||||
hate = cur->stored_hate_amount;
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
@ -475,16 +476,16 @@ Mob *HateList::GetMostHate(){
|
||||
}
|
||||
|
||||
|
||||
Mob *HateList::GetRandom()
|
||||
Mob *HateList::GetRandomEntOnHateList()
|
||||
{
|
||||
int count = list.size();
|
||||
if(count == 0) //If we don't have any entries it'll crash getting a random 0, -1 position.
|
||||
if (count == 0) //If we don't have any entries it'll crash getting a random 0, -1 position.
|
||||
return NULL;
|
||||
|
||||
if(count == 1) //No need to do all that extra work if we only have one hate entry
|
||||
if (count == 1) //No need to do all that extra work if we only have one hate entry
|
||||
{
|
||||
if(*list.begin()) // Just in case tHateEntry is invalidated somehow...
|
||||
return (*list.begin())->ent;
|
||||
if (*list.begin()) // Just in case tHateEntry is invalidated somehow...
|
||||
return (*list.begin())->entity_on_hatelist;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -494,38 +495,36 @@ Mob *HateList::GetRandom()
|
||||
for (int i = 0; i < random; i++)
|
||||
++iterator;
|
||||
|
||||
return (*iterator)->ent;
|
||||
return (*iterator)->entity_on_hatelist;
|
||||
}
|
||||
|
||||
int32 HateList::GetEntHate(Mob *ent, bool damage)
|
||||
int32 HateList::GetEntHateAmount(Mob *in_entity, bool damage)
|
||||
{
|
||||
tHateEntry *p;
|
||||
struct_HateList *entity;
|
||||
|
||||
p = Find(ent);
|
||||
entity = Find(in_entity);
|
||||
|
||||
if ( p && damage)
|
||||
return p->damage;
|
||||
else if (p)
|
||||
return p->hate;
|
||||
if (entity && damage)
|
||||
return entity->hatelist_damage;
|
||||
else if (entity)
|
||||
return entity->stored_hate_amount;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
//looking for any mob with hate > -1
|
||||
bool HateList::IsEmpty() {
|
||||
bool HateList::IsHateListEmpty() {
|
||||
return(list.size() == 0);
|
||||
}
|
||||
|
||||
// Prints hate list to a client
|
||||
void HateList::PrintToClient(Client *c)
|
||||
void HateList::PrintHateListToClient(Client *c)
|
||||
{
|
||||
auto iterator = list.begin();
|
||||
while (iterator != list.end())
|
||||
{
|
||||
tHateEntry *e = (*iterator);
|
||||
struct_HateList *e = (*iterator);
|
||||
c->Message(0, "- name: %s, damage: %d, hate: %d",
|
||||
(e->ent && e->ent->GetName()) ? e->ent->GetName() : "(null)",
|
||||
e->damage, e->hate);
|
||||
(e->entity_on_hatelist && e->entity_on_hatelist->GetName()) ? e->entity_on_hatelist->GetName() : "(null)",
|
||||
e->hatelist_damage, e->stored_hate_amount);
|
||||
|
||||
++iterator;
|
||||
}
|
||||
@ -533,7 +532,7 @@ void HateList::PrintToClient(Client *c)
|
||||
|
||||
int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts)
|
||||
{
|
||||
if(!target || !caster)
|
||||
if (!target || !caster)
|
||||
return 0;
|
||||
|
||||
int ret = 0;
|
||||
@ -541,25 +540,25 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
|
||||
auto iterator = list.begin();
|
||||
while (iterator != list.end())
|
||||
{
|
||||
tHateEntry *h = (*iterator);
|
||||
struct_HateList *h = (*iterator);
|
||||
++iterator;
|
||||
if(h && h->ent && h->ent != caster)
|
||||
if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster)
|
||||
{
|
||||
if(caster->CombatRange(h->ent))
|
||||
if (caster->CombatRange(h->entity_on_hatelist))
|
||||
{
|
||||
id_list.push_back(h->ent->GetID());
|
||||
id_list.push_back(h->entity_on_hatelist->GetID());
|
||||
++ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<uint32>::iterator iter = id_list.begin();
|
||||
while(iter != id_list.end())
|
||||
while (iter != id_list.end())
|
||||
{
|
||||
Mob *cur = entity_list.GetMobID((*iter));
|
||||
if(cur)
|
||||
if (cur)
|
||||
{
|
||||
for(int i = 0; i < count; ++i) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
caster->Attack(cur, MainPrimary, false, false, false, opts);
|
||||
}
|
||||
}
|
||||
@ -571,7 +570,7 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
|
||||
|
||||
void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_center)
|
||||
{
|
||||
if(!caster)
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
Mob* center = caster;
|
||||
@ -590,33 +589,32 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_cent
|
||||
auto iterator = list.begin();
|
||||
while (iterator != list.end())
|
||||
{
|
||||
tHateEntry *h = (*iterator);
|
||||
if(range > 0)
|
||||
struct_HateList *h = (*iterator);
|
||||
if (range > 0)
|
||||
{
|
||||
dist_targ = center->DistNoRoot(*h->ent);
|
||||
if(dist_targ <= range && dist_targ >= min_range2)
|
||||
dist_targ = center->DistNoRoot(*h->entity_on_hatelist);
|
||||
if (dist_targ <= range && dist_targ >= min_range2)
|
||||
{
|
||||
id_list.push_back(h->ent->GetID());
|
||||
h->ent->CalcSpellPowerDistanceMod(spell_id, dist_targ);
|
||||
id_list.push_back(h->entity_on_hatelist->GetID());
|
||||
h->entity_on_hatelist->CalcSpellPowerDistanceMod(spell_id, dist_targ);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
id_list.push_back(h->ent->GetID());
|
||||
h->ent->CalcSpellPowerDistanceMod(spell_id, 0, caster);
|
||||
id_list.push_back(h->entity_on_hatelist->GetID());
|
||||
h->entity_on_hatelist->CalcSpellPowerDistanceMod(spell_id, 0, caster);
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
|
||||
std::list<uint32>::iterator iter = id_list.begin();
|
||||
while(iter != id_list.end())
|
||||
while (iter != id_list.end())
|
||||
{
|
||||
Mob *cur = entity_list.GetMobID((*iter));
|
||||
if(cur)
|
||||
if (cur)
|
||||
{
|
||||
caster->SpellOnTarget(spell_id, cur);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
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 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.
|
||||
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
|
||||
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 HATELIST_H
|
||||
@ -25,11 +25,12 @@ class Mob;
|
||||
class Raid;
|
||||
struct ExtraAttackOptions;
|
||||
|
||||
struct tHateEntry
|
||||
struct struct_HateList
|
||||
{
|
||||
Mob *ent;
|
||||
int32 damage, hate;
|
||||
bool bFrenzy;
|
||||
Mob *entity_on_hatelist;
|
||||
int32 hatelist_damage;
|
||||
uint32 stored_hate_amount;
|
||||
bool is_entity_frenzy;
|
||||
};
|
||||
|
||||
class HateList
|
||||
@ -38,53 +39,38 @@ public:
|
||||
HateList();
|
||||
~HateList();
|
||||
|
||||
// adds a mob to the hatelist
|
||||
void Add(Mob *ent, int32 in_hate=0, int32 in_dam=0, bool bFrenzy = false, bool iAddIfNotExist = true);
|
||||
// sets existing hate
|
||||
void Set(Mob *other, uint32 in_hate, uint32 in_dam);
|
||||
// removes mobs from hatelist
|
||||
bool RemoveEnt(Mob *ent);
|
||||
// Remove all
|
||||
void Wipe();
|
||||
// ???
|
||||
void DoFactionHits(int32 nfl_id);
|
||||
// Gets Hate amount for mob
|
||||
int32 GetEntHate(Mob *ent, bool damage = false);
|
||||
// gets top hated mob
|
||||
Mob *GetTop(Mob *center);
|
||||
// gets any on the list
|
||||
Mob *GetRandom();
|
||||
// get closest mob or nullptr if list empty
|
||||
Mob *GetClosest(Mob *hater);
|
||||
// gets top mob or nullptr if hate list empty
|
||||
Mob *GetDamageTop(Mob *hater);
|
||||
// used to check if mob is on hatelist
|
||||
bool IsOnHateList(Mob *);
|
||||
// used to remove or add frenzy hate
|
||||
void CheckFrenzyHate();
|
||||
//Gets the target with the most hate regardless of things like frenzy etc.
|
||||
Mob* GetMostHate();
|
||||
// Count 'Summoned' pets on hatelist
|
||||
int SummonedPetCount(Mob *hater);
|
||||
Mob *GetClosestEntOnHateList(Mob *hater);
|
||||
Mob *GetDamageTopOnHateList(Mob *hater);
|
||||
Mob *GetEntWithMostHateOnList(Mob *center);
|
||||
Mob *GetRandomEntOnHateList();
|
||||
Mob* GetEntWithMostHateOnList();
|
||||
|
||||
bool IsEntOnHateList(Mob *mob);
|
||||
bool IsHateListEmpty();
|
||||
bool RemoveEntFromHateList(Mob *ent);
|
||||
|
||||
int AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts);
|
||||
int GetSummonedPetCountOnHateList(Mob *hater);
|
||||
|
||||
void SpellCast(Mob *caster, uint32 spell_id, float range, Mob *ae_center = nullptr);
|
||||
int32 GetEntHateAmount(Mob *ent, bool in_damage = false);
|
||||
|
||||
bool IsEmpty();
|
||||
void PrintToClient(Client *c);
|
||||
std::list<struct_HateList*>& GetHateList() { return list; }
|
||||
|
||||
//For accessing the hate list via perl; don't use for anything else
|
||||
std::list<tHateEntry*>& GetHateList() { return list; }
|
||||
void AddEntToHateList(Mob *ent, int32 in_hate = 0, int32 in_damage = 0, bool in_is_frenzied = false, bool add_to_hate_list_if_not_exist = true);
|
||||
void DoFactionHits(int32 npc_faction_level_id);
|
||||
void IsEntityInFrenzyMode();
|
||||
void PrintHateListToClient(Client *c);
|
||||
void SetHateAmountOnEnt(Mob *other, uint32 in_hate, uint32 in_damage);
|
||||
void SetHateOwner(Mob *new_hate_owner) { hate_owner = new_hate_owner; }
|
||||
void SpellCast(Mob *caster, uint32 spell_id, float range, Mob *ae_center = nullptr);
|
||||
void WipeHateList();
|
||||
|
||||
//setting owner
|
||||
void SetOwner(Mob *newOwner) { owner = newOwner; }
|
||||
|
||||
protected:
|
||||
tHateEntry* Find(Mob *ent);
|
||||
struct_HateList* Find(Mob *ent);
|
||||
private:
|
||||
std::list<tHateEntry*> list;
|
||||
Mob *owner;
|
||||
std::list<struct_HateList*> list;
|
||||
Mob *hate_owner;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -72,12 +72,12 @@ const NPCType *Horse::BuildHorseType(uint16 spell_id) {
|
||||
std::string query = StringFormat("SELECT race, gender, texture, mountspeed FROM horses WHERE filename = '%s'", fileName);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Mount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
LogFile->write(EQEmuLog::Error, "Error in Mount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1) {
|
||||
LogFile->write(EQEMuLog::Error, "No Database entry for mount: %s, check the horses table", fileName);
|
||||
LogFile->write(EQEmuLog::Error, "No Database entry for mount: %s, check the horses table", fileName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ void Client::SummonHorse(uint16 spell_id) {
|
||||
return;
|
||||
}
|
||||
if(!Horse::IsHorseSpell(spell_id)) {
|
||||
LogFile->write(EQEMuLog::Error, "%s tried to summon an unknown horse, spell id %d", GetName(), spell_id);
|
||||
LogFile->write(EQEmuLog::Error, "%s tried to summon an unknown horse, spell id %d", GetName(), spell_id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -532,7 +532,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
|
||||
if(inst == nullptr) {
|
||||
Message(13, "An unknown server error has occurred and your item was not created.");
|
||||
// this goes to logfile since this is a major error
|
||||
LogFile->write(EQEMuLog::Error, "Player %s on account %s encountered an unknown item creation error.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
|
||||
LogFile->write(EQEmuLog::Error, "Player %s on account %s encountered an unknown item creation error.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
|
||||
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
|
||||
|
||||
return false;
|
||||
@ -617,6 +617,7 @@ void Client::DropItem(int16 slot_id)
|
||||
|
||||
// Save client inventory change to database
|
||||
if (slot_id == MainCursor) {
|
||||
SendCursorBuffer();
|
||||
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
|
||||
database.SaveCursor(CharacterID(), s, e);
|
||||
} else {
|
||||
@ -678,10 +679,27 @@ int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
|
||||
return INVALID_ID;
|
||||
}
|
||||
|
||||
void Client::SendCursorBuffer() {
|
||||
// Temporary work-around for the RoF+ Client Buffer
|
||||
// Instead of dealing with client moving items in cursor buffer,
|
||||
// we can just send the next item in the cursor buffer to the cursor.
|
||||
if (GetClientVersion() >= EQClientRoF)
|
||||
{
|
||||
if (!GetInv().CursorEmpty())
|
||||
{
|
||||
const ItemInst* inst = GetInv().GetCursorItem();
|
||||
if (inst)
|
||||
{
|
||||
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove item from inventory
|
||||
void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_update, bool update_db) {
|
||||
#if (EQDEBUG >= 5)
|
||||
LogFile->write(EQEMuLog::Debug, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true":"false");
|
||||
LogFile->write(EQEmuLog::Debug, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true":"false");
|
||||
#endif
|
||||
|
||||
// Added 'IsSlotValid(slot_id)' check to both segments of client packet processing.
|
||||
@ -794,10 +812,6 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd
|
||||
}
|
||||
}
|
||||
|
||||
// Puts an item into the person's inventory
|
||||
// Any items already there will be removed from user's inventory
|
||||
// (Also saves changes back to the database: this may be optimized in the future)
|
||||
// client_update: Sends packet to client
|
||||
bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update)
|
||||
{
|
||||
mlog(INVENTORY__SLOTS, "Putting item %s (%d) on the cursor", inst.GetItem()->Name, inst.GetItem()->ID);
|
||||
@ -811,6 +825,10 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update)
|
||||
return database.SaveCursor(CharacterID(), s, e);
|
||||
}
|
||||
|
||||
// Puts an item into the person's inventory
|
||||
// Any items already there will be removed from user's inventory
|
||||
// (Also saves changes back to the database: this may be optimized in the future)
|
||||
// client_update: Sends packet to client
|
||||
bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update) {
|
||||
mlog(INVENTORY__SLOTS, "Putting item %s (%d) into slot %d", inst.GetItem()->Name, inst.GetItem()->ID, slot_id);
|
||||
|
||||
@ -908,7 +926,7 @@ bool Client::TryStacking(ItemInst* item, uint8 type, bool try_worn, bool try_cur
|
||||
bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_cursor, ServerLootItem_Struct** bag_item_data)
|
||||
{
|
||||
// #1: Try to auto equip
|
||||
if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel<=level && !inst.GetItem()->Attuneable && inst.GetItem()->ItemType != ItemTypeAugmentation)
|
||||
if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel<=level && (!inst.GetItem()->Attuneable || inst.IsAttuned()) && inst.GetItem()->ItemType != ItemTypeAugmentation)
|
||||
{
|
||||
// too messy as-is... <watch>
|
||||
for (int16 i = EmuConstants::EQUIPMENT_BEGIN; i < MainPowerSource; i++) // originally (i < 22)
|
||||
@ -1009,105 +1027,113 @@ void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type)
|
||||
}
|
||||
}
|
||||
|
||||
bool Client::MakeItemLink(char* &ret_link, const ItemInst *inst) {
|
||||
// TODO: needs clean-up to save references
|
||||
bool MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint8 evolving, uint8 evolvedlevel) {
|
||||
//we're sending back the entire "link", minus the null characters & item name
|
||||
//that way, we can use it for regular links & Task links
|
||||
//note: initiator needs to pass us ret_link
|
||||
|
||||
/*
|
||||
/*
|
||||
--- Usage ---
|
||||
Chat: "%c" "%s" "%s" "%c", 0x12, ret_link, inst->GetItem()->name, 0x12
|
||||
Task: "<a WndNotify=\"27," "%s" "\">" "%s" "</a>", ret_link, inst->GetItem()->name
|
||||
<a WndNotify="27,00960F000000000000000000000000000000000000000">Master's Book of Wood Elven Culture</a>
|
||||
http://eqitems.13th-floor.org/phpBB2/viewtopic.php?p=510#510
|
||||
*/
|
||||
<a WndNotify="27,00960F000000000000000000000000000000000000000">Master's Book of Wood Elven Culture</a>
|
||||
http://eqitems.13th-floor.org/phpBB2/viewtopic.php?p=510#510
|
||||
*/
|
||||
|
||||
if (!inst) //have to have an item to make the link
|
||||
if (!item) //have to have an item to make the link
|
||||
return false;
|
||||
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
//format:
|
||||
//0 itemid aug1 aug2 aug3 aug4 aug5 evolving? loregroup evolved level hash
|
||||
//0 00000 00000 00000 00000 00000 00000 0 0000 0 00000000
|
||||
//length:
|
||||
//1 5 5 5 5 5 5 1 4 1 8 = 45
|
||||
//evolving item info: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=145#558
|
||||
uint8 evolving = 0;
|
||||
uint16 loregroup = 0;
|
||||
uint8 evolvedlevel = 0;
|
||||
int hash = 0;
|
||||
|
||||
//int hash = GetItemLinkHash(inst); //eventually this will work (currently crashes zone), but for now we'll skip the extra overhead
|
||||
if (GetClientVersion() >= EQClientRoF2)
|
||||
{
|
||||
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%01X" "%1X" "%04X" "%1X" "%05X" "%08X",
|
||||
int hash = NOT_USED;
|
||||
|
||||
// Tested with UF and RoF..there appears to be a problem with using non-augment arguments below...
|
||||
// Currently, enabling them causes misalignments in what the client expects. I haven't looked
|
||||
// into it further to determine the cause..but, the function is setup to accept the parameters.
|
||||
// Note: some links appear with '00000' in front of the name..so, it's likely we need to send
|
||||
// some additional information when certain parameters are true -U
|
||||
//switch (GetClientVersion()) {
|
||||
switch (0) {
|
||||
case EQClientRoF2:
|
||||
// This operator contains 14 parameter masks..but, only 13 parameter values.
|
||||
// Even so, the client link appears ok... Need to figure out the discrepancy -U
|
||||
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%1X" "%04X" "%1X" "%05X" "%08X",
|
||||
0,
|
||||
item->ID,
|
||||
inst->GetAugmentItemID(0),
|
||||
inst->GetAugmentItemID(1),
|
||||
inst->GetAugmentItemID(2),
|
||||
inst->GetAugmentItemID(3),
|
||||
inst->GetAugmentItemID(4),
|
||||
inst->GetAugmentItemID(5),
|
||||
evolving,
|
||||
loregroup,
|
||||
evolvedlevel,
|
||||
aug0,
|
||||
aug1,
|
||||
aug2,
|
||||
aug3,
|
||||
aug4,
|
||||
aug5,
|
||||
0,//evolving,
|
||||
0,//item->LoreGroup,
|
||||
0,//evolvedlevel,
|
||||
0,
|
||||
hash
|
||||
);
|
||||
}
|
||||
else if (GetClientVersion() >= EQClientRoF)
|
||||
{
|
||||
return true;
|
||||
case EQClientRoF:
|
||||
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
|
||||
0,
|
||||
item->ID,
|
||||
inst->GetAugmentItemID(0),
|
||||
inst->GetAugmentItemID(1),
|
||||
inst->GetAugmentItemID(2),
|
||||
inst->GetAugmentItemID(3),
|
||||
inst->GetAugmentItemID(4),
|
||||
inst->GetAugmentItemID(5),
|
||||
evolving,
|
||||
loregroup,
|
||||
evolvedlevel,
|
||||
aug0,
|
||||
aug1,
|
||||
aug2,
|
||||
aug3,
|
||||
aug4,
|
||||
aug5,
|
||||
0,//evolving,
|
||||
0,//item->LoreGroup,
|
||||
0,//evolvedlevel,
|
||||
0,
|
||||
hash
|
||||
);
|
||||
}
|
||||
else if (GetClientVersion() >= EQClientSoF)
|
||||
{
|
||||
);
|
||||
return true;
|
||||
case EQClientUnderfoot:
|
||||
case EQClientSoD:
|
||||
case EQClientSoF:
|
||||
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
|
||||
0,
|
||||
item->ID,
|
||||
inst->GetAugmentItemID(0),
|
||||
inst->GetAugmentItemID(1),
|
||||
inst->GetAugmentItemID(2),
|
||||
inst->GetAugmentItemID(3),
|
||||
inst->GetAugmentItemID(4),
|
||||
evolving,
|
||||
loregroup,
|
||||
evolvedlevel,
|
||||
aug0,
|
||||
aug1,
|
||||
aug2,
|
||||
aug3,
|
||||
aug4,
|
||||
0,//evolving,
|
||||
0,//item->LoreGroup,
|
||||
0,//evolvedlevel,
|
||||
0,
|
||||
hash
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
);
|
||||
return true;
|
||||
case EQClientTitanium:
|
||||
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
|
||||
0,
|
||||
item->ID,
|
||||
inst->GetAugmentItemID(0),
|
||||
inst->GetAugmentItemID(1),
|
||||
inst->GetAugmentItemID(2),
|
||||
inst->GetAugmentItemID(3),
|
||||
inst->GetAugmentItemID(4),
|
||||
evolving,
|
||||
loregroup,
|
||||
evolvedlevel,
|
||||
aug0,
|
||||
aug1,
|
||||
aug2,
|
||||
aug3,
|
||||
aug4,
|
||||
0,//evolving,
|
||||
0,//item->LoreGroup,
|
||||
0,//evolvedlevel,
|
||||
hash
|
||||
);
|
||||
);
|
||||
return true;
|
||||
case EQClient62:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Client::GetItemLinkHash(const ItemInst* inst) {
|
||||
@ -1198,6 +1224,7 @@ int Client::GetItemLinkHash(const ItemInst* inst) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
// This appears to still be in use... The core of this should be incorporated into class Client::TextLink
|
||||
void Client::SendItemLink(const ItemInst* inst, bool send_to_all)
|
||||
{
|
||||
/*
|
||||
@ -1299,7 +1326,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
|
||||
// This could be expounded upon at some point to let the server know that
|
||||
// the client has moved a buffered cursor item onto the active cursor -U
|
||||
if (move_in->from_slot == move_in->to_slot) { // Item summon, no further proccessing needed
|
||||
if (move_in->from_slot == move_in->to_slot) { // Item summon, no further processing needed
|
||||
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
|
||||
return true;
|
||||
}
|
||||
@ -1315,13 +1342,15 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
}
|
||||
|
||||
DeleteItemInInventory(move_in->from_slot);
|
||||
SendCursorBuffer();
|
||||
|
||||
return true; // Item destroyed by client
|
||||
}
|
||||
else {
|
||||
mlog(INVENTORY__SLOTS, "Deleted item from slot %d as a result of an inventory container tradeskill combine.", move_in->from_slot);
|
||||
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
|
||||
DeleteItemInInventory(move_in->from_slot);
|
||||
return true; // Item deletetion
|
||||
return true; // Item deletion
|
||||
}
|
||||
}
|
||||
if(auto_attack && (move_in->from_slot == MainPrimary || move_in->from_slot == MainSecondary || move_in->from_slot == MainRange))
|
||||
@ -1363,7 +1392,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
//SetTint(dst_slot_id,src_inst->GetColor());
|
||||
if (src_inst->GetCharges() > 0 && (src_inst->GetCharges() < (int16)move_in->number_in_stack || move_in->number_in_stack > src_inst->GetItem()->StackSize))
|
||||
{
|
||||
Message(13,"Error: Insufficent number in stack.");
|
||||
Message(13,"Error: Insufficient number in stack.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1413,7 +1442,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
//verify shared bank transactions in the database
|
||||
if(src_inst && src_slot_id >= EmuConstants::SHARED_BANK_BEGIN && src_slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
|
||||
if(!database.VerifyInventory(account_id, src_slot_id, src_inst)) {
|
||||
LogFile->write(EQEMuLog::Error, "Player %s on account %s was found exploiting the shared bank.\n", GetName(), account_name);
|
||||
LogFile->write(EQEmuLog::Error, "Player %s on account %s was found exploiting the shared bank.\n", GetName(), account_name);
|
||||
DeleteItemInInventory(dst_slot_id,0,true);
|
||||
return(false);
|
||||
}
|
||||
@ -1428,7 +1457,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
}
|
||||
if(dst_inst && dst_slot_id >= EmuConstants::SHARED_BANK_BEGIN && dst_slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
|
||||
if(!database.VerifyInventory(account_id, dst_slot_id, dst_inst)) {
|
||||
LogFile->write(EQEMuLog::Error, "Player %s on account %s was found exploting the shared bank.\n", GetName(), account_name);
|
||||
LogFile->write(EQEmuLog::Error, "Player %s on account %s was found exploting the shared bank.\n", GetName(), account_name);
|
||||
DeleteItemInInventory(src_slot_id,0,true);
|
||||
return(false);
|
||||
}
|
||||
@ -1520,11 +1549,19 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
}
|
||||
|
||||
safe_delete(world_inst);
|
||||
if (src_slot_id == MainCursor) {
|
||||
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
|
||||
if (src_slot_id == MainCursor)
|
||||
{
|
||||
if (dstitemid == 0)
|
||||
{
|
||||
SendCursorBuffer();
|
||||
}
|
||||
std::list<ItemInst*>::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end();
|
||||
database.SaveCursor(character_id, s, e);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
database.SaveInventory(character_id, m_inv[src_slot_id], src_slot_id);
|
||||
}
|
||||
|
||||
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in, true); } // QS Audit
|
||||
|
||||
@ -1551,6 +1588,10 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
|
||||
|
||||
trade->AddEntity(dst_slot_id, move_in->number_in_stack);
|
||||
if (dstitemid == 0)
|
||||
{
|
||||
SendCursorBuffer();
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@ -1563,6 +1604,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
}
|
||||
}
|
||||
|
||||
bool all_to_stack = false;
|
||||
// Step 5: Swap (or stack) items
|
||||
if (move_in->number_in_stack > 0) {
|
||||
// Determine if charged items can stack
|
||||
@ -1593,6 +1635,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
mlog(INVENTORY__SLOTS, "Dest (%d) now has %d charges, source (%d) was entirely consumed. (%d moved)", dst_slot_id, dst_inst->GetCharges(), src_slot_id, usedcharges);
|
||||
database.SaveInventory(CharacterID(),nullptr,src_slot_id);
|
||||
m_inv.DeleteItem(src_slot_id);
|
||||
all_to_stack = true;
|
||||
} else {
|
||||
mlog(INVENTORY__SLOTS, "Dest (%d) now has %d charges, source (%d) has %d (%d moved)", dst_slot_id, dst_inst->GetCharges(), src_slot_id, src_inst->GetCharges(), usedcharges);
|
||||
}
|
||||
@ -1666,6 +1709,11 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
|
||||
// Step 7: Save change to the database
|
||||
if (src_slot_id == MainCursor){
|
||||
// If not swapping another item to cursor and stacking items were depleted
|
||||
if (dstitemid == 0 || all_to_stack == true)
|
||||
{
|
||||
SendCursorBuffer();
|
||||
}
|
||||
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
|
||||
database.SaveCursor(character_id, s, e);
|
||||
} else
|
||||
@ -1968,7 +2016,7 @@ void Client::DyeArmor(DyeStruct* dye){
|
||||
|
||||
bool Client::DecreaseByID(uint32 type, uint8 amt) {
|
||||
const Item_Struct* TempItem = 0;
|
||||
ItemInst* ins;
|
||||
ItemInst* ins = nullptr;
|
||||
int x;
|
||||
int num = 0;
|
||||
for(x = EmuConstants::EQUIPMENT_BEGIN; x <= EmuConstants::GENERAL_BAGS_END; x++)
|
||||
@ -2104,6 +2152,7 @@ void Client::RemoveNoRent(bool client_update) {
|
||||
std::list<ItemInst*>::iterator iter = local.begin();
|
||||
while (iter != local.end()) {
|
||||
inst = *iter;
|
||||
// should probably put a check here for valid pointer..but, that was checked when the item was put into inventory -U
|
||||
if (!inst->GetItem()->NoRent)
|
||||
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from `Limbo`", inst->GetItem()->Name);
|
||||
else
|
||||
@ -2229,6 +2278,7 @@ void Client::RemoveDuplicateLore(bool client_update) {
|
||||
std::list<ItemInst*>::iterator iter = local.begin();
|
||||
while (iter != local.end()) {
|
||||
inst = *iter;
|
||||
// probably needs a valid pointer check -U
|
||||
if (CheckLoreConflict(inst->GetItem())) {
|
||||
mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name);
|
||||
safe_delete(*iter);
|
||||
@ -2431,8 +2481,8 @@ void Client::CreateBandolier(const EQApplicationPacket *app) {
|
||||
_log(INVENTORY__BANDOLIER, "Char: %s Creating Bandolier Set %i, Set Name: %s", GetName(), bs->number, bs->name);
|
||||
strcpy(m_pp.bandoliers[bs->number].name, bs->name);
|
||||
|
||||
const ItemInst* InvItem;
|
||||
const Item_Struct *BaseItem;
|
||||
const ItemInst* InvItem = nullptr;
|
||||
const Item_Struct *BaseItem = nullptr;
|
||||
int16 WeaponSlot;
|
||||
|
||||
for(int BandolierSlot = bandolierMainHand; BandolierSlot <= bandolierAmmo; BandolierSlot++) {
|
||||
|
||||
@ -145,7 +145,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
drop_chance = zone->random.Real(0.0, 100.0);
|
||||
|
||||
#if EQDEBUG>=11
|
||||
LogFile->write(EQEMuLog::Debug, "Drop chance for npc: %s, this chance:%f, drop roll:%f", npc->GetName(), thischance, drop_chance);
|
||||
LogFile->write(EQEmuLog::Debug, "Drop chance for npc: %s, this chance:%f, drop roll:%f", npc->GetName(), thischance, drop_chance);
|
||||
#endif
|
||||
if (thischance == 100.0 || drop_chance < thischance)
|
||||
{
|
||||
@ -187,7 +187,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
|
||||
ServerLootItem_Struct* item = new ServerLootItem_Struct;
|
||||
#if EQDEBUG>=11
|
||||
LogFile->write(EQEMuLog::Debug, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID);
|
||||
LogFile->write(EQEmuLog::Debug, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID);
|
||||
#endif
|
||||
|
||||
EQApplicationPacket* outapp = nullptr;
|
||||
@ -324,7 +324,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
what was this about???
|
||||
|
||||
if (((npc->GetRace()==127) && (npc->CastToMob()->GetOwnerID()!=0)) && (item2->Slots==24576) || (item2->Slots==8192) || (item2->Slots==16384)){
|
||||
npc->d_meele_texture2=atoi(newid);
|
||||
npc->d_melee_texture2=atoi(newid);
|
||||
wc->wear_slot_id=8;
|
||||
if (item2->Material >0)
|
||||
wc->material=item2->Material;
|
||||
|
||||
@ -1354,8 +1354,8 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
|
||||
LuaCreateNPCParse(max_dmg, uint32, 4);
|
||||
LuaCreateNPCParse(attack_count, int16, 0);
|
||||
LuaCreateNPCParseString(special_abilities, 512, "");
|
||||
LuaCreateNPCParse(d_meele_texture1, uint16, 0);
|
||||
LuaCreateNPCParse(d_meele_texture2, uint16, 0);
|
||||
LuaCreateNPCParse(d_melee_texture1, uint16, 0);
|
||||
LuaCreateNPCParse(d_melee_texture2, uint16, 0);
|
||||
LuaCreateNPCParseString(ammo_idfile, 32, "");
|
||||
LuaCreateNPCParse(prim_melee_type, uint8, 0);
|
||||
LuaCreateNPCParse(sec_melee_type, uint8, 0);
|
||||
|
||||
@ -12,42 +12,42 @@
|
||||
|
||||
Lua_Mob Lua_HateEntry::GetEnt() {
|
||||
Lua_Safe_Call_Class(Lua_Mob);
|
||||
return Lua_Mob(self->ent);
|
||||
return Lua_Mob(self->entity_on_hatelist);
|
||||
}
|
||||
|
||||
void Lua_HateEntry::SetEnt(Lua_Mob e) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ent = e;
|
||||
self->entity_on_hatelist = e;
|
||||
}
|
||||
|
||||
int Lua_HateEntry::GetDamage() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->damage;
|
||||
return self->hatelist_damage;
|
||||
}
|
||||
|
||||
void Lua_HateEntry::SetDamage(int value) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->damage = value;
|
||||
self->hatelist_damage = value;
|
||||
}
|
||||
|
||||
int Lua_HateEntry::GetHate() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->hate;
|
||||
return self->stored_hate_amount;
|
||||
}
|
||||
|
||||
void Lua_HateEntry::SetHate(int value) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->hate = value;
|
||||
self->stored_hate_amount = value;
|
||||
}
|
||||
|
||||
int Lua_HateEntry::GetFrenzy() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->bFrenzy;
|
||||
return self->is_entity_frenzy;
|
||||
}
|
||||
|
||||
void Lua_HateEntry::SetFrenzy(bool value) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->bFrenzy = value;
|
||||
self->is_entity_frenzy = value;
|
||||
}
|
||||
|
||||
luabind::scope lua_register_hate_entry() {
|
||||
|
||||
@ -5,17 +5,17 @@
|
||||
#include "lua_ptr.h"
|
||||
|
||||
class Lua_Mob;
|
||||
struct tHateEntry;
|
||||
struct struct_HateList;
|
||||
|
||||
luabind::scope lua_register_hate_entry();
|
||||
luabind::scope lua_register_hate_list();
|
||||
|
||||
class Lua_HateEntry : public Lua_Ptr<tHateEntry>
|
||||
class Lua_HateEntry : public Lua_Ptr<struct_HateList>
|
||||
{
|
||||
typedef tHateEntry NativeType;
|
||||
typedef struct_HateList NativeType;
|
||||
public:
|
||||
Lua_HateEntry() : Lua_Ptr(nullptr) { }
|
||||
Lua_HateEntry(tHateEntry *d) : Lua_Ptr(d) { }
|
||||
Lua_HateEntry(struct_HateList *d) : Lua_Ptr(d) { }
|
||||
virtual ~Lua_HateEntry() { }
|
||||
|
||||
Lua_Mob GetEnt();
|
||||
|
||||
@ -576,6 +576,11 @@ int Lua_Mob::GetCorruption() {
|
||||
return self->GetCorrup();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetPhR() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetPhR();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetMaxSTR() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMaxSTR();
|
||||
@ -895,17 +900,17 @@ void Lua_Mob::AddToHateList(Lua_Mob other, int hate, int damage, bool yell_for_h
|
||||
|
||||
void Lua_Mob::SetHate(Lua_Mob other) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetHate(other);
|
||||
self->SetHateAmountOnEnt(other);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetHate(Lua_Mob other, int hate) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetHate(other, hate);
|
||||
self->SetHateAmountOnEnt(other, hate);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetHate(Lua_Mob other, int hate, int damage) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetHate(other, hate, damage);
|
||||
self->SetHateAmountOnEnt(other, hate, damage);
|
||||
}
|
||||
|
||||
void Lua_Mob::HalveAggro(Lua_Mob other) {
|
||||
@ -1962,6 +1967,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetPR", &Lua_Mob::GetPR)
|
||||
.def("GetCR", &Lua_Mob::GetCR)
|
||||
.def("GetCorruption", &Lua_Mob::GetCorruption)
|
||||
.def("GetPhR", &Lua_Mob::GetPhR)
|
||||
.def("GetMaxSTR", &Lua_Mob::GetMaxSTR)
|
||||
.def("GetMaxSTA", &Lua_Mob::GetMaxSTA)
|
||||
.def("GetMaxDEX", &Lua_Mob::GetMaxDEX)
|
||||
|
||||
@ -128,6 +128,7 @@ public:
|
||||
int GetPR();
|
||||
int GetCR();
|
||||
int GetCorruption();
|
||||
int GetPhR();
|
||||
int GetMaxSTR();
|
||||
int GetMaxSTA();
|
||||
int GetMaxDEX();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user