diff --git a/changelog.txt b/changelog.txt index 01ddc4625..0091a7583 100644 --- a/changelog.txt +++ b/changelog.txt @@ -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 diff --git a/client_files/export/main.cpp b/client_files/export/main.cpp index e9b127aad..8bf6827d4 100644 --- a/client_files/export/main.cpp +++ b/client_files/export/main.cpp @@ -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); diff --git a/client_files/import/main.cpp b/client_files/import/main.cpp index 9683e3bfe..7617248d0 100644 --- a/client_files/import/main.cpp +++ b/client_files/import/main.cpp @@ -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; } diff --git a/common/crash.cpp b/common/crash.cpp index 5ce1229a5..cd7389c09 100644 --- a/common/crash.cpp +++ b/common/crash.cpp @@ -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; } diff --git a/common/database.cpp b/common/database.cpp index 3de2a308b..d6dcd7405 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -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 &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; } diff --git a/common/debug.cpp b/common/debug.cpp index 3b283240a..ce56ebcbb 100644 --- a/common/debug.cpp +++ b/common/debug.cpp @@ -9,6 +9,31 @@ #define strncasecmp _strnicmp #define strcasecmp _stricmp + #include + #include + #include + +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 @@ -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; diff --git a/common/debug.h b/common/debug.h index 5e2fff368..da97fb0de 100644 --- a/common/debug.h +++ b/common/debug.h @@ -74,10 +74,10 @@ #include -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 { diff --git a/common/eq_dictionary.h b/common/eq_dictionary.h index 43511072f..3438f133b 100644 --- a/common/eq_dictionary.h +++ b/common/eq_dictionary.h @@ -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 diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index cec29178d..0c91d96f8 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -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 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() diff --git a/common/eq_stream.cpp b/common/eq_stream.cpp index 594f3b5bc..3e89e2fc3 100644 --- a/common/eq_stream.cpp +++ b/common/eq_stream.cpp @@ -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); diff --git a/common/eqtime.cpp b/common/eqtime.cpp index 7e1eb9f5d..bff36bc4c 100644 --- a/common/eqtime.cpp +++ b/common/eqtime.cpp @@ -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; diff --git a/common/guild_base.cpp b/common/guild_base.cpp index 06e108534..f1db14af7 100644 --- a/common/guild_base.cpp +++ b/common/guild_base.cpp @@ -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; } diff --git a/common/item.cpp b/common/item.cpp index 1b99ad779..7f6e049d6 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -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& 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& 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& 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; diff --git a/common/item.h b/common/item.h index b0aa06466..03182e4dd 100644 --- a/common/item.h +++ b/common/item.h @@ -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(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); diff --git a/common/logsys_eqemu.cpp b/common/logsys_eqemu.cpp index b5f846b4a..f91de2cea 100644 --- a/common/logsys_eqemu.cpp +++ b/common/logsys_eqemu.cpp @@ -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); } diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index ad6fb95d6..f65302c36 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -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 diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index a750d2abb..03d919dd8 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -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 diff --git a/common/patches/rof2_constants.h b/common/patches/rof2_constants.h index 596ffa7e7..b4cbb15e0 100644 --- a/common/patches/rof2_constants.h +++ b/common/patches/rof2_constants.h @@ -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 { diff --git a/common/patches/rof2_ops.h b/common/patches/rof2_ops.h index 19519212a..66b86d756 100644 --- a/common/patches/rof2_ops.h +++ b/common/patches/rof2_ops.h @@ -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) diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index 6776ff0e7..baf067bbf 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -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; diff --git a/common/patches/rof_constants.h b/common/patches/rof_constants.h index 97cb25aa5..233a1b36c 100644 --- a/common/patches/rof_constants.h +++ b/common/patches/rof_constants.h @@ -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 { diff --git a/common/patches/rof_ops.h b/common/patches/rof_ops.h index 878870a81..ef97dda99 100644 --- a/common/patches/rof_ops.h +++ b/common/patches/rof_ops.h @@ -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) diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index c84a670a9..fb2f09615 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -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 diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 50d787472..6982290c8 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -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 diff --git a/common/patches/sod_constants.h b/common/patches/sod_constants.h index 8bdf45532..89749fd56 100644 --- a/common/patches/sod_constants.h +++ b/common/patches/sod_constants.h @@ -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 { diff --git a/common/patches/sod_ops.h b/common/patches/sod_ops.h index 038b42e08..0a0a8a4d5 100644 --- a/common/patches/sod_ops.h +++ b/common/patches/sod_ops.h @@ -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) diff --git a/common/patches/sod_structs.h b/common/patches/sod_structs.h index 7ec101fd3..24ed9c7cc 100644 --- a/common/patches/sod_structs.h +++ b/common/patches/sod_structs.h @@ -4409,7 +4409,6 @@ struct MercenaryAssign_Struct { /*0012*/ }; - }; //end namespace structs }; //end namespace SoD diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index f7d35d403..8405f9def 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -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 diff --git a/common/patches/sof_constants.h b/common/patches/sof_constants.h index 0b959ef3a..5e0f4b18a 100644 --- a/common/patches/sof_constants.h +++ b/common/patches/sof_constants.h @@ -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 { diff --git a/common/patches/sof_ops.h b/common/patches/sof_ops.h index 132e3dc77..9cfd400e3 100644 --- a/common/patches/sof_ops.h +++ b/common/patches/sof_ops.h @@ -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) diff --git a/common/patches/sof_structs.h b/common/patches/sof_structs.h index 385fd8b46..4e84998b7 100644 --- a/common/patches/sof_structs.h +++ b/common/patches/sof_structs.h @@ -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_*/ - - - - - - - - - - diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 26ab0f531..f40c0266c 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -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 diff --git a/common/patches/titanium_constants.h b/common/patches/titanium_constants.h index 85e525fe8..ff44513c2 100644 --- a/common/patches/titanium_constants.h +++ b/common/patches/titanium_constants.h @@ -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 { diff --git a/common/patches/titanium_ops.h b/common/patches/titanium_ops.h index 338558602..4ddcae630 100644 --- a/common/patches/titanium_ops.h +++ b/common/patches/titanium_ops.h @@ -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) diff --git a/common/patches/titanium_structs.h b/common/patches/titanium_structs.h index b9d299ab9..7d21ba998 100644 --- a/common/patches/titanium_structs.h +++ b/common/patches/titanium_structs.h @@ -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_*/ - - - - - - - - - - diff --git a/common/patches/underfoot.cpp b/common/patches/underfoot.cpp index 3ddfeafd0..1ebd8dc8d 100644 --- a/common/patches/underfoot.cpp +++ b/common/patches/underfoot.cpp @@ -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 diff --git a/common/patches/underfoot_constants.h b/common/patches/underfoot_constants.h index b89a4f255..a656c56eb 100644 --- a/common/patches/underfoot_constants.h +++ b/common/patches/underfoot_constants.h @@ -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 { diff --git a/common/patches/underfoot_ops.h b/common/patches/underfoot_ops.h index cfb4d4fe9..61f4f1c0f 100644 --- a/common/patches/underfoot_ops.h +++ b/common/patches/underfoot_ops.h @@ -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) diff --git a/common/ptimer.cpp b/common/ptimer.cpp index b39f37a04..bd753d391 100644 --- a/common/ptimer.cpp +++ b/common/ptimer.cpp @@ -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; } diff --git a/common/rulesys.cpp b/common/rulesys.cpp index 95f22754c..ae1b8e5f6 100644 --- a/common/rulesys.cpp +++ b/common/rulesys.cpp @@ -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 &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; } diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 7dff17b43..c036fb5de 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -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(reinterpret_cast(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(reinterpret_cast(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; } diff --git a/common/timeoutmgr.cpp b/common/timeoutmgr.cpp index ca436b093..771ce16af 100644 --- a/common/timeoutmgr.cpp +++ b/common/timeoutmgr.cpp @@ -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::iterator cur,end; cur = members.begin(); diff --git a/common/timer.cpp b/common/timer.cpp index c1c94a7f6..d5a90a0f2 100644 --- a/common/timer.cpp +++ b/common/timer.cpp @@ -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() diff --git a/common/timer.h b/common/timer.h index 1e3ab97e0..c4d89fe11 100644 --- a/common/timer.h +++ b/common/timer.h @@ -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); } diff --git a/common/version.h b/common/version.h index 461c26e23..48a600be1 100644 --- a/common/version.h +++ b/common/version.h @@ -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 diff --git a/luabind/luabind/object.hpp b/luabind/luabind/object.hpp index ea12bf272..0feb7bd48 100644 --- a/luabind/luabind/object.hpp +++ b/luabind/luabind/object.hpp @@ -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 diff --git a/queryserv/database.cpp b/queryserv/database.cpp index 4f7fdf10f..56e09e238 100644 --- a/queryserv/database.cpp +++ b/queryserv/database.cpp @@ -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; } } diff --git a/shared_memory/main.cpp b/shared_memory/main.cpp index 8cc554441..b9ee32929 100644 --- a/shared_memory/main.cpp +++ b/shared_memory/main.cpp @@ -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; } } diff --git a/ucs/database.cpp b/ucs/database.cpp index 8130585d1..09e4389b7 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -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; } } diff --git a/utils/patches/patch_RoF2.conf b/utils/patches/patch_RoF2.conf index 88ae7ab31..23bec152e 100644 --- a/utils/patches/patch_RoF2.conf +++ b/utils/patches/patch_RoF2.conf @@ -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 diff --git a/utils/scripts/db_update.pl b/utils/scripts/db_update.pl index bf92ce60f..be1285fe4 100644 --- a/utils/scripts/db_update.pl +++ b/utils/scripts/db_update.pl @@ -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... diff --git a/utils/scripts/parse_crashes.pl b/utils/scripts/parse_crashes.pl new file mode 100644 index 000000000..667a19b81 --- /dev/null +++ b/utils/scripts/parse_crashes.pl @@ -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++; +} \ No newline at end of file diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 432d97183..1ba3048b8 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -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 diff --git a/utils/sql/git/required/2014_12_24_npc_types_table_update.sql b/utils/sql/git/required/2014_12_24_npc_types_table_update.sql new file mode 100644 index 000000000..c65749b36 --- /dev/null +++ b/utils/sql/git/required/2014_12_24_npc_types_table_update.sql @@ -0,0 +1 @@ +ALTER TABLE `npc_types` ADD `herosforgemodel` int( 11 ) NOT NULL DEFAULT '0' AFTER `helmtexture`; \ No newline at end of file diff --git a/utils/sql/git/required/2014_12_24_npc_types_update.sql b/utils/sql/git/required/2014_12_24_npc_types_update.sql new file mode 100644 index 000000000..a44d15c2d --- /dev/null +++ b/utils/sql/git/required/2014_12_24_npc_types_update.sql @@ -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; \ No newline at end of file diff --git a/utils/sql/git/required/2014_12_26_merc_weaponinfo_table_update.sql b/utils/sql/git/required/2014_12_26_merc_weaponinfo_table_update.sql new file mode 100644 index 000000000..3c8d291bb --- /dev/null +++ b/utils/sql/git/required/2014_12_26_merc_weaponinfo_table_update.sql @@ -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; \ No newline at end of file diff --git a/utils/sql/git/required/2014_12_31_npc_types_default_values_update.sql b/utils/sql/git/required/2014_12_31_npc_types_default_values_update.sql new file mode 100644 index 000000000..b75544981 --- /dev/null +++ b/utils/sql/git/required/2014_12_31_npc_types_default_values_update.sql @@ -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'; diff --git a/world/adventure.cpp b/world/adventure.cpp index b6db3d6d0..c6272cb31 100644 --- a/world/adventure.cpp +++ b/world/adventure.cpp @@ -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(); diff --git a/world/adventure_manager.cpp b/world/adventure_manager.cpp index 47ea42c51..4a6756d5e 100644 --- a/world/adventure_manager.cpp +++ b/world/adventure_manager.cpp @@ -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; } diff --git a/world/eql_config.cpp b/world/eql_config.cpp index f99ba0fb6..65d4a5f11 100644 --- a/world/eql_config.cpp +++ b/world/eql_config.cpp @@ -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; } diff --git a/world/world_logsys.cpp b/world/world_logsys.cpp index 351af9767..3cfada073 100644 --- a/world/world_logsys.cpp +++ b/world/world_logsys.cpp @@ -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, ...) { diff --git a/world/worlddb.cpp b/world/worlddb.cpp index e65a3a338..91406b527 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -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 &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; } diff --git a/zone/aa.cpp b/zone/aa.cpp index 5c4a7546d..0f94b8c72 100644 --- a/zone/aa.cpp +++ b/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; } diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 3e833aad9..b2b3881bb 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -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; } diff --git a/zone/attack.cpp b/zone/attack.cpp index 30e653745..18f5c11e2 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -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); } } diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index b9f35c9ff..a47c1f38b 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1420,7 +1420,7 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon) if (GetClass() == BARD) newbon->ManaRegen = 0; // Bards do not get mana regen from spells. } -void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* newbon, uint16 casterId, bool item_bonus, uint32 ticsremaining, int buffslot, +void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* new_bonus, uint16 casterId, bool item_bonus, uint32 ticsremaining, int buffslot, bool IsAISpellEffect, uint16 effect_id, int32 se_base, int32 se_limit, int32 se_max) { int i, effect_value, base2, max, effectid; @@ -1443,7 +1443,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne uint8 focus = IsFocusEffect(spell_id, i); if (focus) { - newbon->FocusEffects[focus] = spells[spell_id].effectid[i]; + new_bonus->FocusEffects[focus] = spells[spell_id].effectid[i]; continue; } @@ -1466,20 +1466,20 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { case SE_CurrentHP: //regens if(effect_value > 0) { - newbon->HPRegen += effect_value; + new_bonus->HPRegen += effect_value; } break; case SE_CurrentEndurance: - newbon->EnduranceRegen += effect_value; + new_bonus->EnduranceRegen += effect_value; break; case SE_ChangeFrenzyRad: { // redundant to have level check here - if(newbon->AggroRange == -1 || effect_value < newbon->AggroRange) + if(new_bonus->AggroRange == -1 || effect_value < new_bonus->AggroRange) { - newbon->AggroRange = static_cast(effect_value); + new_bonus->AggroRange = static_cast(effect_value); } break; } @@ -1489,9 +1489,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne // Harmony effect as buff - kinda tricky // harmony could stack with a lull spell, which has better aggro range // take the one with less range in any case - if(newbon->AssistRange == -1 || effect_value < newbon->AssistRange) + if(new_bonus->AssistRange == -1 || effect_value < new_bonus->AssistRange) { - newbon->AssistRange = static_cast(effect_value); + new_bonus->AssistRange = static_cast(effect_value); } break; } @@ -1499,16 +1499,16 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_AttackSpeed: { if ((effect_value - 100) > 0) { // Haste - if (newbon->haste < 0) break; // Slowed - Don't apply haste - if ((effect_value - 100) > newbon->haste) { - newbon->haste = effect_value - 100; + if (new_bonus->haste < 0) break; // Slowed - Don't apply haste + if ((effect_value - 100) > new_bonus->haste) { + new_bonus->haste = effect_value - 100; } } else if ((effect_value - 100) < 0) { // Slow int real_slow_value = (100 - effect_value) * -1; real_slow_value -= ((real_slow_value * GetSlowMitigation()/100)); - if (real_slow_value < newbon->haste) - newbon->haste = real_slow_value; + if (real_slow_value < new_bonus->haste) + new_bonus->haste = real_slow_value; } break; } @@ -1516,16 +1516,16 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_AttackSpeed2: { if ((effect_value - 100) > 0) { // Haste V2 - Stacks with V1 but does not Overcap - if (newbon->hastetype2 < 0) break; //Slowed - Don't apply haste2 - if ((effect_value - 100) > newbon->hastetype2) { - newbon->hastetype2 = effect_value - 100; + if (new_bonus->hastetype2 < 0) break; //Slowed - Don't apply haste2 + if ((effect_value - 100) > new_bonus->hastetype2) { + new_bonus->hastetype2 = effect_value - 100; } } else if ((effect_value - 100) < 0) { // Slow int real_slow_value = (100 - effect_value) * -1; real_slow_value -= ((real_slow_value * GetSlowMitigation()/100)); - if (real_slow_value < newbon->hastetype2) - newbon->hastetype2 = real_slow_value; + if (real_slow_value < new_bonus->hastetype2) + new_bonus->hastetype2 = real_slow_value; } break; } @@ -1534,13 +1534,13 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { if (effect_value < 0){ //Slow effect_value -= ((effect_value * GetSlowMitigation()/100)); - if (effect_value < newbon->hastetype3) - newbon->hastetype3 = effect_value; + if (effect_value < new_bonus->hastetype3) + new_bonus->hastetype3 = effect_value; } else if (effect_value > 0) { // Haste V3 - Stacks and Overcaps - if (effect_value > newbon->hastetype3) { - newbon->hastetype3 = effect_value; + if (effect_value > new_bonus->hastetype3) { + new_bonus->hastetype3 = effect_value; } } break; @@ -1556,10 +1556,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne if (effect_value < 0) //A few spells use negative values(Descriptions all indicate it should be a slow) effect_value = effect_value * -1; - if (effect_value > 0 && effect_value > newbon->inhibitmelee) { + if (effect_value > 0 && effect_value > new_bonus->inhibitmelee) { effect_value -= ((effect_value * GetSlowMitigation()/100)); - if (effect_value > newbon->inhibitmelee) - newbon->inhibitmelee = effect_value; + if (effect_value > new_bonus->inhibitmelee) + new_bonus->inhibitmelee = effect_value; } break; @@ -1567,141 +1567,141 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_TotalHP: { - newbon->HP += effect_value; + new_bonus->HP += effect_value; break; } case SE_ManaRegen_v2: case SE_CurrentMana: { - newbon->ManaRegen += effect_value; + new_bonus->ManaRegen += effect_value; break; } case SE_ManaPool: { - newbon->Mana += effect_value; + new_bonus->Mana += effect_value; break; } case SE_Stamina: { - newbon->EnduranceReduction += effect_value; + new_bonus->EnduranceReduction += effect_value; break; } case SE_ACv2: case SE_ArmorClass: { - newbon->AC += effect_value; + new_bonus->AC += effect_value; break; } case SE_ATK: { - newbon->ATK += effect_value; + new_bonus->ATK += effect_value; break; } case SE_STR: { - newbon->STR += effect_value; + new_bonus->STR += effect_value; break; } case SE_DEX: { - newbon->DEX += effect_value; + new_bonus->DEX += effect_value; break; } case SE_AGI: { - newbon->AGI += effect_value; + new_bonus->AGI += effect_value; break; } case SE_STA: { - newbon->STA += effect_value; + new_bonus->STA += effect_value; break; } case SE_INT: { - newbon->INT += effect_value; + new_bonus->INT += effect_value; break; } case SE_WIS: { - newbon->WIS += effect_value; + new_bonus->WIS += effect_value; break; } case SE_CHA: { if (spells[spell_id].base[i] != 0) { - newbon->CHA += effect_value; + new_bonus->CHA += effect_value; } break; } case SE_AllStats: { - newbon->STR += effect_value; - newbon->DEX += effect_value; - newbon->AGI += effect_value; - newbon->STA += effect_value; - newbon->INT += effect_value; - newbon->WIS += effect_value; - newbon->CHA += effect_value; + new_bonus->STR += effect_value; + new_bonus->DEX += effect_value; + new_bonus->AGI += effect_value; + new_bonus->STA += effect_value; + new_bonus->INT += effect_value; + new_bonus->WIS += effect_value; + new_bonus->CHA += effect_value; break; } case SE_ResistFire: { - newbon->FR += effect_value; + new_bonus->FR += effect_value; break; } case SE_ResistCold: { - newbon->CR += effect_value; + new_bonus->CR += effect_value; break; } case SE_ResistPoison: { - newbon->PR += effect_value; + new_bonus->PR += effect_value; break; } case SE_ResistDisease: { - newbon->DR += effect_value; + new_bonus->DR += effect_value; break; } case SE_ResistMagic: { - newbon->MR += effect_value; + new_bonus->MR += effect_value; break; } case SE_ResistAll: { - newbon->MR += effect_value; - newbon->DR += effect_value; - newbon->PR += effect_value; - newbon->CR += effect_value; - newbon->FR += effect_value; + new_bonus->MR += effect_value; + new_bonus->DR += effect_value; + new_bonus->PR += effect_value; + new_bonus->CR += effect_value; + new_bonus->FR += effect_value; break; } case SE_ResistCorruption: { - newbon->Corrup += effect_value; + new_bonus->Corrup += effect_value; break; } @@ -1711,43 +1711,43 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { //are these #define'd somewhere? case 0: //str - newbon->STRCapMod += effect_value; + new_bonus->STRCapMod += effect_value; break; case 1: //sta - newbon->STACapMod += effect_value; + new_bonus->STACapMod += effect_value; break; case 2: //agi - newbon->AGICapMod += effect_value; + new_bonus->AGICapMod += effect_value; break; case 3: //dex - newbon->DEXCapMod += effect_value; + new_bonus->DEXCapMod += effect_value; break; case 4: //wis - newbon->WISCapMod += effect_value; + new_bonus->WISCapMod += effect_value; break; case 5: //int - newbon->INTCapMod += effect_value; + new_bonus->INTCapMod += effect_value; break; case 6: //cha - newbon->CHACapMod += effect_value; + new_bonus->CHACapMod += effect_value; break; case 7: //mr - newbon->MRCapMod += effect_value; + new_bonus->MRCapMod += effect_value; break; case 8: //cr - newbon->CRCapMod += effect_value; + new_bonus->CRCapMod += effect_value; break; case 9: //fr - newbon->FRCapMod += effect_value; + new_bonus->FRCapMod += effect_value; break; case 10: //pr - newbon->PRCapMod += effect_value; + new_bonus->PRCapMod += effect_value; break; case 11: //dr - newbon->DRCapMod += effect_value; + new_bonus->DRCapMod += effect_value; break; case 12: // corruption - newbon->CorrupCapMod += effect_value; + new_bonus->CorrupCapMod += effect_value; break; } break; @@ -1756,82 +1756,82 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_CastingLevel2: case SE_CastingLevel: // Brilliance of Ro { - newbon->effective_casting_level += effect_value; + new_bonus->effective_casting_level += effect_value; break; } case SE_MovementSpeed: - newbon->movementspeed += effect_value; + new_bonus->movementspeed += effect_value; break; case SE_SpellDamageShield: - newbon->SpellDamageShield += effect_value; + new_bonus->SpellDamageShield += effect_value; break; case SE_DamageShield: { - newbon->DamageShield += effect_value; - newbon->DamageShieldSpellID = spell_id; + new_bonus->DamageShield += effect_value; + new_bonus->DamageShieldSpellID = spell_id; //When using npc_spells_effects MAX value can be set to determine DS Type if (IsAISpellEffect && max) - newbon->DamageShieldType = GetDamageShieldType(spell_id, max); + new_bonus->DamageShieldType = GetDamageShieldType(spell_id, max); else - newbon->DamageShieldType = GetDamageShieldType(spell_id); + new_bonus->DamageShieldType = GetDamageShieldType(spell_id); break; } case SE_ReverseDS: { - newbon->ReverseDamageShield += effect_value; - newbon->ReverseDamageShieldSpellID = spell_id; + new_bonus->ReverseDamageShield += effect_value; + new_bonus->ReverseDamageShieldSpellID = spell_id; if (IsAISpellEffect && max) - newbon->ReverseDamageShieldType = GetDamageShieldType(spell_id, max); + new_bonus->ReverseDamageShieldType = GetDamageShieldType(spell_id, max); else - newbon->ReverseDamageShieldType = GetDamageShieldType(spell_id); + new_bonus->ReverseDamageShieldType = GetDamageShieldType(spell_id); break; } case SE_Reflect: - newbon->reflect_chance += effect_value; + new_bonus->reflect_chance += effect_value; break; case SE_Amplification: - newbon->Amplification += effect_value; + new_bonus->Amplification += effect_value; break; case SE_ChangeAggro: - newbon->hatemod += effect_value; + new_bonus->hatemod += effect_value; break; case SE_MeleeMitigation: //for some reason... this value is negative for increased mitigation - newbon->MeleeMitigationEffect -= effect_value; + new_bonus->MeleeMitigationEffect -= effect_value; break; case SE_CriticalHitChance: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) { if(base2 == -1) - newbon->CriticalHitChance[HIGHEST_SKILL+1] += effect_value; + new_bonus->CriticalHitChance[HIGHEST_SKILL+1] += effect_value; else - newbon->CriticalHitChance[base2] += effect_value; + new_bonus->CriticalHitChance[base2] += effect_value; } else if(effect_value < 0) { - if(base2 == -1 && newbon->CriticalHitChance[HIGHEST_SKILL+1] > effect_value) - newbon->CriticalHitChance[HIGHEST_SKILL+1] = effect_value; - else if(base2 != -1 && newbon->CriticalHitChance[base2] > effect_value) - newbon->CriticalHitChance[base2] = effect_value; + if(base2 == -1 && new_bonus->CriticalHitChance[HIGHEST_SKILL+1] > effect_value) + new_bonus->CriticalHitChance[HIGHEST_SKILL+1] = effect_value; + else if(base2 != -1 && new_bonus->CriticalHitChance[base2] > effect_value) + new_bonus->CriticalHitChance[base2] = effect_value; } - else if(base2 == -1 && newbon->CriticalHitChance[HIGHEST_SKILL+1] < effect_value) - newbon->CriticalHitChance[HIGHEST_SKILL+1] = effect_value; - else if(base2 != -1 && newbon->CriticalHitChance[base2] < effect_value) - newbon->CriticalHitChance[base2] = effect_value; + else if(base2 == -1 && new_bonus->CriticalHitChance[HIGHEST_SKILL+1] < effect_value) + new_bonus->CriticalHitChance[HIGHEST_SKILL+1] = effect_value; + else if(base2 != -1 && new_bonus->CriticalHitChance[base2] < effect_value) + new_bonus->CriticalHitChance[base2] = effect_value; break; } @@ -1839,13 +1839,13 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_CrippBlowChance: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->CrippBlowChance += effect_value; + new_bonus->CrippBlowChance += effect_value; - else if((effect_value < 0) && (newbon->CrippBlowChance > effect_value)) - newbon->CrippBlowChance = effect_value; + else if((effect_value < 0) && (new_bonus->CrippBlowChance > effect_value)) + new_bonus->CrippBlowChance = effect_value; - else if(newbon->CrippBlowChance < effect_value) - newbon->CrippBlowChance = effect_value; + else if(new_bonus->CrippBlowChance < effect_value) + new_bonus->CrippBlowChance = effect_value; break; } @@ -1853,65 +1853,65 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_AvoidMeleeChance: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->AvoidMeleeChanceEffect += effect_value; + new_bonus->AvoidMeleeChanceEffect += effect_value; - else if((effect_value < 0) && (newbon->AvoidMeleeChanceEffect > effect_value)) - newbon->AvoidMeleeChanceEffect = effect_value; + else if((effect_value < 0) && (new_bonus->AvoidMeleeChanceEffect > effect_value)) + new_bonus->AvoidMeleeChanceEffect = effect_value; - else if(newbon->AvoidMeleeChanceEffect < effect_value) - newbon->AvoidMeleeChanceEffect = effect_value; + else if(new_bonus->AvoidMeleeChanceEffect < effect_value) + new_bonus->AvoidMeleeChanceEffect = effect_value; break; } case SE_RiposteChance: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->RiposteChance += effect_value; + new_bonus->RiposteChance += effect_value; - else if((effect_value < 0) && (newbon->RiposteChance > effect_value)) - newbon->RiposteChance = effect_value; + else if((effect_value < 0) && (new_bonus->RiposteChance > effect_value)) + new_bonus->RiposteChance = effect_value; - else if(newbon->RiposteChance < effect_value) - newbon->RiposteChance = effect_value; + else if(new_bonus->RiposteChance < effect_value) + new_bonus->RiposteChance = effect_value; break; } case SE_DodgeChance: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->DodgeChance += effect_value; + new_bonus->DodgeChance += effect_value; - else if((effect_value < 0) && (newbon->DodgeChance > effect_value)) - newbon->DodgeChance = effect_value; + else if((effect_value < 0) && (new_bonus->DodgeChance > effect_value)) + new_bonus->DodgeChance = effect_value; - if(newbon->DodgeChance < effect_value) - newbon->DodgeChance = effect_value; + if(new_bonus->DodgeChance < effect_value) + new_bonus->DodgeChance = effect_value; break; } case SE_ParryChance: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->ParryChance += effect_value; + new_bonus->ParryChance += effect_value; - else if((effect_value < 0) && (newbon->ParryChance > effect_value)) - newbon->ParryChance = effect_value; + else if((effect_value < 0) && (new_bonus->ParryChance > effect_value)) + new_bonus->ParryChance = effect_value; - if(newbon->ParryChance < effect_value) - newbon->ParryChance = effect_value; + if(new_bonus->ParryChance < effect_value) + new_bonus->ParryChance = effect_value; break; } case SE_DualWieldChance: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->DualWieldChance += effect_value; + new_bonus->DualWieldChance += effect_value; - else if((effect_value < 0) && (newbon->DualWieldChance > effect_value)) - newbon->DualWieldChance = effect_value; + else if((effect_value < 0) && (new_bonus->DualWieldChance > effect_value)) + new_bonus->DualWieldChance = effect_value; - if(newbon->DualWieldChance < effect_value) - newbon->DualWieldChance = effect_value; + if(new_bonus->DualWieldChance < effect_value) + new_bonus->DualWieldChance = effect_value; break; } @@ -1919,13 +1919,13 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->DoubleAttackChance += effect_value; + new_bonus->DoubleAttackChance += effect_value; - else if((effect_value < 0) && (newbon->DoubleAttackChance > effect_value)) - newbon->DoubleAttackChance = effect_value; + else if((effect_value < 0) && (new_bonus->DoubleAttackChance > effect_value)) + new_bonus->DoubleAttackChance = effect_value; - if(newbon->DoubleAttackChance < effect_value) - newbon->DoubleAttackChance = effect_value; + if(new_bonus->DoubleAttackChance < effect_value) + new_bonus->DoubleAttackChance = effect_value; break; } @@ -1933,82 +1933,82 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->TripleAttackChance += effect_value; + new_bonus->TripleAttackChance += effect_value; - else if((effect_value < 0) && (newbon->TripleAttackChance > effect_value)) - newbon->TripleAttackChance = effect_value; + else if((effect_value < 0) && (new_bonus->TripleAttackChance > effect_value)) + new_bonus->TripleAttackChance = effect_value; - if(newbon->TripleAttackChance < effect_value) - newbon->TripleAttackChance = effect_value; + if(new_bonus->TripleAttackChance < effect_value) + new_bonus->TripleAttackChance = effect_value; break; } case SE_MeleeLifetap: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->MeleeLifetap += spells[spell_id].base[i]; + new_bonus->MeleeLifetap += spells[spell_id].base[i]; - else if((effect_value < 0) && (newbon->MeleeLifetap > effect_value)) - newbon->MeleeLifetap = effect_value; + else if((effect_value < 0) && (new_bonus->MeleeLifetap > effect_value)) + new_bonus->MeleeLifetap = effect_value; - else if(newbon->MeleeLifetap < effect_value) - newbon->MeleeLifetap = effect_value; + else if(new_bonus->MeleeLifetap < effect_value) + new_bonus->MeleeLifetap = effect_value; break; } case SE_Vampirism: - newbon->Vampirism += effect_value; + new_bonus->Vampirism += effect_value; break; case SE_AllInstrumentMod: { - if(effect_value > newbon->singingMod) - newbon->singingMod = effect_value; - if(effect_value > newbon->brassMod) - newbon->brassMod = effect_value; - if(effect_value > newbon->percussionMod) - newbon->percussionMod = effect_value; - if(effect_value > newbon->windMod) - newbon->windMod = effect_value; - if(effect_value > newbon->stringedMod) - newbon->stringedMod = effect_value; + if(effect_value > new_bonus->singingMod) + new_bonus->singingMod = effect_value; + if(effect_value > new_bonus->brassMod) + new_bonus->brassMod = effect_value; + if(effect_value > new_bonus->percussionMod) + new_bonus->percussionMod = effect_value; + if(effect_value > new_bonus->windMod) + new_bonus->windMod = effect_value; + if(effect_value > new_bonus->stringedMod) + new_bonus->stringedMod = effect_value; break; } case SE_ResistSpellChance: - newbon->ResistSpellChance += effect_value; + new_bonus->ResistSpellChance += effect_value; break; case SE_ResistFearChance: { if(effect_value == 100) // If we reach 100% in a single spell/item then we should be immune to negative fear resist effects until our immunity is over - newbon->Fearless = true; + new_bonus->Fearless = true; - newbon->ResistFearChance += effect_value; // these should stack + new_bonus->ResistFearChance += effect_value; // these should stack break; } case SE_Fearless: - newbon->Fearless = true; + new_bonus->Fearless = true; break; case SE_HundredHands: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->HundredHands += effect_value; + new_bonus->HundredHands += effect_value; - if (effect_value > 0 && effect_value > newbon->HundredHands) - newbon->HundredHands = effect_value; //Increase Weapon Delay - else if (effect_value < 0 && effect_value < newbon->HundredHands) - newbon->HundredHands = effect_value; //Decrease Weapon Delay + if (effect_value > 0 && effect_value > new_bonus->HundredHands) + new_bonus->HundredHands = effect_value; //Increase Weapon Delay + else if (effect_value < 0 && effect_value < new_bonus->HundredHands) + new_bonus->HundredHands = effect_value; //Decrease Weapon Delay break; } case SE_MeleeSkillCheck: { - if(newbon->MeleeSkillCheck < effect_value) { - newbon->MeleeSkillCheck = effect_value; - newbon->MeleeSkillCheckSkill = base2==-1?255:base2; + if(new_bonus->MeleeSkillCheck < effect_value) { + new_bonus->MeleeSkillCheck = effect_value; + new_bonus->MeleeSkillCheckSkill = base2==-1?255:base2; } break; } @@ -2018,29 +2018,29 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne if (RuleB(Spells, AdditiveBonusValues) && item_bonus){ if(base2 == -1) - newbon->HitChanceEffect[HIGHEST_SKILL+1] += effect_value; + new_bonus->HitChanceEffect[HIGHEST_SKILL+1] += effect_value; else - newbon->HitChanceEffect[base2] += effect_value; + new_bonus->HitChanceEffect[base2] += effect_value; } else if(base2 == -1){ - if ((effect_value < 0) && (newbon->HitChanceEffect[HIGHEST_SKILL+1] > effect_value)) - newbon->HitChanceEffect[HIGHEST_SKILL+1] = effect_value; + if ((effect_value < 0) && (new_bonus->HitChanceEffect[HIGHEST_SKILL+1] > effect_value)) + new_bonus->HitChanceEffect[HIGHEST_SKILL+1] = effect_value; - else if (!newbon->HitChanceEffect[HIGHEST_SKILL+1] || - ((newbon->HitChanceEffect[HIGHEST_SKILL+1] > 0) && (newbon->HitChanceEffect[HIGHEST_SKILL+1] < effect_value))) - newbon->HitChanceEffect[HIGHEST_SKILL+1] = effect_value; + else if (!new_bonus->HitChanceEffect[HIGHEST_SKILL+1] || + ((new_bonus->HitChanceEffect[HIGHEST_SKILL+1] > 0) && (new_bonus->HitChanceEffect[HIGHEST_SKILL+1] < effect_value))) + new_bonus->HitChanceEffect[HIGHEST_SKILL+1] = effect_value; } else { - if ((effect_value < 0) && (newbon->HitChanceEffect[base2] > effect_value)) - newbon->HitChanceEffect[base2] = effect_value; + if ((effect_value < 0) && (new_bonus->HitChanceEffect[base2] > effect_value)) + new_bonus->HitChanceEffect[base2] = effect_value; - else if (!newbon->HitChanceEffect[base2] || - ((newbon->HitChanceEffect[base2] > 0) && (newbon->HitChanceEffect[base2] < effect_value))) - newbon->HitChanceEffect[base2] = effect_value; + else if (!new_bonus->HitChanceEffect[base2] || + ((new_bonus->HitChanceEffect[base2] > 0) && (new_bonus->HitChanceEffect[base2] < effect_value))) + new_bonus->HitChanceEffect[base2] = effect_value; } break; @@ -2050,71 +2050,71 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_DamageModifier: { if(base2 == -1) - newbon->DamageModifier[HIGHEST_SKILL+1] += effect_value; + new_bonus->DamageModifier[HIGHEST_SKILL+1] += effect_value; else - newbon->DamageModifier[base2] += effect_value; + new_bonus->DamageModifier[base2] += effect_value; break; } case SE_DamageModifier2: { if(base2 == -1) - newbon->DamageModifier2[HIGHEST_SKILL+1] += effect_value; + new_bonus->DamageModifier2[HIGHEST_SKILL+1] += effect_value; else - newbon->DamageModifier2[base2] += effect_value; + new_bonus->DamageModifier2[base2] += effect_value; break; } case SE_MinDamageModifier: { if(base2 == -1) - newbon->MinDamageModifier[HIGHEST_SKILL+1] += effect_value; + new_bonus->MinDamageModifier[HIGHEST_SKILL+1] += effect_value; else - newbon->MinDamageModifier[base2] += effect_value; + new_bonus->MinDamageModifier[base2] += effect_value; break; } case SE_StunResist: { - if(newbon->StunResist < effect_value) - newbon->StunResist = effect_value; + if(new_bonus->StunResist < effect_value) + new_bonus->StunResist = effect_value; break; } case SE_ProcChance: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) - newbon->ProcChanceSPA += effect_value; + new_bonus->ProcChanceSPA += effect_value; - else if((effect_value < 0) && (newbon->ProcChanceSPA > effect_value)) - newbon->ProcChanceSPA = effect_value; + else if((effect_value < 0) && (new_bonus->ProcChanceSPA > effect_value)) + new_bonus->ProcChanceSPA = effect_value; - if(newbon->ProcChanceSPA < effect_value) - newbon->ProcChanceSPA = effect_value; + if(new_bonus->ProcChanceSPA < effect_value) + new_bonus->ProcChanceSPA = effect_value; break; } case SE_ExtraAttackChance: - newbon->ExtraAttackChance += effect_value; + new_bonus->ExtraAttackChance += effect_value; break; case SE_PercentXPIncrease: { - if(newbon->XPRateMod < effect_value) - newbon->XPRateMod = effect_value; + if(new_bonus->XPRateMod < effect_value) + new_bonus->XPRateMod = effect_value; break; } case SE_DeathSave: { - if(newbon->DeathSave[0] < effect_value) + if(new_bonus->DeathSave[0] < effect_value) { - newbon->DeathSave[0] = effect_value; //1='Partial' 2='Full' - newbon->DeathSave[1] = buffslot; + new_bonus->DeathSave[0] = effect_value; //1='Partial' 2='Full' + new_bonus->DeathSave[1] = buffslot; //These are used in later expansion spell effects. - newbon->DeathSave[2] = base2;//Min level for HealAmt - newbon->DeathSave[3] = max;//HealAmt + new_bonus->DeathSave[2] = base2;//Min level for HealAmt + new_bonus->DeathSave[3] = max;//HealAmt } break; } @@ -2122,44 +2122,44 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_DivineSave: { if (RuleB(Spells, AdditiveBonusValues) && item_bonus) { - newbon->DivineSaveChance[0] += effect_value; - newbon->DivineSaveChance[1] = 0; + new_bonus->DivineSaveChance[0] += effect_value; + new_bonus->DivineSaveChance[1] = 0; } - else if(newbon->DivineSaveChance[0] < effect_value) + else if(new_bonus->DivineSaveChance[0] < effect_value) { - newbon->DivineSaveChance[0] = effect_value; - newbon->DivineSaveChance[1] = base2; + new_bonus->DivineSaveChance[0] = effect_value; + new_bonus->DivineSaveChance[1] = base2; //SetDeathSaveChance(true); } break; } case SE_Flurry: - newbon->FlurryChance += effect_value; + new_bonus->FlurryChance += effect_value; break; case SE_Accuracy: { - if ((effect_value < 0) && (newbon->Accuracy[HIGHEST_SKILL+1] > effect_value)) - newbon->Accuracy[HIGHEST_SKILL+1] = effect_value; + if ((effect_value < 0) && (new_bonus->Accuracy[HIGHEST_SKILL+1] > effect_value)) + new_bonus->Accuracy[HIGHEST_SKILL+1] = effect_value; - else if (!newbon->Accuracy[HIGHEST_SKILL+1] || - ((newbon->Accuracy[HIGHEST_SKILL+1] > 0) && (newbon->Accuracy[HIGHEST_SKILL+1] < effect_value))) - newbon->Accuracy[HIGHEST_SKILL+1] = effect_value; + else if (!new_bonus->Accuracy[HIGHEST_SKILL+1] || + ((new_bonus->Accuracy[HIGHEST_SKILL+1] > 0) && (new_bonus->Accuracy[HIGHEST_SKILL+1] < effect_value))) + new_bonus->Accuracy[HIGHEST_SKILL+1] = effect_value; break; } case SE_MaxHPChange: - newbon->MaxHPChange += effect_value; + new_bonus->MaxHPChange += effect_value; break; case SE_EndurancePool: - newbon->Endurance += effect_value; + new_bonus->Endurance += effect_value; break; case SE_HealRate: - newbon->HealRate += effect_value; + new_bonus->HealRate += effect_value; break; case SE_SkillDamageTaken: @@ -2174,9 +2174,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne else { if(base2 == -1) - newbon->SkillDmgTaken[HIGHEST_SKILL+1] += effect_value; + new_bonus->SkillDmgTaken[HIGHEST_SKILL+1] += effect_value; else - newbon->SkillDmgTaken[base2] += effect_value; + new_bonus->SkillDmgTaken[base2] += effect_value; } break; @@ -2186,9 +2186,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { for(int e = 0; e < MAX_SPELL_TRIGGER; e++) { - if(!newbon->SpellTriggers[e]) + if(!new_bonus->SpellTriggers[e]) { - newbon->SpellTriggers[e] = spell_id; + new_bonus->SpellTriggers[e] = spell_id; break; } } @@ -2196,44 +2196,44 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne } case SE_SpellCritChance: - newbon->CriticalSpellChance += effect_value; + new_bonus->CriticalSpellChance += effect_value; break; case SE_CriticalSpellChance: { - newbon->CriticalSpellChance += effect_value; + new_bonus->CriticalSpellChance += effect_value; - if (base2 > newbon->SpellCritDmgIncNoStack) - newbon->SpellCritDmgIncNoStack = base2; + if (base2 > new_bonus->SpellCritDmgIncNoStack) + new_bonus->SpellCritDmgIncNoStack = base2; break; } case SE_SpellCritDmgIncrease: - newbon->SpellCritDmgIncrease += effect_value; + new_bonus->SpellCritDmgIncrease += effect_value; break; case SE_DotCritDmgIncrease: - newbon->DotCritDmgIncrease += effect_value; + new_bonus->DotCritDmgIncrease += effect_value; break; case SE_CriticalHealChance: - newbon->CriticalHealChance += effect_value; + new_bonus->CriticalHealChance += effect_value; break; case SE_CriticalHealOverTime: - newbon->CriticalHealOverTime += effect_value; + new_bonus->CriticalHealOverTime += effect_value; break; case SE_CriticalHealDecay: - newbon->CriticalHealDecay = true; + new_bonus->CriticalHealDecay = true; break; case SE_CriticalRegenDecay: - newbon->CriticalRegenDecay = true; + new_bonus->CriticalRegenDecay = true; break; case SE_CriticalDotDecay: - newbon->CriticalDotDecay = true; + new_bonus->CriticalDotDecay = true; break; case SE_MitigateDamageShield: @@ -2241,24 +2241,24 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne if (effect_value < 0) effect_value = effect_value*-1; - newbon->DSMitigationOffHand += effect_value; + new_bonus->DSMitigationOffHand += effect_value; break; } case SE_CriticalDoTChance: - newbon->CriticalDoTChance += effect_value; + new_bonus->CriticalDoTChance += effect_value; break; case SE_ProcOnKillShot: { for(int e = 0; e < MAX_SPELL_TRIGGER*3; e+=3) { - if(!newbon->SpellOnKill[e]) + if(!new_bonus->SpellOnKill[e]) { // Base2 = Spell to fire | Base1 = % chance | Base3 = min level - newbon->SpellOnKill[e] = base2; - newbon->SpellOnKill[e+1] = effect_value; - newbon->SpellOnKill[e+2] = max; + new_bonus->SpellOnKill[e] = base2; + new_bonus->SpellOnKill[e+1] = effect_value; + new_bonus->SpellOnKill[e+2] = max; break; } } @@ -2269,11 +2269,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { for(int e = 0; e < MAX_SPELL_TRIGGER; e+=2) { - if(!newbon->SpellOnDeath[e]) + if(!new_bonus->SpellOnDeath[e]) { // Base2 = Spell to fire | Base1 = % chance - newbon->SpellOnDeath[e] = base2; - newbon->SpellOnDeath[e+1] = effect_value; + new_bonus->SpellOnDeath[e] = base2; + new_bonus->SpellOnDeath[e+1] = effect_value; break; } } @@ -2283,151 +2283,151 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_CriticalDamageMob: { if(base2 == -1) - newbon->CritDmgMob[HIGHEST_SKILL+1] += effect_value; + new_bonus->CritDmgMob[HIGHEST_SKILL+1] += effect_value; else - newbon->CritDmgMob[base2] += effect_value; + new_bonus->CritDmgMob[base2] += effect_value; break; } case SE_ReduceSkillTimer: { - if(newbon->SkillReuseTime[base2] < effect_value) - newbon->SkillReuseTime[base2] = effect_value; + if(new_bonus->SkillReuseTime[base2] < effect_value) + new_bonus->SkillReuseTime[base2] = effect_value; break; } case SE_SkillDamageAmount: { if(base2 == -1) - newbon->SkillDamageAmount[HIGHEST_SKILL+1] += effect_value; + new_bonus->SkillDamageAmount[HIGHEST_SKILL+1] += effect_value; else - newbon->SkillDamageAmount[base2] += effect_value; + new_bonus->SkillDamageAmount[base2] += effect_value; break; } case SE_GravityEffect: - newbon->GravityEffect = 1; + new_bonus->GravityEffect = 1; break; case SE_AntiGate: - newbon->AntiGate = true; + new_bonus->AntiGate = true; break; case SE_MagicWeapon: - newbon->MagicWeapon = true; + new_bonus->MagicWeapon = true; break; case SE_IncreaseBlockChance: - newbon->IncreaseBlockChance += effect_value; + new_bonus->IncreaseBlockChance += effect_value; break; case SE_PersistantCasting: - newbon->PersistantCasting += effect_value; + new_bonus->PersistantCasting += effect_value; break; case SE_LimitHPPercent: { - if(newbon->HPPercCap[0] != 0 && newbon->HPPercCap[0] > effect_value){ - newbon->HPPercCap[0] = effect_value; - newbon->HPPercCap[1] = base2; + if(new_bonus->HPPercCap[0] != 0 && new_bonus->HPPercCap[0] > effect_value){ + new_bonus->HPPercCap[0] = effect_value; + new_bonus->HPPercCap[1] = base2; } - else if(newbon->HPPercCap[0] == 0){ - newbon->HPPercCap[0] = effect_value; - newbon->HPPercCap[1] = base2; + else if(new_bonus->HPPercCap[0] == 0){ + new_bonus->HPPercCap[0] = effect_value; + new_bonus->HPPercCap[1] = base2; } break; } case SE_LimitManaPercent: { - if(newbon->ManaPercCap[0] != 0 && newbon->ManaPercCap[0] > effect_value){ - newbon->ManaPercCap[0] = effect_value; - newbon->ManaPercCap[1] = base2; + if(new_bonus->ManaPercCap[0] != 0 && new_bonus->ManaPercCap[0] > effect_value){ + new_bonus->ManaPercCap[0] = effect_value; + new_bonus->ManaPercCap[1] = base2; } - else if(newbon->ManaPercCap[0] == 0) { - newbon->ManaPercCap[0] = effect_value; - newbon->ManaPercCap[1] = base2; + else if(new_bonus->ManaPercCap[0] == 0) { + new_bonus->ManaPercCap[0] = effect_value; + new_bonus->ManaPercCap[1] = base2; } break; } case SE_LimitEndPercent: { - if(newbon->EndPercCap[0] != 0 && newbon->EndPercCap[0] > effect_value) { - newbon->EndPercCap[0] = effect_value; - newbon->EndPercCap[1] = base2; + if(new_bonus->EndPercCap[0] != 0 && new_bonus->EndPercCap[0] > effect_value) { + new_bonus->EndPercCap[0] = effect_value; + new_bonus->EndPercCap[1] = base2; } - else if(newbon->EndPercCap[0] == 0){ - newbon->EndPercCap[0] = effect_value; - newbon->EndPercCap[1] = base2; + else if(new_bonus->EndPercCap[0] == 0){ + new_bonus->EndPercCap[0] = effect_value; + new_bonus->EndPercCap[1] = base2; } break; } case SE_BlockNextSpellFocus: - newbon->BlockNextSpell = true; + new_bonus->BlockNextSpell = true; break; case SE_NegateSpellEffect: - newbon->NegateEffects = true; + new_bonus->NegateEffects = true; break; case SE_ImmuneFleeing: - newbon->ImmuneToFlee = true; + new_bonus->ImmuneToFlee = true; break; case SE_DelayDeath: - newbon->DelayDeath += effect_value; + new_bonus->DelayDeath += effect_value; break; case SE_SpellProcChance: - newbon->SpellProcChance += effect_value; + new_bonus->SpellProcChance += effect_value; break; case SE_CharmBreakChance: - newbon->CharmBreakChance += effect_value; + new_bonus->CharmBreakChance += effect_value; break; case SE_BardSongRange: - newbon->SongRange += effect_value; + new_bonus->SongRange += effect_value; break; case SE_HPToMana: { //Lower the ratio the more favorable - if((!newbon->HPToManaConvert) || (newbon->HPToManaConvert >= effect_value)) - newbon->HPToManaConvert = spells[spell_id].base[i]; + if((!new_bonus->HPToManaConvert) || (new_bonus->HPToManaConvert >= effect_value)) + new_bonus->HPToManaConvert = spells[spell_id].base[i]; break; } case SE_SkillDamageAmount2: { if(base2 == -1) - newbon->SkillDamageAmount2[HIGHEST_SKILL+1] += effect_value; + new_bonus->SkillDamageAmount2[HIGHEST_SKILL+1] += effect_value; else - newbon->SkillDamageAmount2[base2] += effect_value; + new_bonus->SkillDamageAmount2[base2] += effect_value; break; } case SE_NegateAttacks: { - if (!newbon->NegateAttacks[0] || - ((newbon->NegateAttacks[0] && newbon->NegateAttacks[2]) && (newbon->NegateAttacks[2] < max))){ - newbon->NegateAttacks[0] = 1; - newbon->NegateAttacks[1] = buffslot; - newbon->NegateAttacks[2] = max; + if (!new_bonus->NegateAttacks[0] || + ((new_bonus->NegateAttacks[0] && new_bonus->NegateAttacks[2]) && (new_bonus->NegateAttacks[2] < max))){ + new_bonus->NegateAttacks[0] = 1; + new_bonus->NegateAttacks[1] = buffslot; + new_bonus->NegateAttacks[2] = max; } break; } case SE_MitigateMeleeDamage: { - if (newbon->MitigateMeleeRune[0] < effect_value){ - newbon->MitigateMeleeRune[0] = effect_value; - newbon->MitigateMeleeRune[1] = buffslot; - newbon->MitigateMeleeRune[2] = base2; - newbon->MitigateMeleeRune[3] = max; + if (new_bonus->MitigateMeleeRune[0] < effect_value){ + new_bonus->MitigateMeleeRune[0] = effect_value; + new_bonus->MitigateMeleeRune[1] = buffslot; + new_bonus->MitigateMeleeRune[2] = base2; + new_bonus->MitigateMeleeRune[3] = max; } break; } @@ -2435,268 +2435,268 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_MeleeThresholdGuard: { - if (newbon->MeleeThresholdGuard[0] < effect_value){ - newbon->MeleeThresholdGuard[0] = effect_value; - newbon->MeleeThresholdGuard[1] = buffslot; - newbon->MeleeThresholdGuard[2] = base2; + if (new_bonus->MeleeThresholdGuard[0] < effect_value){ + new_bonus->MeleeThresholdGuard[0] = effect_value; + new_bonus->MeleeThresholdGuard[1] = buffslot; + new_bonus->MeleeThresholdGuard[2] = base2; } break; } case SE_SpellThresholdGuard: { - if (newbon->SpellThresholdGuard[0] < effect_value){ - newbon->SpellThresholdGuard[0] = effect_value; - newbon->SpellThresholdGuard[1] = buffslot; - newbon->SpellThresholdGuard[2] = base2; + if (new_bonus->SpellThresholdGuard[0] < effect_value){ + new_bonus->SpellThresholdGuard[0] = effect_value; + new_bonus->SpellThresholdGuard[1] = buffslot; + new_bonus->SpellThresholdGuard[2] = base2; } break; } case SE_MitigateSpellDamage: { - if (newbon->MitigateSpellRune[0] < effect_value){ - newbon->MitigateSpellRune[0] = effect_value; - newbon->MitigateSpellRune[1] = buffslot; - newbon->MitigateSpellRune[2] = base2; - newbon->MitigateSpellRune[3] = max; + if (new_bonus->MitigateSpellRune[0] < effect_value){ + new_bonus->MitigateSpellRune[0] = effect_value; + new_bonus->MitigateSpellRune[1] = buffslot; + new_bonus->MitigateSpellRune[2] = base2; + new_bonus->MitigateSpellRune[3] = max; } break; } case SE_MitigateDotDamage: { - if (newbon->MitigateDotRune[0] < effect_value){ - newbon->MitigateDotRune[0] = effect_value; - newbon->MitigateDotRune[1] = buffslot; - newbon->MitigateDotRune[2] = base2; - newbon->MitigateDotRune[3] = max; + if (new_bonus->MitigateDotRune[0] < effect_value){ + new_bonus->MitigateDotRune[0] = effect_value; + new_bonus->MitigateDotRune[1] = buffslot; + new_bonus->MitigateDotRune[2] = base2; + new_bonus->MitigateDotRune[3] = max; } break; } case SE_ManaAbsorbPercentDamage: { - if (newbon->ManaAbsorbPercentDamage[0] < effect_value){ - newbon->ManaAbsorbPercentDamage[0] = effect_value; - newbon->ManaAbsorbPercentDamage[1] = buffslot; + if (new_bonus->ManaAbsorbPercentDamage[0] < effect_value){ + new_bonus->ManaAbsorbPercentDamage[0] = effect_value; + new_bonus->ManaAbsorbPercentDamage[1] = buffslot; } break; } case SE_TriggerMeleeThreshold: - newbon->TriggerMeleeThreshold = true; + new_bonus->TriggerMeleeThreshold = true; break; case SE_TriggerSpellThreshold: - newbon->TriggerSpellThreshold = true; + new_bonus->TriggerSpellThreshold = true; break; case SE_ShieldBlock: - newbon->ShieldBlock += effect_value; + new_bonus->ShieldBlock += effect_value; break; case SE_ShieldEquipHateMod: - newbon->ShieldEquipHateMod += effect_value; + new_bonus->ShieldEquipHateMod += effect_value; break; case SE_ShieldEquipDmgMod: - newbon->ShieldEquipDmgMod[0] += effect_value; - newbon->ShieldEquipDmgMod[1] += base2; + new_bonus->ShieldEquipDmgMod[0] += effect_value; + new_bonus->ShieldEquipDmgMod[1] += base2; break; case SE_BlockBehind: - newbon->BlockBehind += effect_value; + new_bonus->BlockBehind += effect_value; break; case SE_Blind: - newbon->IsBlind = true; + new_bonus->IsBlind = true; break; case SE_Fear: - newbon->IsFeared = true; + new_bonus->IsFeared = true; break; //AA bonuses - implemented broadly into spell/item effects case SE_FrontalStunResist: - newbon->FrontalStunResist += effect_value; + new_bonus->FrontalStunResist += effect_value; break; case SE_ImprovedBindWound: - newbon->BindWound += effect_value; + new_bonus->BindWound += effect_value; break; case SE_MaxBindWound: - newbon->MaxBindWound += effect_value; + new_bonus->MaxBindWound += effect_value; break; case SE_BaseMovementSpeed: - newbon->BaseMovementSpeed += effect_value; + new_bonus->BaseMovementSpeed += effect_value; break; case SE_IncreaseRunSpeedCap: - newbon->IncreaseRunSpeedCap += effect_value; + new_bonus->IncreaseRunSpeedCap += effect_value; break; case SE_DoubleSpecialAttack: - newbon->DoubleSpecialAttack += effect_value; + new_bonus->DoubleSpecialAttack += effect_value; break; case SE_TripleBackstab: - newbon->TripleBackstab += effect_value; + new_bonus->TripleBackstab += effect_value; break; case SE_FrontalBackstabMinDmg: - newbon->FrontalBackstabMinDmg = true; + new_bonus->FrontalBackstabMinDmg = true; break; case SE_FrontalBackstabChance: - newbon->FrontalBackstabChance += effect_value; + new_bonus->FrontalBackstabChance += effect_value; break; case SE_ConsumeProjectile: - newbon->ConsumeProjectile += effect_value; + new_bonus->ConsumeProjectile += effect_value; break; case SE_ForageAdditionalItems: - newbon->ForageAdditionalItems += effect_value; + new_bonus->ForageAdditionalItems += effect_value; break; case SE_Salvage: - newbon->SalvageChance += effect_value; + new_bonus->SalvageChance += effect_value; break; case SE_ArcheryDamageModifier: - newbon->ArcheryDamageModifier += effect_value; + new_bonus->ArcheryDamageModifier += effect_value; break; case SE_DoubleRangedAttack: - newbon->DoubleRangedAttack += effect_value; + new_bonus->DoubleRangedAttack += effect_value; break; case SE_SecondaryDmgInc: - newbon->SecondaryDmgInc = true; + new_bonus->SecondaryDmgInc = true; break; case SE_StrikeThrough: case SE_StrikeThrough2: - newbon->StrikeThrough += effect_value; + new_bonus->StrikeThrough += effect_value; break; case SE_GiveDoubleAttack: - newbon->GiveDoubleAttack += effect_value; + new_bonus->GiveDoubleAttack += effect_value; break; case SE_PetCriticalHit: - newbon->PetCriticalHit += effect_value; + new_bonus->PetCriticalHit += effect_value; break; case SE_CombatStability: - newbon->CombatStability += effect_value; + new_bonus->CombatStability += effect_value; break; case SE_AddSingingMod: switch (base2) { case ItemTypeWindInstrument: - newbon->windMod += effect_value; + new_bonus->windMod += effect_value; break; case ItemTypeStringedInstrument: - newbon->stringedMod += effect_value; + new_bonus->stringedMod += effect_value; break; case ItemTypeBrassInstrument: - newbon->brassMod += effect_value; + new_bonus->brassMod += effect_value; break; case ItemTypePercussionInstrument: - newbon->percussionMod += effect_value; + new_bonus->percussionMod += effect_value; break; case ItemTypeSinging: - newbon->singingMod += effect_value; + new_bonus->singingMod += effect_value; break; } break; case SE_SongModCap: - newbon->songModCap += effect_value; + new_bonus->songModCap += effect_value; break; case SE_PetAvoidance: - newbon->PetAvoidance += effect_value; + new_bonus->PetAvoidance += effect_value; break; case SE_Ambidexterity: - newbon->Ambidexterity += effect_value; + new_bonus->Ambidexterity += effect_value; break; case SE_PetMaxHP: - newbon->PetMaxHP += effect_value; + new_bonus->PetMaxHP += effect_value; break; case SE_PetFlurry: - newbon->PetFlurry += effect_value; + new_bonus->PetFlurry += effect_value; break; case SE_GivePetGroupTarget: - newbon->GivePetGroupTarget = true; + new_bonus->GivePetGroupTarget = true; break; case SE_RootBreakChance: - newbon->RootBreakChance += effect_value; + new_bonus->RootBreakChance += effect_value; break; case SE_ChannelChanceItems: - newbon->ChannelChanceItems += effect_value; + new_bonus->ChannelChanceItems += effect_value; break; case SE_ChannelChanceSpells: - newbon->ChannelChanceSpells += effect_value; + new_bonus->ChannelChanceSpells += effect_value; break; case SE_UnfailingDivinity: - newbon->UnfailingDivinity += effect_value; + new_bonus->UnfailingDivinity += effect_value; break; case SE_ItemHPRegenCapIncrease: - newbon->ItemHPRegenCap += effect_value; + new_bonus->ItemHPRegenCap += effect_value; break; case SE_OffhandRiposteFail: - newbon->OffhandRiposteFail += effect_value; + new_bonus->OffhandRiposteFail += effect_value; break; case SE_ItemAttackCapIncrease: - newbon->ItemATKCap += effect_value; + new_bonus->ItemATKCap += effect_value; break; case SE_TwoHandBluntBlock: - newbon->TwoHandBluntBlock += effect_value; + new_bonus->TwoHandBluntBlock += effect_value; break; case SE_StunBashChance: - newbon->StunBashChance += effect_value; + new_bonus->StunBashChance += effect_value; break; case SE_IncreaseChanceMemwipe: - newbon->IncreaseChanceMemwipe += effect_value; + new_bonus->IncreaseChanceMemwipe += effect_value; break; case SE_CriticalMend: - newbon->CriticalMend += effect_value; + new_bonus->CriticalMend += effect_value; break; case SE_SpellEffectResistChance: { for(int e = 0; e < MAX_RESISTABLE_EFFECTS*2; e+=2) { - if(newbon->SEResist[e+1] && (newbon->SEResist[e] == base2) && (newbon->SEResist[e+1] < effect_value)){ - newbon->SEResist[e] = base2; //Spell Effect ID - newbon->SEResist[e+1] = effect_value; //Resist Chance + if(new_bonus->SEResist[e+1] && (new_bonus->SEResist[e] == base2) && (new_bonus->SEResist[e+1] < effect_value)){ + new_bonus->SEResist[e] = base2; //Spell Effect ID + new_bonus->SEResist[e+1] = effect_value; //Resist Chance break; } - else if (!newbon->SEResist[e+1]){ - newbon->SEResist[e] = base2; //Spell Effect ID - newbon->SEResist[e+1] = effect_value; //Resist Chance + else if (!new_bonus->SEResist[e+1]){ + new_bonus->SEResist[e] = base2; //Spell Effect ID + new_bonus->SEResist[e+1] = effect_value; //Resist Chance break; } } @@ -2705,110 +2705,110 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_MasteryofPast: { - if(newbon->MasteryofPast < effect_value) - newbon->MasteryofPast = effect_value; + if(new_bonus->MasteryofPast < effect_value) + new_bonus->MasteryofPast = effect_value; break; } case SE_DoubleRiposte: { - newbon->DoubleRiposte += effect_value; + new_bonus->DoubleRiposte += effect_value; } case SE_GiveDoubleRiposte: { //Only allow for regular double riposte chance. - if(newbon->GiveDoubleRiposte[base2] == 0){ - if(newbon->GiveDoubleRiposte[0] < effect_value) - newbon->GiveDoubleRiposte[0] = effect_value; + if(new_bonus->GiveDoubleRiposte[base2] == 0){ + if(new_bonus->GiveDoubleRiposte[0] < effect_value) + new_bonus->GiveDoubleRiposte[0] = effect_value; } break; } case SE_SlayUndead: { - if(newbon->SlayUndead[1] < effect_value) - newbon->SlayUndead[0] = effect_value; // Rate - newbon->SlayUndead[1] = base2; // Damage Modifier + if(new_bonus->SlayUndead[1] < effect_value) + new_bonus->SlayUndead[0] = effect_value; // Rate + new_bonus->SlayUndead[1] = base2; // Damage Modifier break; } case SE_TriggerOnReqTarget: case SE_TriggerOnReqCaster: - newbon->TriggerOnValueAmount = true; + new_bonus->TriggerOnValueAmount = true; break; case SE_DivineAura: - newbon->DivineAura = true; + new_bonus->DivineAura = true; break; case SE_ImprovedTaunt: - if (newbon->ImprovedTaunt[0] < effect_value) { - newbon->ImprovedTaunt[0] = effect_value; - newbon->ImprovedTaunt[1] = base2; - newbon->ImprovedTaunt[2] = buffslot; + if (new_bonus->ImprovedTaunt[0] < effect_value) { + new_bonus->ImprovedTaunt[0] = effect_value; + new_bonus->ImprovedTaunt[1] = base2; + new_bonus->ImprovedTaunt[2] = buffslot; } break; case SE_DistanceRemoval: - newbon->DistanceRemoval = true; + new_bonus->DistanceRemoval = true; break; case SE_FrenziedDevastation: - newbon->FrenziedDevastation += base2; + new_bonus->FrenziedDevastation += base2; break; case SE_Root: - if (newbon->Root[0] && (newbon->Root[1] > buffslot)){ - newbon->Root[0] = 1; - newbon->Root[1] = buffslot; + if (new_bonus->Root[0] && (new_bonus->Root[1] > buffslot)){ + new_bonus->Root[0] = 1; + new_bonus->Root[1] = buffslot; } - else if (!newbon->Root[0]){ - newbon->Root[0] = 1; - newbon->Root[1] = buffslot; + else if (!new_bonus->Root[0]){ + new_bonus->Root[0] = 1; + new_bonus->Root[1] = buffslot; } break; case SE_Rune: - if (newbon->MeleeRune[0] && (newbon->MeleeRune[1] > buffslot)){ + if (new_bonus->MeleeRune[0] && (new_bonus->MeleeRune[1] > buffslot)){ - newbon->MeleeRune[0] = effect_value; - newbon->MeleeRune[1] = buffslot; + new_bonus->MeleeRune[0] = effect_value; + new_bonus->MeleeRune[1] = buffslot; } - else if (!newbon->MeleeRune[0]){ - newbon->MeleeRune[0] = effect_value; - newbon->MeleeRune[1] = buffslot; + else if (!new_bonus->MeleeRune[0]){ + new_bonus->MeleeRune[0] = effect_value; + new_bonus->MeleeRune[1] = buffslot; } break; case SE_AbsorbMagicAtt: - if (newbon->AbsorbMagicAtt[0] && (newbon->AbsorbMagicAtt[1] > buffslot)){ - newbon->AbsorbMagicAtt[0] = effect_value; - newbon->AbsorbMagicAtt[1] = buffslot; + if (new_bonus->AbsorbMagicAtt[0] && (new_bonus->AbsorbMagicAtt[1] > buffslot)){ + new_bonus->AbsorbMagicAtt[0] = effect_value; + new_bonus->AbsorbMagicAtt[1] = buffslot; } - else if (!newbon->AbsorbMagicAtt[0]){ - newbon->AbsorbMagicAtt[0] = effect_value; - newbon->AbsorbMagicAtt[1] = buffslot; + else if (!new_bonus->AbsorbMagicAtt[0]){ + new_bonus->AbsorbMagicAtt[0] = effect_value; + new_bonus->AbsorbMagicAtt[1] = buffslot; } break; case SE_NegateIfCombat: - newbon->NegateIfCombat = true; + new_bonus->NegateIfCombat = true; break; case SE_Screech: - newbon->Screech = effect_value; + new_bonus->Screech = effect_value; break; case SE_AlterNPCLevel: if (IsNPC()){ - if (!newbon->AlterNPCLevel - || ((effect_value < 0) && (newbon->AlterNPCLevel > effect_value)) - || ((effect_value > 0) && (newbon->AlterNPCLevel < effect_value))) { + if (!new_bonus->AlterNPCLevel + || ((effect_value < 0) && (new_bonus->AlterNPCLevel > effect_value)) + || ((effect_value > 0) && (new_bonus->AlterNPCLevel < effect_value))) { int tmp_lv = GetOrigLevel() + effect_value; if (tmp_lv < 1) @@ -2816,7 +2816,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne else if (tmp_lv > 255) tmp_lv = 255; if ((GetLevel() != tmp_lv)){ - newbon->AlterNPCLevel = effect_value; + new_bonus->AlterNPCLevel = effect_value; SetLevel(tmp_lv); } } @@ -2824,82 +2824,82 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne break; case SE_AStacker: - newbon->AStacker[0] = 1; - newbon->AStacker[1] = effect_value; + new_bonus->AStacker[0] = 1; + new_bonus->AStacker[1] = effect_value; break; case SE_BStacker: - newbon->BStacker[0] = 1; - newbon->BStacker[1] = effect_value; + new_bonus->BStacker[0] = 1; + new_bonus->BStacker[1] = effect_value; break; case SE_CStacker: - newbon->CStacker[0] = 1; - newbon->CStacker[1] = effect_value; + new_bonus->CStacker[0] = 1; + new_bonus->CStacker[1] = effect_value; break; case SE_DStacker: - newbon->DStacker[0] = 1; - newbon->DStacker[1] = effect_value; + new_bonus->DStacker[0] = 1; + new_bonus->DStacker[1] = effect_value; break; case SE_Berserk: - newbon->BerserkSPA = true; + new_bonus->BerserkSPA = true; break; case SE_Metabolism: - newbon->Metabolism += effect_value; + new_bonus->Metabolism += effect_value; break; case SE_ImprovedReclaimEnergy: { - if((effect_value < 0) && (newbon->ImprovedReclaimEnergy > effect_value)) - newbon->ImprovedReclaimEnergy = effect_value; + if((effect_value < 0) && (new_bonus->ImprovedReclaimEnergy > effect_value)) + new_bonus->ImprovedReclaimEnergy = effect_value; - else if(newbon->ImprovedReclaimEnergy < effect_value) - newbon->ImprovedReclaimEnergy = effect_value; + else if(new_bonus->ImprovedReclaimEnergy < effect_value) + new_bonus->ImprovedReclaimEnergy = effect_value; break; } case SE_HeadShot: { - if(newbon->HeadShot[1] < base2){ - newbon->HeadShot[0] = effect_value; - newbon->HeadShot[1] = base2; + if(new_bonus->HeadShot[1] < base2){ + new_bonus->HeadShot[0] = effect_value; + new_bonus->HeadShot[1] = base2; } break; } case SE_HeadShotLevel: { - if(newbon->HSLevel < effect_value) - newbon->HSLevel = effect_value; + if(new_bonus->HSLevel < effect_value) + new_bonus->HSLevel = effect_value; break; } case SE_Assassinate: { - if(newbon->Assassinate[1] < base2){ - newbon->Assassinate[0] = effect_value; - newbon->Assassinate[1] = base2; + if(new_bonus->Assassinate[1] < base2){ + new_bonus->Assassinate[0] = effect_value; + new_bonus->Assassinate[1] = base2; } break; } case SE_AssassinateLevel: { - if(newbon->AssassinateLevel < effect_value) - newbon->AssassinateLevel = effect_value; + if(new_bonus->AssassinateLevel < effect_value) + new_bonus->AssassinateLevel = effect_value; break; } case SE_FinishingBlow: { //base1 = chance, base2 = damage - if (newbon->FinishingBlow[1] < base2){ - newbon->FinishingBlow[0] = effect_value; - newbon->FinishingBlow[1] = base2; + if (new_bonus->FinishingBlow[1] < base2){ + new_bonus->FinishingBlow[0] = effect_value; + new_bonus->FinishingBlow[1] = base2; } break; } @@ -2907,42 +2907,42 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_FinishingBlowLvl: { //base1 = level, base2 = ??? (Set to 200 in AA data, possible proc rate mod?) - if (newbon->FinishingBlowLvl[0] < effect_value){ - newbon->FinishingBlowLvl[0] = effect_value; - newbon->FinishingBlowLvl[1] = base2; + if (new_bonus->FinishingBlowLvl[0] < effect_value){ + new_bonus->FinishingBlowLvl[0] = effect_value; + new_bonus->FinishingBlowLvl[1] = base2; } break; } case SE_PetMeleeMitigation: - newbon->PetMeleeMitigation += effect_value; + new_bonus->PetMeleeMitigation += effect_value; break; case SE_MeleeVulnerability: - newbon->MeleeVulnerability += effect_value; + new_bonus->MeleeVulnerability += effect_value; break; case SE_Sanctuary: - newbon->Sanctuary = true; + new_bonus->Sanctuary = true; break; case SE_FactionModPct: { - if((effect_value < 0) && (newbon->FactionModPct > effect_value)) - newbon->FactionModPct = effect_value; + if((effect_value < 0) && (new_bonus->FactionModPct > effect_value)) + new_bonus->FactionModPct = effect_value; - else if(newbon->FactionModPct < effect_value) - newbon->FactionModPct = effect_value; + else if(new_bonus->FactionModPct < effect_value) + new_bonus->FactionModPct = effect_value; break; } case SE_IllusionPersistence: - newbon->IllusionPersistence = true; + new_bonus->IllusionPersistence = true; break; case SE_LimitToSkill:{ if (effect_value <= HIGHEST_SKILL){ - newbon->LimitToSkill[effect_value] = true; + new_bonus->LimitToSkill[effect_value] = true; } break; } @@ -2951,11 +2951,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne for(int e = 0; e < MAX_SKILL_PROCS; e++) { - if(newbon->SkillProc[e] && newbon->SkillProc[e] == spell_id) + if(new_bonus->SkillProc[e] && new_bonus->SkillProc[e] == spell_id) break; //Do not use the same spell id more than once. - else if(!newbon->SkillProc[e]){ - newbon->SkillProc[e] = spell_id; + else if(!new_bonus->SkillProc[e]){ + new_bonus->SkillProc[e] = spell_id; break; } } @@ -2966,11 +2966,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne for(int e = 0; e < MAX_SKILL_PROCS; e++) { - if(newbon->SkillProcSuccess[e] && newbon->SkillProcSuccess[e] == spell_id) + if(new_bonus->SkillProcSuccess[e] && new_bonus->SkillProcSuccess[e] == spell_id) break; //Do not use the same spell id more than once. - else if(!newbon->SkillProcSuccess[e]){ - newbon->SkillProcSuccess[e] = spell_id; + else if(!new_bonus->SkillProcSuccess[e]){ + new_bonus->SkillProcSuccess[e] = spell_id; break; } } diff --git a/zone/bot.cpp b/zone/bot.cpp index a8522c55a..da574f29b 100644 --- a/zone/bot.cpp +++ b/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::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) { diff --git a/zone/bot.h b/zone/bot.h index 47fafa052..b783c150a 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -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 GetBotSpells() { return AIspells; } diff --git a/zone/client.cpp b/zone/client.cpp index 7a98de929..5d1397b43 100644 --- a/zone/client.cpp +++ b/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 + ""; + stat_field += h_stat_spacing + a_resist_name + a_resist_spacing + a_resist + heroic_color + h_resist_field + ""; if(stat_row_counter < 6) { - stat_field += h_stat_spacing + a_resist_name + a_resist_spacing + a_resist + heroic_color + h_resist_field + "
"; + stat_field += "
"; } } /*########################################################## @@ -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 = ""; + _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; +} diff --git a/zone/client.h b/zone/client.h index b07ae83ac..06b94a880 100644 --- a/zone/client.h +++ b/zone/client.h @@ -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' '' '' '/12x' + std::string GetLinkBody() { return m_LinkBody; } // contains string format: '' + std::string GetLinkText() { return m_LinkText; } // contains string format: '' + + 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); } diff --git a/zone/client_logs.cpp b/zone/client_logs.cpp index 7ce3d5aab..4aba31159 100644 --- a/zone/client_logs.cpp +++ b/zone/client_logs.cpp @@ -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::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; diff --git a/zone/client_logs.h b/zone/client_logs.h index e3d5350b5..4db83a6b1 100644 --- a/zone/client_logs.h +++ b/zone/client_logs.h @@ -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 entries[EQEMuLog::MaxLogID]; + std::vector entries[EQEmuLog::MaxLogID]; static char _buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH+1]; }; diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 2db70e8a3..1a05052ad 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -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; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 3f0f2bb2d..0b3c2eb1d 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -415,7 +415,7 @@ int Client::HandlePacket(const EQApplicationPacket *app) #ifdef SOLAR if(0 && opcode != OP_ClientUpdate) { - LogFile->write(EQEMuLog::Debug,"HandlePacket() OPCODE debug enabled client %s", GetName()); + LogFile->write(EQEmuLog::Debug,"HandlePacket() OPCODE debug enabled client %s", GetName()); std::cerr << "OPCODE: " << std::hex << std::setw(4) << std::setfill('0') << opcode << std::dec << ", size: " << app->size << std::endl; DumpPacket(app); } @@ -430,7 +430,7 @@ int Client::HandlePacket(const EQApplicationPacket *app) parse->EventPlayer(EVENT_UNHANDLED_OPCODE, this, "", 1, &args); #if EQDEBUG >= 10 - LogFile->write(EQEMuLog::Error, "HandlePacket() Opcode error: Unexpected packet during CLIENT_CONNECTING: opcode:" + LogFile->write(EQEmuLog::Error, "HandlePacket() Opcode error: Unexpected packet during CLIENT_CONNECTING: opcode:" " %s (#%d eq=0x%04x), size: %i", OpcodeNames[opcode], opcode, 0, app->size); DumpPacket(app); #endif @@ -482,7 +482,7 @@ int Client::HandlePacket(const EQApplicationPacket *app) case CLIENT_LINKDEAD: break; default: - LogFile->write(EQEMuLog::Debug, "Unknown client_state: %d\n", client_state); + LogFile->write(EQEmuLog::Debug, "Unknown client_state: %d\n", client_state); break; } @@ -965,7 +965,7 @@ return; void Client::Handle_Connect_OP_ApproveZone(const EQApplicationPacket *app) { if (app->size != sizeof(ApproveZone_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size on OP_ApproveZone: Expected %i, Got %i", + LogFile->write(EQEmuLog::Error, "Invalid size on OP_ApproveZone: Expected %i, Got %i", sizeof(ApproveZone_Struct), app->size); return; } @@ -978,14 +978,14 @@ void Client::Handle_Connect_OP_ApproveZone(const EQApplicationPacket *app) void Client::Handle_Connect_OP_ClientError(const EQApplicationPacket *app) { if (app->size != sizeof(ClientError_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size on OP_ClientError: Expected %i, Got %i", + LogFile->write(EQEmuLog::Error, "Invalid size on OP_ClientError: Expected %i, Got %i", sizeof(ClientError_Struct), app->size); return; } // Client reporting error to server ClientError_Struct* error = (ClientError_Struct*)app->pBuffer; - LogFile->write(EQEMuLog::Error, "Client error: %s", error->character_name); - LogFile->write(EQEMuLog::Error, "Error message: %s", error->message); + LogFile->write(EQEmuLog::Error, "Client error: %s", error->character_name); + LogFile->write(EQEmuLog::Error, "Error message: %s", error->message); Message(13, error->message); #if (EQDEBUG>=5) DumpPacket(app); @@ -1179,7 +1179,7 @@ void Client::Handle_Connect_OP_SendTributes(const EQApplicationPacket *app) void Client::Handle_Connect_OP_SetServerFilter(const EQApplicationPacket *app) { if (app->size != sizeof(SetServerFilter_Struct)) { - LogFile->write(EQEMuLog::Error, "Received invalid sized OP_SetServerFilter"); + LogFile->write(EQEmuLog::Error, "Received invalid sized OP_SetServerFilter"); DumpPacket(app); return; } @@ -1196,7 +1196,7 @@ void Client::Handle_Connect_OP_SpawnAppearance(const EQApplicationPacket *app) void Client::Handle_Connect_OP_TGB(const EQApplicationPacket *app) { if (app->size != sizeof(uint32)) { - LogFile->write(EQEMuLog::Error, "Invalid size on OP_TGB: Expected %i, Got %i", + LogFile->write(EQEmuLog::Error, "Invalid size on OP_TGB: Expected %i, Got %i", sizeof(uint32), app->size); return; } @@ -1316,14 +1316,14 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) ClientVersionBit = 0; bool siv = m_inv.SetInventoryVersion(ClientVersion); - LogFile->write(EQEMuLog::Debug, "%s inventory version to %s(%i)", (siv ? "Succeeded in setting" : "Failed to set"), EQClientVersionName(ClientVersion), ClientVersion); + LogFile->write(EQEmuLog::Debug, "%s inventory version to %s(%i)", (siv ? "Succeeded in setting" : "Failed to set"), EQClientVersionName(ClientVersion), ClientVersion); /* Antighost code tmp var is so the search doesnt find this object */ Client* client = entity_list.GetClientByName(cze->char_name); if (!zone->GetAuth(ip, cze->char_name, &WID, &account_id, &character_id, &admin, lskey, &tellsoff)) { - LogFile->write(EQEMuLog::Error, "GetAuth() returned false kicking client"); + LogFile->write(EQEmuLog::Error, "GetAuth() returned false kicking client"); if (client != 0) { client->Save(); client->Kick(); @@ -1339,7 +1339,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) struct in_addr ghost_addr; ghost_addr.s_addr = eqs->GetRemoteIP(); - LogFile->write(EQEMuLog::Error,"Ghosting client: Account ID:%i Name:%s Character:%s IP:%s", + LogFile->write(EQEmuLog::Error,"Ghosting client: Account ID:%i Name:%s Character:%s IP:%s", client->AccountID(), client->AccountName(), client->GetName(), inet_ntoa(ghost_addr)); client->Save(); client->Disconnect(); @@ -1361,7 +1361,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) database.LoadCharacterFactionValues(cid, factionvalues); /* Load Character Account Data: Temp until I move */ - query = StringFormat("SELECT `status`, `name`, `lsaccount_id`, `gmspeed`, `revoked`, `hideme` FROM `account` WHERE `id` = %u", this->AccountID()); + query = StringFormat("SELECT `status`, `name`, `lsaccount_id`, `gmspeed`, `revoked`, `hideme`, `time_creation` FROM `account` WHERE `id` = %u", this->AccountID()); auto results = database.QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { admin = atoi(row[0]); @@ -1370,7 +1370,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) gmspeed = atoi(row[3]); revoked = atoi(row[4]); gmhideme = atoi(row[5]); - if (account_creation){ account_creation = atoul(row[6]); } + account_creation = atoul(row[6]); } /* Load Character Data */ @@ -1385,7 +1385,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) if (LFP){ LFP = atoi(row[0]); } if (LFG){ LFG = atoi(row[1]); } - if (firstlogon){ firstlogon = atoi(row[3]); } + if (row[3]) + firstlogon = atoi(row[3]); } if (RuleB(Character, SharedBankPlat)) @@ -1728,7 +1729,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) p_timers.SetCharID(CharacterID()); if (!p_timers.Load(&database)) { - LogFile->write(EQEMuLog::Error, "Unable to load ability timers from the database for %s (%i)!", GetCleanName(), CharacterID()); + LogFile->write(EQEmuLog::Error, "Unable to load ability timers from the database for %s (%i)!", GetCleanName(), CharacterID()); } /* Load Spell Slot Refresh from Currently Memoried Spells */ @@ -1940,7 +1941,7 @@ void Client::Handle_OP_AcceptNewTask(const EQApplicationPacket *app) { if (app->size != sizeof(AcceptNewTask_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_AcceptNewTask expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_AcceptNewTask expected %i got %i", sizeof(AcceptNewTask_Struct), app->size); DumpPacket(app); return; @@ -1955,7 +1956,7 @@ void Client::Handle_OP_AdventureInfoRequest(const EQApplicationPacket *app) { if (app->size < sizeof(EntityId_Struct)) { - LogFile->write(EQEMuLog::Error, "Handle_OP_AdventureInfoRequest had a packet that was too small."); + LogFile->write(EQEmuLog::Error, "Handle_OP_AdventureInfoRequest had a packet that was too small."); return; } EntityId_Struct* ent = (EntityId_Struct*)app->pBuffer; @@ -2010,7 +2011,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (app->size != sizeof(Adventure_Purchase_Struct)) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_AdventureMerchantPurchase expected:%i got:%i", sizeof(Adventure_Purchase_Struct), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_AdventureMerchantPurchase expected:%i got:%i", sizeof(Adventure_Purchase_Struct), app->size); return; } @@ -2190,7 +2191,7 @@ void Client::Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app) { if (app->size != sizeof(AdventureMerchant_Struct)) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_AdventureMerchantRequest expected:%i got:%i", sizeof(AdventureMerchant_Struct), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_AdventureMerchantRequest expected:%i got:%i", sizeof(AdventureMerchant_Struct), app->size); return; } std::stringstream ss(std::stringstream::in | std::stringstream::out); @@ -2280,7 +2281,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app) { if (app->size != sizeof(Adventure_Sell_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch on OP_AdventureMerchantSell: got %u expected %u", + LogFile->write(EQEmuLog::Debug, "Size mismatch on OP_AdventureMerchantSell: got %u expected %u", app->size, sizeof(Adventure_Sell_Struct)); DumpPacket(app); return; @@ -2412,7 +2413,7 @@ void Client::Handle_OP_AdventureRequest(const EQApplicationPacket *app) { if (app->size < sizeof(AdventureRequest_Struct)) { - LogFile->write(EQEMuLog::Error, "Handle_OP_AdventureRequest had a packet that was too small."); + LogFile->write(EQEmuLog::Error, "Handle_OP_AdventureRequest had a packet that was too small."); return; } @@ -2938,7 +2939,7 @@ void Client::Handle_OP_AltCurrencySellSelection(const EQApplicationPacket *app) void Client::Handle_OP_Animation(const EQApplicationPacket *app) { if (app->size != sizeof(Animation_Struct)) { - LogFile->write(EQEMuLog::Error, "Received invalid sized " + LogFile->write(EQEmuLog::Error, "Received invalid sized " "OP_Animation: got %d, expected %d", app->size, sizeof(Animation_Struct)); DumpPacket(app); @@ -2957,7 +2958,7 @@ void Client::Handle_OP_Animation(const EQApplicationPacket *app) void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app) { if (app->size != sizeof(ApplyPoison_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_ApplyPoison, size=%i, expected %i", app->size, sizeof(ApplyPoison_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_ApplyPoison, size=%i, expected %i", app->size, sizeof(ApplyPoison_Struct)); DumpPacket(app); return; } @@ -2994,7 +2995,7 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app) DeleteItemInInventory(ApplyPoisonData->inventorySlot, 1, true); - LogFile->write(EQEMuLog::Debug, "Chance to Apply Poison was %f. Roll was %f. Result is %u.", SuccessChance, ChanceRoll, ApplyPoisonSuccessResult); + LogFile->write(EQEmuLog::Debug, "Chance to Apply Poison was %f. Roll was %f. Result is %u.", SuccessChance, ChanceRoll, ApplyPoisonSuccessResult); } } @@ -3009,7 +3010,7 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app) void Client::Handle_OP_Assist(const EQApplicationPacket *app) { if (app->size != sizeof(EntityId_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_Assist expected %i got %i", sizeof(EntityId_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_Assist expected %i got %i", sizeof(EntityId_Struct), app->size); return; } @@ -3039,7 +3040,7 @@ void Client::Handle_OP_Assist(const EQApplicationPacket *app) void Client::Handle_OP_AssistGroup(const EQApplicationPacket *app) { if (app->size != sizeof(EntityId_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_AssistGroup expected %i got %i", sizeof(EntityId_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_AssistGroup expected %i got %i", sizeof(EntityId_Struct), app->size); return; } QueuePacket(app); @@ -3052,7 +3053,7 @@ void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app) // Some clients this seems to nuke the charm text (ex. Adventurer's Stone) if (app->size != sizeof(AugmentInfo_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_AugmentInfo expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_AugmentInfo expected %i got %i", sizeof(AugmentInfo_Struct), app->size); DumpPacket(app); return; @@ -3071,7 +3072,7 @@ void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app) void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) { if (app->size != sizeof(AugmentItem_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for AugmentItem_Struct: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for AugmentItem_Struct: Expected: %i, Got: %i", sizeof(AugmentItem_Struct), app->size); return; } @@ -3088,7 +3089,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) // Adding augment if (in_augment->augment_action == 0) { - ItemInst *tobe_auged, *auged_with = nullptr; + ItemInst *tobe_auged = nullptr, *auged_with = nullptr; int8 slot = -1; Inventory& user_inv = GetInv(); @@ -3158,7 +3159,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) } else if (in_augment->augment_action == 1) { - ItemInst *tobe_auged, *auged_with = nullptr; + ItemInst *tobe_auged = nullptr, *auged_with = nullptr; int8 slot = -1; Inventory& user_inv = GetInv(); @@ -3228,7 +3229,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app) { if (app->size != 4) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_AutoAttack expected:4 got:%i", app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_AutoAttack expected:4 got:%i", app->size); return; } @@ -3280,7 +3281,7 @@ void Client::Handle_OP_AutoAttack2(const EQApplicationPacket *app) void Client::Handle_OP_AutoFire(const EQApplicationPacket *app) { if (app->size != sizeof(bool)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_AutoFire expected %i got %i", sizeof(bool), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_AutoFire expected %i got %i", sizeof(bool), app->size); DumpPacket(app); return; } @@ -3296,7 +3297,7 @@ void Client::Handle_OP_Bandolier(const EQApplicationPacket *app) // Although there are three different structs for OP_Bandolier, they are all the same size. // if (app->size != sizeof(BandolierCreate_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_Bandolier expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_Bandolier expected %i got %i", sizeof(BandolierCreate_Struct), app->size); DumpPacket(app); return; @@ -3315,7 +3316,7 @@ void Client::Handle_OP_Bandolier(const EQApplicationPacket *app) SetBandolier(app); break; default: - LogFile->write(EQEMuLog::Debug, "Uknown Bandolier action %i", bs->action); + LogFile->write(EQEmuLog::Debug, "Uknown Bandolier action %i", bs->action); } } @@ -3324,7 +3325,7 @@ void Client::Handle_OP_BankerChange(const EQApplicationPacket *app) { if (app->size != sizeof(BankerChange_Struct) && app->size != 4) //Titanium only sends 4 Bytes for this { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_BankerChange expected %i got %i", sizeof(BankerChange_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_BankerChange expected %i got %i", sizeof(BankerChange_Struct), app->size); DumpPacket(app); return; } @@ -3409,7 +3410,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) if (app->size < 4) { - LogFile->write(EQEMuLog::Debug, "OP_Barter packet below minimum expected size. The packet was %i bytes.", app->size); + LogFile->write(EQEmuLog::Debug, "OP_Barter packet below minimum expected size. The packet was %i bytes.", app->size); DumpPacket(app); return; } @@ -3565,7 +3566,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) void Client::Handle_OP_BazaarInspect(const EQApplicationPacket *app) { if (app->size != sizeof(BazaarInspect_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for BazaarInspect_Struct: Expected %i, Got %i", + LogFile->write(EQEmuLog::Error, "Invalid size for BazaarInspect_Struct: Expected %i, Got %i", sizeof(BazaarInspect_Struct), app->size); return; } @@ -3621,7 +3622,7 @@ void Client::Handle_OP_BazaarSearch(const EQApplicationPacket *app) } else { _log(TRADING__CLIENT, "Malformed BazaarSearch_Struct packe, Action %it received, ignoring..."); - LogFile->write(EQEMuLog::Error, "Malformed BazaarSearch_Struct packet received, ignoring...\n"); + LogFile->write(EQEmuLog::Error, "Malformed BazaarSearch_Struct packet received, ignoring...\n"); } return; @@ -3706,16 +3707,16 @@ void Client::Handle_OP_Begging(const EQApplicationPacket *app) void Client::Handle_OP_Bind_Wound(const EQApplicationPacket *app) { if (app->size != sizeof(BindWound_Struct)){ - LogFile->write(EQEMuLog::Error, "Size mismatch for Bind wound packet"); + LogFile->write(EQEmuLog::Error, "Size mismatch for Bind wound packet"); DumpPacket(app); } BindWound_Struct* bind_in = (BindWound_Struct*)app->pBuffer; Mob* bindmob = entity_list.GetMob(bind_in->to); if (!bindmob){ - LogFile->write(EQEMuLog::Error, "Bindwound on non-exsistant mob from %s", this->GetName()); + LogFile->write(EQEmuLog::Error, "Bindwound on non-exsistant mob from %s", this->GetName()); } else { - LogFile->write(EQEMuLog::Debug, "BindWound in: to:\'%s\' from=\'%s\'", bindmob->GetName(), GetName()); + LogFile->write(EQEmuLog::Debug, "BindWound in: to:\'%s\' from=\'%s\'", bindmob->GetName(), GetName()); BindWound(bindmob, true); } return; @@ -3728,7 +3729,7 @@ void Client::Handle_OP_BlockedBuffs(const EQApplicationPacket *app) if (app->size != sizeof(BlockedBuffs_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_BlockedBuffs expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_BlockedBuffs expected %i got %i", sizeof(BlockedBuffs_Struct), app->size); DumpPacket(app); @@ -3823,7 +3824,7 @@ void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app) // this sends unclean mob name, so capped at 64 // a_boat006 if (app->size <= 5 || app->size > 64) { - LogFile->write(EQEMuLog::Error, "Size mismatch in OP_BoardBoad. Expected greater than 5 less than 64, got %i", app->size); + LogFile->write(EQEmuLog::Error, "Size mismatch in OP_BoardBoad. Expected greater than 5 less than 64, got %i", app->size); DumpPacket(app); return; } @@ -3844,7 +3845,7 @@ void Client::Handle_OP_Buff(const EQApplicationPacket *app) { if (app->size != sizeof(SpellBuffFade_Struct)) { - LogFile->write(EQEMuLog::Error, "Size mismatch in OP_Buff. expected %i got %i", sizeof(SpellBuffFade_Struct), app->size); + LogFile->write(EQEmuLog::Error, "Size mismatch in OP_Buff. expected %i got %i", sizeof(SpellBuffFade_Struct), app->size); DumpPacket(app); return; } @@ -3926,7 +3927,7 @@ void Client::Handle_OP_CancelTask(const EQApplicationPacket *app) { if (app->size != sizeof(CancelTask_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_CancelTask expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_CancelTask expected %i got %i", sizeof(CancelTask_Struct), app->size); DumpPacket(app); return; @@ -3940,7 +3941,7 @@ void Client::Handle_OP_CancelTask(const EQApplicationPacket *app) void Client::Handle_OP_CancelTrade(const EQApplicationPacket *app) { if (app->size != sizeof(CancelTrade_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_CancelTrade, size=%i, expected %i", app->size, sizeof(CancelTrade_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_CancelTrade, size=%i, expected %i", app->size, sizeof(CancelTrade_Struct)); return; } Mob* with = trade->With(); @@ -3989,16 +3990,16 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) m_TargetRing = xyz_location(castspell->x_pos, castspell->y_pos, castspell->z_pos); #ifdef _EQDEBUG - LogFile->write(EQEMuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[0], castspell->cs_unknown[0]); - LogFile->write(EQEMuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[1], castspell->cs_unknown[1]); - LogFile->write(EQEMuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[2], castspell->cs_unknown[2]); - LogFile->write(EQEMuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[3], castspell->cs_unknown[3]); - LogFile->write(EQEMuLog::Debug, "cs_unknown2: 32 %p %u", &castspell->cs_unknown, *(uint32*)castspell->cs_unknown); - LogFile->write(EQEMuLog::Debug, "cs_unknown2: 32 %p %i", &castspell->cs_unknown, *(uint32*)castspell->cs_unknown); - LogFile->write(EQEMuLog::Debug, "cs_unknown2: 16 %p %u %u", &castspell->cs_unknown, *(uint16*)castspell->cs_unknown, *(uint16*)castspell->cs_unknown + sizeof(uint16)); - LogFile->write(EQEMuLog::Debug, "cs_unknown2: 16 %p %i %i", &castspell->cs_unknown, *(uint16*)castspell->cs_unknown, *(uint16*)castspell->cs_unknown + sizeof(uint16)); + LogFile->write(EQEmuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[0], castspell->cs_unknown[0]); + LogFile->write(EQEmuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[1], castspell->cs_unknown[1]); + LogFile->write(EQEmuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[2], castspell->cs_unknown[2]); + LogFile->write(EQEmuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[3], castspell->cs_unknown[3]); + LogFile->write(EQEmuLog::Debug, "cs_unknown2: 32 %p %u", &castspell->cs_unknown, *(uint32*)castspell->cs_unknown); + LogFile->write(EQEmuLog::Debug, "cs_unknown2: 32 %p %i", &castspell->cs_unknown, *(uint32*)castspell->cs_unknown); + LogFile->write(EQEmuLog::Debug, "cs_unknown2: 16 %p %u %u", &castspell->cs_unknown, *(uint16*)castspell->cs_unknown, *(uint16*)castspell->cs_unknown + sizeof(uint16)); + LogFile->write(EQEmuLog::Debug, "cs_unknown2: 16 %p %i %i", &castspell->cs_unknown, *(uint16*)castspell->cs_unknown, *(uint16*)castspell->cs_unknown + sizeof(uint16)); #endif - LogFile->write(EQEMuLog::Debug, "OP CastSpell: slot=%d, spell=%d, target=%d, inv=%lx", castspell->slot, castspell->spell_id, castspell->target_id, (unsigned long)castspell->inventoryslot); + LogFile->write(EQEmuLog::Debug, "OP CastSpell: slot=%d, spell=%d, target=%d, inv=%lx", castspell->slot, castspell->spell_id, castspell->target_id, (unsigned long)castspell->inventoryslot); std::cout << "OP_CastSpell " << castspell->slot << " spell " << castspell->spell_id << " inventory slot " << castspell->inventoryslot << "\n" << std::endl; @@ -4028,7 +4029,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) //discipline, using the item spell slot if (castspell->inventoryslot == INVALID_INDEX) { if (!UseDiscipline(castspell->spell_id, castspell->target_id)) { - LogFile->write(EQEMuLog::Debug, "Unknown ability being used by %s, spell being cast is: %i\n", GetName(), castspell->spell_id); + LogFile->write(EQEmuLog::Debug, "Unknown ability being used by %s, spell being cast is: %i\n", GetName(), castspell->spell_id); InterruptSpell(castspell->spell_id); } return; @@ -4171,7 +4172,7 @@ void Client::Handle_OP_ClearBlockedBuffs(const EQApplicationPacket *app) if (app->size != 1) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_ClearBlockedBuffs expected 1 got %i", app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_ClearBlockedBuffs expected 1 got %i", app->size); DumpPacket(app); @@ -4193,7 +4194,7 @@ void Client::Handle_OP_ClearNPCMarks(const EQApplicationPacket *app) if (app->size != 0) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_ClearNPCMarks expected 0 got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_ClearNPCMarks expected 0 got %i", app->size); DumpPacket(app); @@ -4215,7 +4216,7 @@ void Client::Handle_OP_ClearSurname(const EQApplicationPacket *app) void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app) { if (app->size != sizeof(ClickDoor_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_ClickDoor, size=%i, expected %i", app->size, sizeof(ClickDoor_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_ClickDoor, size=%i, expected %i", app->size, sizeof(ClickDoor_Struct)); return; } ClickDoor_Struct* cd = (ClickDoor_Struct*)app->pBuffer; @@ -4240,7 +4241,7 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app) void Client::Handle_OP_ClickObject(const EQApplicationPacket *app) { if (app->size != sizeof(ClickObject_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size on ClickObject_Struct: Expected %i, Got %i", + LogFile->write(EQEmuLog::Error, "Invalid size on ClickObject_Struct: Expected %i, Got %i", sizeof(ClickObject_Struct), app->size); return; } @@ -4291,7 +4292,7 @@ void Client::Handle_OP_ClickObjectAction(const EQApplicationPacket *app) else { if (app->size != sizeof(ClickObjectAction_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size on OP_ClickObjectAction: Expected %i, Got %i", + LogFile->write(EQEmuLog::Error, "Invalid size on OP_ClickObjectAction: Expected %i, Got %i", sizeof(ClickObjectAction_Struct), app->size); return; } @@ -4304,11 +4305,11 @@ void Client::Handle_OP_ClickObjectAction(const EQApplicationPacket *app) object->Close(); } else { - LogFile->write(EQEMuLog::Error, "Unsupported action %d in OP_ClickObjectAction", oos->open); + LogFile->write(EQEmuLog::Error, "Unsupported action %d in OP_ClickObjectAction", oos->open); } } else { - LogFile->write(EQEMuLog::Error, "Invalid object %d in OP_ClickObjectAction", oos->drop_id); + LogFile->write(EQEmuLog::Error, "Invalid object %d in OP_ClickObjectAction", oos->drop_id); } } @@ -4325,8 +4326,8 @@ void Client::Handle_OP_ClickObjectAction(const EQApplicationPacket *app) void Client::Handle_OP_ClientError(const EQApplicationPacket *app) { ClientError_Struct* error = (ClientError_Struct*)app->pBuffer; - LogFile->write(EQEMuLog::Error, "Client error: %s", error->character_name); - LogFile->write(EQEMuLog::Error, "Error message:%s", error->message); + LogFile->write(EQEmuLog::Error, "Client error: %s", error->character_name); + LogFile->write(EQEmuLog::Error, "Error message:%s", error->message); return; } @@ -4347,7 +4348,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) if (app->size != sizeof(PlayerPositionUpdateClient_Struct) && app->size != (sizeof(PlayerPositionUpdateClient_Struct)+1) ) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_ClientUpdate expected:%i got:%i", sizeof(PlayerPositionUpdateClient_Struct), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_ClientUpdate expected:%i got:%i", sizeof(PlayerPositionUpdateClient_Struct), app->size); return; } PlayerPositionUpdateClient_Struct* ppu = (PlayerPositionUpdateClient_Struct*)app->pBuffer; @@ -4686,7 +4687,7 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app) { if (app->size != sizeof(Consider_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in Consider expected %i got %i", sizeof(Consider_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in Consider expected %i got %i", sizeof(Consider_Struct), app->size); return; } Consider_Struct* conin = (Consider_Struct*)app->pBuffer; @@ -4780,7 +4781,7 @@ void Client::Handle_OP_ConsiderCorpse(const EQApplicationPacket *app) { if (app->size != sizeof(Consider_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in Consider corpse expected %i got %i", sizeof(Consider_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in Consider corpse expected %i got %i", sizeof(Consider_Struct), app->size); return; } Consider_Struct* conin = (Consider_Struct*)app->pBuffer; @@ -4840,7 +4841,7 @@ void Client::Handle_OP_Consume(const EQApplicationPacket *app) { if (app->size != sizeof(Consume_Struct)) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_Consume expected:%i got:%i", sizeof(Consume_Struct), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_Consume expected:%i got:%i", sizeof(Consume_Struct), app->size); return; } Consume_Struct* pcs = (Consume_Struct*)app->pBuffer; @@ -4877,7 +4878,7 @@ void Client::Handle_OP_Consume(const EQApplicationPacket *app) ItemInst *myitem = GetInv().GetItem(pcs->slot); if (myitem == nullptr) { - LogFile->write(EQEMuLog::Error, "Consuming from empty slot %d", pcs->slot); + LogFile->write(EQEmuLog::Error, "Consuming from empty slot %d", pcs->slot); return; } @@ -4889,7 +4890,7 @@ void Client::Handle_OP_Consume(const EQApplicationPacket *app) Consume(eat_item, ItemTypeDrink, pcs->slot, (pcs->auto_consumed == 0xffffffff)); } else { - LogFile->write(EQEMuLog::Error, "OP_Consume: unknown type, type:%i", (int)pcs->type); + LogFile->write(EQEmuLog::Error, "OP_Consume: unknown type, type:%i", (int)pcs->type); return; } if (m_pp.hunger_level > 50000) @@ -4910,7 +4911,7 @@ void Client::Handle_OP_Consume(const EQApplicationPacket *app) void Client::Handle_OP_ControlBoat(const EQApplicationPacket *app) { if (app->size != sizeof(ControlBoat_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_ControlBoat, size=%i, expected %i", app->size, sizeof(ControlBoat_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_ControlBoat, size=%i, expected %i", app->size, sizeof(ControlBoat_Struct)); return; } ControlBoat_Struct* cbs = (ControlBoat_Struct*)app->pBuffer; @@ -5066,7 +5067,7 @@ void Client::Handle_OP_CrystalReclaim(const EQApplicationPacket *app) void Client::Handle_OP_Damage(const EQApplicationPacket *app) { if (app->size != sizeof(CombatDamage_Struct)) { - LogFile->write(EQEMuLog::Error, "Received invalid sized OP_Damage: got %d, expected %d", app->size, + LogFile->write(EQEmuLog::Error, "Received invalid sized OP_Damage: got %d, expected %d", app->size, sizeof(CombatDamage_Struct)); DumpPacket(app); return; @@ -5105,7 +5106,7 @@ void Client::Handle_OP_DelegateAbility(const EQApplicationPacket *app) if (app->size != sizeof(DelegateAbility_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_DelegateAbility expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_DelegateAbility expected %i got %i", sizeof(DelegateAbility_Struct), app->size); DumpPacket(app); @@ -5196,7 +5197,7 @@ void Client::Handle_OP_DeleteSpawn(const EQApplicationPacket *app) entity_list.QueueClients(this, outapp, false); safe_delete(outapp); - hate_list.RemoveEnt(this->CastToMob()); + hate_list.RemoveEntFromHateList(this->CastToMob()); Disconnect(); return; @@ -5280,7 +5281,7 @@ void Client::Handle_OP_DoGroupLeadershipAbility(const EQApplicationPacket *app) if (app->size != sizeof(DoGroupLeadershipAbility_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_DoGroupLeadershipAbility expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_DoGroupLeadershipAbility expected %i got %i", sizeof(DoGroupLeadershipAbility_Struct), app->size); DumpPacket(app); @@ -5332,7 +5333,7 @@ void Client::Handle_OP_DoGroupLeadershipAbility(const EQApplicationPacket *app) } default: - LogFile->write(EQEMuLog::Debug, "Got unhandled OP_DoGroupLeadershipAbility Ability: %d Parameter: %d", + LogFile->write(EQEmuLog::Debug, "Got unhandled OP_DoGroupLeadershipAbility Ability: %d Parameter: %d", dglas->Ability, dglas->Parameter); break; } @@ -5414,7 +5415,7 @@ void Client::Handle_OP_Dye(const EQApplicationPacket *app) void Client::Handle_OP_Emote(const EQApplicationPacket *app) { if (app->size != sizeof(Emote_Struct)) { - LogFile->write(EQEMuLog::Error, "Received invalid sized " + LogFile->write(EQEmuLog::Error, "Received invalid sized " "OP_Emote: got %d, expected %d", app->size, sizeof(Emote_Struct)); DumpPacket(app); @@ -5505,7 +5506,7 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app) } if (app->size != sizeof(EnvDamage2_Struct)) { - LogFile->write(EQEMuLog::Error, "Received invalid sized OP_EnvDamage: got %d, expected %d", app->size, + LogFile->write(EQEmuLog::Error, "Received invalid sized OP_EnvDamage: got %d, expected %d", app->size, sizeof(EnvDamage2_Struct)); DumpPacket(app); return; @@ -5560,7 +5561,7 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app) void Client::Handle_OP_FaceChange(const EQApplicationPacket *app) { if (app->size != sizeof(FaceChange_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for OP_FaceChange: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for OP_FaceChange: Expected: %i, Got: %i", sizeof(FaceChange_Struct), app->size); return; } @@ -5829,7 +5830,7 @@ void Client::Handle_OP_GMBecomeNPC(const EQApplicationPacket *app) return; } if (app->size != sizeof(BecomeNPC_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GMBecomeNPC, size=%i, expected %i", app->size, sizeof(BecomeNPC_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GMBecomeNPC, size=%i, expected %i", app->size, sizeof(BecomeNPC_Struct)); return; } //entity_list.QueueClients(this, app, false); @@ -5881,7 +5882,7 @@ void Client::Handle_OP_GMEmoteZone(const EQApplicationPacket *app) return; } if (app->size != sizeof(GMEmoteZone_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GMEmoteZone, size=%i, expected %i", app->size, sizeof(GMEmoteZone_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GMEmoteZone, size=%i, expected %i", app->size, sizeof(GMEmoteZone_Struct)); return; } GMEmoteZone_Struct* gmez = (GMEmoteZone_Struct*)app->pBuffer; @@ -5898,7 +5899,7 @@ void Client::Handle_OP_GMEmoteZone(const EQApplicationPacket *app) void Client::Handle_OP_GMEndTraining(const EQApplicationPacket *app) { if (app->size != sizeof(GMTrainEnd_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_GMEndTraining expected %i got %i", sizeof(GMTrainEnd_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_GMEndTraining expected %i got %i", sizeof(GMTrainEnd_Struct), app->size); DumpPacket(app); return; } @@ -5914,7 +5915,7 @@ void Client::Handle_OP_GMFind(const EQApplicationPacket *app) return; } if (app->size != sizeof(GMSummon_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GMFind, size=%i, expected %i", app->size, sizeof(GMSummon_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GMFind, size=%i, expected %i", app->size, sizeof(GMSummon_Struct)); return; } //Break down incoming @@ -5979,7 +5980,7 @@ void Client::Handle_OP_GMHideMe(const EQApplicationPacket *app) return; } if (app->size != sizeof(SpawnAppearance_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GMHideMe, size=%i, expected %i", app->size, sizeof(SpawnAppearance_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GMHideMe, size=%i, expected %i", app->size, sizeof(SpawnAppearance_Struct)); return; } SpawnAppearance_Struct* sa = (SpawnAppearance_Struct*)app->pBuffer; @@ -6029,7 +6030,7 @@ void Client::Handle_OP_GMKill(const EQApplicationPacket *app) return; } if (app->size != sizeof(GMKill_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GMKill, size=%i, expected %i", app->size, sizeof(GMKill_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GMKill, size=%i, expected %i", app->size, sizeof(GMKill_Struct)); return; } GMKill_Struct* gmk = (GMKill_Struct *)app->pBuffer; @@ -6096,7 +6097,7 @@ void Client::Handle_OP_GMLastName(const EQApplicationPacket *app) void Client::Handle_OP_GMNameChange(const EQApplicationPacket *app) { if (app->size != sizeof(GMName_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GMNameChange, size=%i, expected %i", app->size, sizeof(GMName_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GMNameChange, size=%i, expected %i", app->size, sizeof(GMName_Struct)); return; } const GMName_Struct* gmn = (const GMName_Struct *)app->pBuffer; @@ -6106,7 +6107,7 @@ void Client::Handle_OP_GMNameChange(const EQApplicationPacket *app) return; } Client* client = entity_list.GetClientByName(gmn->oldname); - LogFile->write(EQEMuLog::Status, "GM(%s) changeing players name. Old:%s New:%s", GetName(), gmn->oldname, gmn->newname); + LogFile->write(EQEmuLog::Status, "GM(%s) changeing players name. Old:%s New:%s", GetName(), gmn->oldname, gmn->newname); bool usedname = database.CheckUsedName((const char*)gmn->newname); if (client == 0) { Message(13, "%s not found for name change. Operation failed!", gmn->oldname); @@ -6148,7 +6149,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) if (app->size < sizeof(GMSearchCorpse_Struct)) { - LogFile->write(EQEMuLog::Debug, "OP_GMSearchCorpse size lower than expected: got %u expected at least %u", + LogFile->write(EQEmuLog::Debug, "OP_GMSearchCorpse size lower than expected: got %u expected at least %u", app->size, sizeof(GMSearchCorpse_Struct)); DumpPacket(app); return; @@ -6271,7 +6272,7 @@ void Client::Handle_OP_GMToggle(const EQApplicationPacket *app) void Client::Handle_OP_GMTraining(const EQApplicationPacket *app) { if (app->size != sizeof(GMTrainee_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_GMTraining expected %i got %i", sizeof(GMTrainee_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_GMTraining expected %i got %i", sizeof(GMTrainee_Struct), app->size); DumpPacket(app); return; } @@ -6282,7 +6283,7 @@ void Client::Handle_OP_GMTraining(const EQApplicationPacket *app) void Client::Handle_OP_GMTrainSkill(const EQApplicationPacket *app) { if (app->size != sizeof(GMSkillChange_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_GMTrainSkill expected %i got %i", sizeof(GMSkillChange_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_GMTrainSkill expected %i got %i", sizeof(GMSkillChange_Struct), app->size); DumpPacket(app); return; } @@ -6350,7 +6351,7 @@ void Client::Handle_OP_GMZoneRequest2(const EQApplicationPacket *app) return; } if (app->size < sizeof(uint32)) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_GMZoneRequest2 expected:%i got:%i", sizeof(uint32), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_GMZoneRequest2 expected:%i got:%i", sizeof(uint32), app->size); return; } @@ -6367,7 +6368,7 @@ void Client::Handle_OP_GroupAcknowledge(const EQApplicationPacket *app) void Client::Handle_OP_GroupCancelInvite(const EQApplicationPacket *app) { if (app->size != sizeof(GroupCancel_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for OP_GroupCancelInvite: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for OP_GroupCancelInvite: Expected: %i, Got: %i", sizeof(GroupCancel_Struct), app->size); return; } @@ -6411,12 +6412,12 @@ void Client::Handle_OP_GroupDelete(const EQApplicationPacket *app) void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app) { if (app->size != sizeof(GroupGeneric_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for GroupGeneric_Struct: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for GroupGeneric_Struct: Expected: %i, Got: %i", sizeof(GroupGeneric_Struct), app->size); return; } - LogFile->write(EQEMuLog::Debug, "Member Disband Request from %s\n", GetName()); + LogFile->write(EQEmuLog::Debug, "Member Disband Request from %s\n", GetName()); GroupGeneric_Struct* gd = (GroupGeneric_Struct*)app->pBuffer; @@ -6558,7 +6559,7 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app) } else { - LogFile->write(EQEMuLog::Error, "Failed to remove player from group. Unable to find player named %s in player group", gd->name2); + LogFile->write(EQEmuLog::Error, "Failed to remove player from group. Unable to find player named %s in player group", gd->name2); } } if (LFP) @@ -6578,7 +6579,7 @@ void Client::Handle_OP_GroupFollow(const EQApplicationPacket *app) void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app) { if (app->size != sizeof(GroupGeneric_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for OP_GroupFollow: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for OP_GroupFollow: Expected: %i, Got: %i", sizeof(GroupGeneric_Struct), app->size); return; } @@ -6627,7 +6628,7 @@ void Client::Handle_OP_GroupInvite(const EQApplicationPacket *app) void Client::Handle_OP_GroupInvite2(const EQApplicationPacket *app) { if (app->size != sizeof(GroupInvite_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for OP_GroupInvite: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for OP_GroupInvite: Expected: %i, Got: %i", sizeof(GroupInvite_Struct), app->size); return; } @@ -6696,7 +6697,7 @@ void Client::Handle_OP_GroupMakeLeader(const EQApplicationPacket *app) if (g->IsLeader(this)) g->ChangeLeader(NewLeader); else { - LogFile->write(EQEMuLog::Debug, "Group /makeleader request originated from non-leader member: %s", GetName()); + LogFile->write(EQEmuLog::Debug, "Group /makeleader request originated from non-leader member: %s", GetName()); DumpPacket(app); } } @@ -6705,7 +6706,7 @@ void Client::Handle_OP_GroupMakeLeader(const EQApplicationPacket *app) void Client::Handle_OP_GroupMentor(const EQApplicationPacket *app) { if (app->size != sizeof(GroupMentor_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GroupMentor, size=%i, expected %i", app->size, sizeof(GroupMentor_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GroupMentor, size=%i, expected %i", app->size, sizeof(GroupMentor_Struct)); DumpPacket(app); return; } @@ -6741,7 +6742,7 @@ void Client::Handle_OP_GroupMentor(const EQApplicationPacket *app) void Client::Handle_OP_GroupRoles(const EQApplicationPacket *app) { if (app->size != sizeof(GroupRole_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GroupRoles, size=%i, expected %i", app->size, sizeof(GroupRole_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GroupRoles, size=%i, expected %i", app->size, sizeof(GroupRole_Struct)); DumpPacket(app); return; } @@ -6787,7 +6788,7 @@ void Client::Handle_OP_GroupUpdate(const EQApplicationPacket *app) { if (app->size != sizeof(GroupUpdate_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch on OP_GroupUpdate: got %u expected %u", + LogFile->write(EQEmuLog::Debug, "Size mismatch on OP_GroupUpdate: got %u expected %u", app->size, sizeof(GroupUpdate_Struct)); DumpPacket(app); return; @@ -6806,7 +6807,7 @@ void Client::Handle_OP_GroupUpdate(const EQApplicationPacket *app) if (group->IsLeader(this)) group->ChangeLeader(newleader); else { - LogFile->write(EQEMuLog::Debug, "Group /makeleader request originated from non-leader member: %s", GetName()); + LogFile->write(EQEmuLog::Debug, "Group /makeleader request originated from non-leader member: %s", GetName()); DumpPacket(app); } } @@ -6815,7 +6816,7 @@ void Client::Handle_OP_GroupUpdate(const EQApplicationPacket *app) default: { - LogFile->write(EQEMuLog::Debug, "Received unhandled OP_GroupUpdate requesting action %u", gu->action); + LogFile->write(EQEmuLog::Debug, "Received unhandled OP_GroupUpdate requesting action %u", gu->action); DumpPacket(app); return; } @@ -6835,7 +6836,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) } if (app->size < sizeof(uint32)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_GuildBank, size=%i, expected %i", app->size, sizeof(uint32)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_GuildBank, size=%i, expected %i", app->size, sizeof(uint32)); DumpPacket(app); return; } @@ -6947,37 +6948,28 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (!CursorItem->NoDrop || CursorItemInst->IsAttuned()) { - Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT); - Allowed = false; } else if (CursorItemInst->IsNoneEmptyContainer()) { - Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT); - Allowed = false; } else if (CursorItemInst->IsAugmented()) { - Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT); - Allowed = false; } else if (CursorItem->NoRent == 0) { - Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT); - Allowed = false; } else if (CursorItem->LoreFlag && GuildBanks->HasItem(GuildID(), CursorItem->ID)) { - Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT); - Allowed = false; } if (!Allowed) { + Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT); GuildBankDepositAck(true); return; @@ -7774,7 +7766,7 @@ void Client::Handle_OP_GuildStatus(const EQApplicationPacket *app) { if (app->size != sizeof(GuildStatus_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_GuildStatus expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_GuildStatus expected %i got %i", sizeof(GuildStatus_Struct), app->size); DumpPacket(app); @@ -7831,7 +7823,7 @@ void Client::Handle_OP_GuildUpdateURLAndChannel(const EQApplicationPacket *app) { if (app->size != sizeof(GuildUpdateURLAndChannel_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_GuildUpdateURLAndChannel expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_GuildUpdateURLAndChannel expected %i got %i", sizeof(GuildUpdateURLAndChannel_Struct), app->size); DumpPacket(app); @@ -7936,7 +7928,7 @@ void Client::Handle_OP_HideCorpse(const EQApplicationPacket *app) // if (app->size != sizeof(HideCorpse_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_HideCorpse expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_HideCorpse expected %i got %i", sizeof(HideCorpse_Struct), app->size); DumpPacket(app); @@ -7965,7 +7957,7 @@ void Client::Handle_OP_Ignore(const EQApplicationPacket *app) void Client::Handle_OP_Illusion(const EQApplicationPacket *app) { if (app->size != sizeof(Illusion_Struct)) { - LogFile->write(EQEMuLog::Error, "Received invalid sized OP_Illusion: got %d, expected %d", app->size, + LogFile->write(EQEmuLog::Error, "Received invalid sized OP_Illusion: got %d, expected %d", app->size, sizeof(Illusion_Struct)); DumpPacket(app); return; @@ -7995,7 +7987,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app) { if (app->size != sizeof(InspectResponse_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_InspectAnswer, size=%i, expected %i", app->size, sizeof(InspectResponse_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_InspectAnswer, size=%i, expected %i", app->size, sizeof(InspectResponse_Struct)); return; } @@ -8050,7 +8042,7 @@ void Client::Handle_OP_InspectMessageUpdate(const EQApplicationPacket *app) { if (app->size != sizeof(InspectMessage_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_InspectMessageUpdate, size=%i, expected %i", app->size, sizeof(InspectMessage_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_InspectMessageUpdate, size=%i, expected %i", app->size, sizeof(InspectMessage_Struct)); return; } @@ -8064,7 +8056,7 @@ void Client::Handle_OP_InspectRequest(const EQApplicationPacket *app) { if (app->size != sizeof(Inspect_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_InspectRequest, size=%i, expected %i", app->size, sizeof(Inspect_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_InspectRequest, size=%i, expected %i", app->size, sizeof(Inspect_Struct)); return; } @@ -8101,7 +8093,7 @@ void Client::Handle_OP_InstillDoubt(const EQApplicationPacket *app) void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) { if (app->size != sizeof(ItemViewRequest_Struct)){ - LogFile->write(EQEMuLog::Error, "Wrong size on OP_ItemLinkClick. Got: %i, Expected: %i", app->size, sizeof(ItemViewRequest_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size on OP_ItemLinkClick. Got: %i, Expected: %i", app->size, sizeof(ItemViewRequest_Struct)); DumpPacket(app); return; } @@ -8201,7 +8193,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) void Client::Handle_OP_ItemLinkResponse(const EQApplicationPacket *app) { if (app->size != sizeof(LDONItemViewRequest_Struct)) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_ItemLinkResponse expected:%i got:%i", sizeof(LDONItemViewRequest_Struct), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_ItemLinkResponse expected:%i got:%i", sizeof(LDONItemViewRequest_Struct), app->size); return; } LDONItemViewRequest_Struct* item = (LDONItemViewRequest_Struct*)app->pBuffer; @@ -8216,7 +8208,7 @@ void Client::Handle_OP_ItemLinkResponse(const EQApplicationPacket *app) void Client::Handle_OP_ItemName(const EQApplicationPacket *app) { if (app->size != sizeof(ItemNamePacket_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for ItemNamePacket_Struct: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for ItemNamePacket_Struct: Expected: %i, Got: %i", sizeof(ItemNamePacket_Struct), app->size); return; } @@ -8414,7 +8406,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) { if (app->size != sizeof(ItemVerifyRequest_Struct)) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_ItemVerifyRequest expected:%i got:%i", sizeof(ItemVerifyRequest_Struct), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_ItemVerifyRequest expected:%i got:%i", sizeof(ItemVerifyRequest_Struct), app->size); return; } @@ -8442,7 +8434,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } if (slot_id < 0) { - LogFile->write(EQEMuLog::Debug, "Unknown slot being used by %s, slot being used is: %i", GetName(), request->slot); + LogFile->write(EQEmuLog::Debug, "Unknown slot being used by %s, slot being used is: %i", GetName(), request->slot); return; } @@ -8485,7 +8477,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) return; } - LogFile->write(EQEMuLog::Debug, "OP ItemVerifyRequest: spell=%i, target=%i, inv=%i", spell_id, target_id, slot_id); + LogFile->write(EQEmuLog::Debug, "OP ItemVerifyRequest: spell=%i, target=%i, inv=%i", spell_id, target_id, slot_id); if (m_inv.SupportsClickCasting(slot_id) || ((item->ItemType == ItemTypePotion || item->PotionBelt) && m_inv.SupportsPotionBeltCasting(slot_id))) // sanity check { @@ -8523,7 +8515,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) if ((spell_id <= 0) && (item->ItemType != ItemTypeFood && item->ItemType != ItemTypeDrink && item->ItemType != ItemTypeAlcohol && item->ItemType != ItemTypeSpell)) { - LogFile->write(EQEMuLog::Debug, "Item with no effect right clicked by %s", GetName()); + LogFile->write(EQEmuLog::Debug, "Item with no effect right clicked by %s", GetName()); } else if (inst->IsType(ItemClassCommon)) { @@ -8596,7 +8588,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) { if (item->ItemType != ItemTypeFood && item->ItemType != ItemTypeDrink && item->ItemType != ItemTypeAlcohol) { - LogFile->write(EQEMuLog::Debug, "Error: unknown item->Click.Type (%i)", item->Click.Type); + LogFile->write(EQEmuLog::Debug, "Error: unknown item->Click.Type (%i)", item->Click.Type); } else { @@ -8612,7 +8604,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) else if (item->ItemType == ItemTypeAlcohol) { #if EQDEBUG >= 1 - LogFile->write(EQEMuLog::Debug, "Drinking Alcohol from slot:%i", slot_id); + LogFile->write(EQEmuLog::Debug, "Drinking Alcohol from slot:%i", slot_id); #endif // This Seems to be handled in OP_DeleteItem handling //DeleteItemInInventory(slot_id, 1, false); @@ -8639,7 +8631,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } else { - LogFile->write(EQEMuLog::Debug, "Error: unknown item->Click.Type (%i)", item->Click.Type); + LogFile->write(EQEmuLog::Debug, "Error: unknown item->Click.Type (%i)", item->Click.Type); } } } @@ -8780,7 +8772,7 @@ void Client::Handle_OP_LDoNSenseTraps(const EQApplicationPacket *app) void Client::Handle_OP_LeadershipExpToggle(const EQApplicationPacket *app) { if (app->size != 1) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_LeadershipExpToggle expected %i got %i", 1, app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_LeadershipExpToggle expected %i got %i", 1, app->size); DumpPacket(app); return; } @@ -8867,7 +8859,7 @@ void Client::Handle_OP_LFGGetMatchesRequest(const EQApplicationPacket *app) { if (app->size != sizeof(LFGGetMatchesRequest_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_LFGGetMatchesRequest, size=%i, expected %i", app->size, sizeof(LFGGetMatchesRequest_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_LFGGetMatchesRequest, size=%i, expected %i", app->size, sizeof(LFGGetMatchesRequest_Struct)); DumpPacket(app); return; } @@ -9027,7 +9019,7 @@ void Client::Handle_OP_LFPCommand(const EQApplicationPacket *app) { if (app->size != sizeof(LFP_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_LFPCommand, size=%i, expected %i", app->size, sizeof(LFP_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_LFPCommand, size=%i, expected %i", app->size, sizeof(LFP_Struct)); DumpPacket(app); return; } @@ -9064,7 +9056,7 @@ void Client::Handle_OP_LFPCommand(const EQApplicationPacket *app) // This should not happen. The client checks if you are in a group and will not let you put LFP on if // you are not the leader. if (!g->IsLeader(this)) { - LogFile->write(EQEMuLog::Error, "Client sent LFP on for character %s who is grouped but not leader.", GetName()); + LogFile->write(EQEmuLog::Error, "Client sent LFP on for character %s who is grouped but not leader.", GetName()); return; } // Fill the LFPMembers array with the rest of the group members, excluding ourself @@ -9089,7 +9081,7 @@ void Client::Handle_OP_LFPGetMatchesRequest(const EQApplicationPacket *app) { if (app->size != sizeof(LFPGetMatchesRequest_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_LFPGetMatchesRequest, size=%i, expected %i", app->size, sizeof(LFPGetMatchesRequest_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_LFPGetMatchesRequest, size=%i, expected %i", app->size, sizeof(LFPGetMatchesRequest_Struct)); DumpPacket(app); return; } @@ -9145,15 +9137,9 @@ void Client::Handle_OP_Logout(const EQApplicationPacket *app) void Client::Handle_OP_LootItem(const EQApplicationPacket *app) { if (app->size != sizeof(LootingItem_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_LootItem, size=%i, expected %i", app->size, sizeof(LootingItem_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_LootItem, size=%i, expected %i", app->size, sizeof(LootingItem_Struct)); return; } - /* - ** fixed the looting code so that it sends the correct opcodes - ** and now correctly removes the looted item the player selected - ** as well as gives the player the proper item. - ** Also fixed a few UI lock ups that would occur. - */ EQApplicationPacket* outapp = 0; Entity* entity = entity_list.GetID(*((uint16*)app->pBuffer)); @@ -9328,7 +9314,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app) if (app->size != sizeof(MercenaryCommand_Struct)) { Message(13, "Size mismatch in OP_MercenaryCommand expected %i got %i", sizeof(MercenaryCommand_Struct), app->size); - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryCommand expected %i got %i", sizeof(MercenaryCommand_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_MercenaryCommand expected %i got %i", sizeof(MercenaryCommand_Struct), app->size); DumpPacket(app); return; } @@ -9385,7 +9371,7 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) // The payload is 4 bytes. The EntityID of the Mercenary Liason which are of class 71. if (app->size != sizeof(MercenaryMerchantShopRequest_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryDataRequest expected 4 got %i", app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_MercenaryDataRequest expected 4 got %i", app->size); DumpPacket(app); @@ -9520,7 +9506,7 @@ void Client::Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app if (app->size != 0) { Message(13, "Size mismatch in OP_MercenaryDataUpdateRequest expected 0 got %i", app->size); - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryDataUpdateRequest expected 0 got %i", app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_MercenaryDataUpdateRequest expected 0 got %i", app->size); DumpPacket(app); return; } @@ -9540,7 +9526,7 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app) if (app->size > 1) { Message(13, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size); - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size); DumpPacket(app); return; } @@ -9565,7 +9551,7 @@ void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app) // The payload is 16 bytes. First four bytes are the Merc ID (Template ID) if (app->size != sizeof(MercenaryMerchantRequest_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryHire expected %i got %i", sizeof(MercenaryMerchantRequest_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_MercenaryHire expected %i got %i", sizeof(MercenaryMerchantRequest_Struct), app->size); DumpPacket(app); @@ -9637,7 +9623,7 @@ void Client::Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app) if (app->size != sizeof(SuspendMercenary_Struct)) { Message(13, "Size mismatch in OP_MercenarySuspendRequest expected %i got %i", sizeof(SuspendMercenary_Struct), app->size); - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenarySuspendRequest expected %i got %i", sizeof(SuspendMercenary_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_MercenarySuspendRequest expected %i got %i", sizeof(SuspendMercenary_Struct), app->size); DumpPacket(app); return; } @@ -9661,7 +9647,7 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app) if (app->size > 1) { Message(13, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size); - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size); DumpPacket(app); return; } @@ -9699,7 +9685,7 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app) void Client::Handle_OP_MoveCoin(const EQApplicationPacket *app) { if (app->size != sizeof(MoveCoin_Struct)){ - LogFile->write(EQEMuLog::Error, "Wrong size on OP_MoveCoin. Got: %i, Expected: %i", app->size, sizeof(MoveCoin_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size on OP_MoveCoin. Got: %i, Expected: %i", app->size, sizeof(MoveCoin_Struct)); DumpPacket(app); return; } @@ -9715,7 +9701,7 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) } if (app->size != sizeof(MoveItem_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_MoveItem, size=%i, expected %i", app->size, sizeof(MoveItem_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_MoveItem, size=%i, expected %i", app->size, sizeof(MoveItem_Struct)); return; } @@ -9740,7 +9726,7 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) } } - // Illegal bagslot useage checks. Currently, user only receives a message if this check is triggered. + // Illegal bagslot usage checks. Currently, user only receives a message if this check is triggered. bool mi_hack = false; if (mi->from_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->from_slot <= EmuConstants::CURSOR_BAG_END) { @@ -9763,7 +9749,7 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) } } - if (mi_hack) { Message(15, "Caution: Illegal use of inaccessable bag slots!"); } + if (mi_hack) { Message(15, "Caution: Illegal use of inaccessible bag slots!"); } if (!SwapItem(mi) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) { SwapItemResync(mi); @@ -9857,7 +9843,7 @@ void Client::Handle_OP_OpenTributeMaster(const EQApplicationPacket *app) void Client::Handle_OP_PDeletePetition(const EQApplicationPacket *app) { if (app->size < 2) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_PDeletePetition, size=%i, expected %i", app->size, 2); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_PDeletePetition, size=%i, expected %i", app->size, 2); return; } if (petition_list.DeletePetitionByCharName((char*)app->pBuffer)) @@ -9870,7 +9856,7 @@ void Client::Handle_OP_PDeletePetition(const EQApplicationPacket *app) void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) { if (app->size != sizeof(PetCommand_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_PetCommands, size=%i, expected %i", app->size, sizeof(PetCommand_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_PetCommands, size=%i, expected %i", app->size, sizeof(PetCommand_Struct)); return; } char val1[20] = { 0 }; @@ -9908,12 +9894,14 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) uint32 PetCommand = pet->command; // Handle Sit/Stand toggle in UF and later. + /* if (GetClientVersion() >= EQClientUnderfoot) { if (PetCommand == PET_SITDOWN) if (mypet->GetPetOrder() == SPO_Sit) PetCommand = PET_STANDUP; } + */ switch (PetCommand) { @@ -9951,6 +9939,31 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } break; } + case PET_QATTACK: { + if (mypet->IsFeared()) + break; //prevent pet from attacking stuff while feared + + if (!GetTarget()) + break; + if (GetTarget()->IsMezzed()) { + Message_StringID(10, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName()); + break; + } + + if (!mypet->IsAttackAllowed(GetTarget())) { + mypet->Say_StringID(NOT_LEGAL_TARGET); + break; + } + + if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) { + if (GetTarget() != this && mypet->DistNoRootNoZ(*GetTarget()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) { + zone->AddAggroMob(); + mypet->AddToHateList(GetTarget(), 1); + Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName()); + } + } + break; + } case PET_BACKOFF: { if (mypet->IsFeared()) break; //keeps pet running while feared @@ -10019,13 +10032,28 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) break; } case PET_TAUNT: { + if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) { + if (mypet->CastToNPC()->IsTaunting()) + { + Message_StringID(MT_PetResponse, PET_NO_TAUNT); + mypet->CastToNPC()->SetTaunting(false); + } + else + { + Message_StringID(MT_PetResponse, PET_DO_TAUNT); + mypet->CastToNPC()->SetTaunting(true); + } + } + break; + } + case PET_TAUNT_ON: { if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) { Message_StringID(MT_PetResponse, PET_DO_TAUNT); mypet->CastToNPC()->SetTaunting(true); } break; } - case PET_NOTAUNT: { + case PET_TAUNT_OFF: { if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) { Message_StringID(MT_PetResponse, PET_NO_TAUNT); mypet->CastToNPC()->SetTaunting(false); @@ -10043,6 +10071,38 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } break; } + case PET_SIT: { + if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF + + if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) { + if (mypet->GetPetOrder() == SPO_Sit) + { + mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING); + mypet->SetPetOrder(SPO_Follow); + mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); + } + else + { + mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING); + mypet->SetPetOrder(SPO_Sit); + mypet->SetRunAnimSpeed(0); + if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet + mypet->InterruptSpell(); //No cast 4 u. //i guess the pet should start casting + mypet->SendAppearancePacket(AT_Anim, ANIM_SIT); + } + } + break; + } + case PET_STANDUP: { + if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF + + if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) { + mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING); + mypet->SetPetOrder(SPO_Follow); + mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); + } + break; + } case PET_SITDOWN: { if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF @@ -10056,17 +10116,21 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } break; } - case PET_STANDUP: { + case PET_SLUMBER: { if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF - if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) { + if (mypet->GetPetType() != petAnimation) { + // Needs to have an IsSleeping() check added and this case should toggle on/off mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING); - mypet->SetPetOrder(SPO_Follow); - mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); + mypet->SetPetOrder(SPO_Sit); + mypet->SetRunAnimSpeed(0); + if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet + mypet->InterruptSpell(); //No cast 4 u. //i guess the pet should start casting + mypet->SendAppearancePacket(AT_Anim, ANIM_DEATH); } break; } - case PET_SLUMBER: { + case PET_SLUMBER_ON: { if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if (mypet->GetPetType() != petAnimation) { @@ -10079,14 +10143,32 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } break; } + case PET_SLUMBER_OFF: { + if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF + + if (mypet->GetPetType() != petAnimation) { + mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING); + mypet->SetPetOrder(SPO_Follow); + mypet->SetRunAnimSpeed(mypet->GetBaseRunspeed()); + mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); + } + break; + } case PET_HOLD: { if (GetAA(aaPetDiscipline) && mypet->IsNPC()){ if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF - mypet->Say_StringID(MT_PetResponse, PET_ON_HOLD); - mypet->WipeHateList(); - mypet->SetHeld(true); + if (mypet->IsHeld()) + { + mypet->SetHeld(false); + } + else + { + mypet->Say_StringID(MT_PetResponse, PET_ON_HOLD); + mypet->WipeHateList(); + mypet->SetHeld(true); + } } break; } @@ -10106,7 +10188,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) mypet->SetHeld(false); break; } - case PET_NOCAST: { + case PET_SPELLHOLD: { if (GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) { if (mypet->IsFeared()) break; @@ -10121,6 +10203,28 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } break; } + case PET_SPELLHOLD_ON: { + if (GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) { + if (mypet->IsFeared()) + break; + if (!mypet->IsNoCast()) { + Message_StringID(MT_PetResponse, PET_NOT_CASTING); + mypet->CastToNPC()->SetNoCast(true); + } + } + break; + } + case PET_SPELLHOLD_OFF: { + if (GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) { + if (mypet->IsFeared()) + break; + if (mypet->IsNoCast()) { + Message_StringID(MT_PetResponse, PET_CASTING); + mypet->CastToNPC()->SetNoCast(false); + } + } + break; + } case PET_FOCUS: { if (GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) { if (mypet->IsFeared()) @@ -10215,7 +10319,7 @@ void Client::Handle_OP_PetitionBug(const EQApplicationPacket *app) void Client::Handle_OP_PetitionCheckIn(const EQApplicationPacket *app) { if (app->size != sizeof(Petition_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_PetitionCheckIn, size=%i, expected %i", app->size, sizeof(Petition_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_PetitionCheckIn, size=%i, expected %i", app->size, sizeof(Petition_Struct)); return; } Petition_Struct* inpet = (Petition_Struct*)app->pBuffer; @@ -10259,7 +10363,7 @@ void Client::Handle_OP_PetitionCheckout(const EQApplicationPacket *app) void Client::Handle_OP_PetitionDelete(const EQApplicationPacket *app) { if (app->size != sizeof(PetitionUpdate_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_PetitionDelete, size=%i, expected %i", app->size, sizeof(PetitionUpdate_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_PetitionDelete, size=%i, expected %i", app->size, sizeof(PetitionUpdate_Struct)); return; } EQApplicationPacket* outapp = new EQApplicationPacket(OP_PetitionUpdate, sizeof(PetitionUpdate_Struct)); @@ -10329,7 +10433,7 @@ void Client::Handle_OP_PickPocket(const EQApplicationPacket *app) { if (app->size != sizeof(PickPocket_Struct)) { - LogFile->write(EQEMuLog::Error, "Size mismatch for Pick Pocket packet"); + LogFile->write(EQEmuLog::Error, "Size mismatch for Pick Pocket packet"); DumpPacket(app); } @@ -10399,7 +10503,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app) { if (app->size != sizeof(PopupResponse_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_PopupResponse expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_PopupResponse expected %i got %i", sizeof(PopupResponse_Struct), app->size); DumpPacket(app); return; @@ -10434,7 +10538,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app) void Client::Handle_OP_PotionBelt(const EQApplicationPacket *app) { if (app->size != sizeof(MovePotionToBelt_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_PotionBelt expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_PotionBelt expected %i got %i", sizeof(MovePotionToBelt_Struct), app->size); DumpPacket(app); return; @@ -10442,7 +10546,7 @@ void Client::Handle_OP_PotionBelt(const EQApplicationPacket *app) MovePotionToBelt_Struct *mptbs = (MovePotionToBelt_Struct*)app->pBuffer; if(!EQEmu::ValueWithin(mptbs->SlotNumber, 0U, 3U)) { - LogFile->write(EQEMuLog::Debug, "Client::Handle_OP_PotionBelt mptbs->SlotNumber out of range."); + LogFile->write(EQEmuLog::Debug, "Client::Handle_OP_PotionBelt mptbs->SlotNumber out of range."); return; } @@ -10465,7 +10569,7 @@ void Client::Handle_OP_PotionBelt(const EQApplicationPacket *app) void Client::Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app) { if (app->size != sizeof(uint32)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_LeadershipExpToggle expected %i got %i", 1, app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_LeadershipExpToggle expected %i got %i", 1, app->size); DumpPacket(app); return; } @@ -10555,7 +10659,7 @@ void Client::Handle_OP_PVPLeaderBoardDetailsRequest(const EQApplicationPacket *a // if (app->size != sizeof(PVPLeaderBoardDetailsRequest_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_PVPLeaderBoardDetailsRequest expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_PVPLeaderBoardDetailsRequest expected %i got %i", sizeof(PVPLeaderBoardDetailsRequest_Struct), app->size); DumpPacket(app); @@ -10582,7 +10686,7 @@ void Client::Handle_OP_PVPLeaderBoardRequest(const EQApplicationPacket *app) // if (app->size != sizeof(PVPLeaderBoardRequest_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_PVPLeaderBoardRequest expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_PVPLeaderBoardRequest expected %i got %i", sizeof(PVPLeaderBoardRequest_Struct), app->size); DumpPacket(app); @@ -10603,7 +10707,7 @@ void Client::Handle_OP_PVPLeaderBoardRequest(const EQApplicationPacket *app) void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) { if (app->size < sizeof(RaidGeneral_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_RaidCommand, size=%i, expected at least %i", app->size, sizeof(RaidGeneral_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_RaidCommand, size=%i, expected at least %i", app->size, sizeof(RaidGeneral_Struct)); DumpPacket(app); return; } @@ -11188,7 +11292,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) void Client::Handle_OP_RandomReq(const EQApplicationPacket *app) { if (app->size != sizeof(RandomReq_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_RandomReq, size=%i, expected %i", app->size, sizeof(RandomReq_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_RandomReq, size=%i, expected %i", app->size, sizeof(RandomReq_Struct)); return; } const RandomReq_Struct* rndq = (const RandomReq_Struct*)app->pBuffer; @@ -11217,7 +11321,7 @@ void Client::Handle_OP_RandomReq(const EQApplicationPacket *app) void Client::Handle_OP_ReadBook(const EQApplicationPacket *app) { if (app->size != sizeof(BookRequest_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_ReadBook, size=%i, expected %i", app->size, sizeof(BookRequest_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_ReadBook, size=%i, expected %i", app->size, sizeof(BookRequest_Struct)); return; } BookRequest_Struct* book = (BookRequest_Struct*)app->pBuffer; @@ -11233,7 +11337,7 @@ void Client::Handle_OP_ReadBook(const EQApplicationPacket *app) void Client::Handle_OP_RecipeAutoCombine(const EQApplicationPacket *app) { if (app->size != sizeof(RecipeAutoCombine_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for RecipeAutoCombine_Struct: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for RecipeAutoCombine_Struct: Expected: %i, Got: %i", sizeof(RecipeAutoCombine_Struct), app->size); return; } @@ -11247,7 +11351,7 @@ void Client::Handle_OP_RecipeAutoCombine(const EQApplicationPacket *app) void Client::Handle_OP_RecipeDetails(const EQApplicationPacket *app) { if (app->size < sizeof(uint32)) { - LogFile->write(EQEMuLog::Error, "Invalid size for RecipeDetails Request: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for RecipeDetails Request: Expected: %i, Got: %i", sizeof(uint32), app->size); return; } @@ -11261,14 +11365,14 @@ void Client::Handle_OP_RecipeDetails(const EQApplicationPacket *app) void Client::Handle_OP_RecipesFavorite(const EQApplicationPacket *app) { if (app->size != sizeof(TradeskillFavorites_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for TradeskillFavorites_Struct: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for TradeskillFavorites_Struct: Expected: %i, Got: %i", sizeof(TradeskillFavorites_Struct), app->size); return; } TradeskillFavorites_Struct* tsf = (TradeskillFavorites_Struct*)app->pBuffer; - LogFile->write(EQEMuLog::Debug, "Requested Favorites for: %d - %d\n", tsf->object_type, tsf->some_id); + LogFile->write(EQEmuLog::Debug, "Requested Favorites for: %d - %d\n", tsf->object_type, tsf->some_id); // results show that object_type is combiner type // some_id = 0 if world combiner, item number otherwise @@ -11320,7 +11424,7 @@ void Client::Handle_OP_RecipesFavorite(const EQApplicationPacket *app) void Client::Handle_OP_RecipesSearch(const EQApplicationPacket *app) { if (app->size != sizeof(RecipesSearch_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for RecipesSearch_Struct: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for RecipesSearch_Struct: Expected: %i, Got: %i", sizeof(RecipesSearch_Struct), app->size); return; } @@ -11329,7 +11433,7 @@ void Client::Handle_OP_RecipesSearch(const EQApplicationPacket *app) rss->query[55] = '\0'; //just to be sure. - LogFile->write(EQEMuLog::Debug, "Requested search recipes for: %d - %d\n", rss->object_type, rss->some_id); + LogFile->write(EQEmuLog::Debug, "Requested search recipes for: %d - %d\n", rss->object_type, rss->some_id); // make where clause segment for container(s) char containers[30]; @@ -11389,7 +11493,7 @@ void Client::Handle_OP_RemoveBlockedBuffs(const EQApplicationPacket *app) if (app->size != sizeof(BlockedBuffs_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_RemoveBlockedBuffs expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_RemoveBlockedBuffs expected %i got %i", sizeof(BlockedBuffs_Struct), app->size); DumpPacket(app); @@ -11552,7 +11656,7 @@ void Client::Handle_OP_RespawnWindow(const EQApplicationPacket *app) // if (app->size != 4) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_RespawnWindow expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_RespawnWindow expected %i got %i", 4, app->size); DumpPacket(app); return; @@ -11603,14 +11707,14 @@ void Client::Handle_OP_Sacrifice(const EQApplicationPacket *app) { if (app->size != sizeof(Sacrifice_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_Sacrifice expected %i got %i", sizeof(Sacrifice_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_Sacrifice expected %i got %i", sizeof(Sacrifice_Struct), app->size); DumpPacket(app); return; } Sacrifice_Struct *ss = (Sacrifice_Struct*)app->pBuffer; if (!PendingSacrifice) { - LogFile->write(EQEMuLog::Error, "Unexpected OP_Sacrifice reply"); + LogFile->write(EQEmuLog::Error, "Unexpected OP_Sacrifice reply"); DumpPacket(app); return; } @@ -11654,7 +11758,7 @@ void Client::Handle_OP_SelectTribute(const EQApplicationPacket *app) //we should enforce being near a real tribute master to change this //but im not sure how I wanna do that right now. if (app->size != sizeof(SelectTributeReq_Struct)) - LogFile->write(EQEMuLog::Error, "Invalid size on OP_SelectTribute packet"); + LogFile->write(EQEmuLog::Error, "Invalid size on OP_SelectTribute packet"); else { SelectTributeReq_Struct *t = (SelectTributeReq_Struct *)app->pBuffer; SendTributeDetails(t->client_id, t->tribute_id); @@ -11768,7 +11872,7 @@ void Client::Handle_OP_SetRunMode(const EQApplicationPacket *app) void Client::Handle_OP_SetServerFilter(const EQApplicationPacket *app) { if (app->size != sizeof(SetServerFilter_Struct)) { - LogFile->write(EQEMuLog::Error, "Received invalid sized " + LogFile->write(EQEmuLog::Error, "Received invalid sized " "OP_SetServerFilter: got %d, expected %d", app->size, sizeof(SetServerFilter_Struct)); DumpPacket(app); @@ -11788,7 +11892,7 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app) } if (app->size < 1) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_SetStartCity, size=%i, expected %i", app->size, 1); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_SetStartCity, size=%i, expected %i", app->size, 1); DumpPacket(app); return; } @@ -11802,7 +11906,7 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app) m_pp.class_, m_pp.deity, m_pp.race); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "No valid start zones found for /setstartcity"); + LogFile->write(EQEmuLog::Error, "No valid start zones found for /setstartcity"); return; } @@ -11853,7 +11957,7 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app) void Client::Handle_OP_SetTitle(const EQApplicationPacket *app) { if (app->size != sizeof(SetTitle_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_SetTitle expected %i got %i", sizeof(SetTitle_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_SetTitle expected %i got %i", sizeof(SetTitle_Struct), app->size); DumpPacket(app); return; } @@ -11877,7 +11981,7 @@ void Client::Handle_OP_SetTitle(const EQApplicationPacket *app) void Client::Handle_OP_Shielding(const EQApplicationPacket *app) { if (app->size != sizeof(Shielding_Struct)) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_Shielding expected:%i got:%i", sizeof(Shielding_Struct), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_Shielding expected:%i got:%i", sizeof(Shielding_Struct), app->size); return; } if (GetClass() != WARRIOR) @@ -11974,7 +12078,7 @@ void Client::Handle_OP_ShopEnd(const EQApplicationPacket *app) void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) { if (app->size != sizeof(Merchant_Sell_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size on OP_ShopPlayerBuy: Expected %i, Got %i", + LogFile->write(EQEmuLog::Error, "Invalid size on OP_ShopPlayerBuy: Expected %i, Got %i", sizeof(Merchant_Sell_Struct), app->size); return; } @@ -11982,7 +12086,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) t1.start(); Merchant_Sell_Struct* mp = (Merchant_Sell_Struct*)app->pBuffer; #if EQDEBUG >= 5 - LogFile->write(EQEMuLog::Debug, "%s, purchase item..", GetName()); + LogFile->write(EQEmuLog::Debug, "%s, purchase item..", GetName()); DumpPacket(app); #endif @@ -12142,7 +12246,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) SendItemPacket(freeslotid, inst, ItemPacketTrade); } else if (!stacked){ - LogFile->write(EQEMuLog::Error, "OP_ShopPlayerBuy: item->ItemClass Unknown! Type: %i", item->ItemClass); + LogFile->write(EQEmuLog::Error, "OP_ShopPlayerBuy: item->ItemClass Unknown! Type: %i", item->ItemClass); } QueuePacket(outapp); if (inst && tmpmer_used){ @@ -12232,7 +12336,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) { if (app->size != sizeof(Merchant_Purchase_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size on OP_ShopPlayerSell: Expected %i, Got %i", + LogFile->write(EQEmuLog::Error, "Invalid size on OP_ShopPlayerSell: Expected %i, Got %i", sizeof(Merchant_Purchase_Struct), app->size); return; } @@ -12299,22 +12403,30 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) int freeslot = 0; if (charges > 0 && (freeslot = zone->SaveTempItem(vendor->CastToNPC()->MerchantType, vendor->GetNPCTypeID(), itemid, charges, true)) > 0){ ItemInst* inst2 = inst->Clone(); - if (RuleB(Merchant, UsePriceMod)){ - inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate*Client::CalcPriceMod(vendor, false)); + + while (true) { + if (inst2 == nullptr) + break; + + if (RuleB(Merchant, UsePriceMod)){ + inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate*Client::CalcPriceMod(vendor, false)); + } + else + inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate); + inst2->SetMerchantSlot(freeslot); + + uint32 MerchantQuantity = zone->GetTempMerchantQuantity(vendor->GetNPCTypeID(), freeslot); + + if (inst2->IsStackable()) { + inst2->SetCharges(MerchantQuantity); + } + inst2->SetMerchantCount(MerchantQuantity); + + SendItemPacket(freeslot - 1, inst2, ItemPacketMerchant); + safe_delete(inst2); + + break; } - else - inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate); - inst2->SetMerchantSlot(freeslot); - - uint32 MerchantQuantity = zone->GetTempMerchantQuantity(vendor->GetNPCTypeID(), freeslot); - - if (inst2->IsStackable()) { - inst2->SetCharges(MerchantQuantity); - } - inst2->SetMerchantCount(MerchantQuantity); - - SendItemPacket(freeslot - 1, inst2, ItemPacketMerchant); - safe_delete(inst2); } // start QS code @@ -12380,7 +12492,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app) { if (app->size != sizeof(Merchant_Click_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_ShopRequest, size=%i, expected %i", app->size, sizeof(Merchant_Click_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_ShopRequest, size=%i, expected %i", app->size, sizeof(Merchant_Click_Struct)); return; } @@ -12673,7 +12785,7 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app) void Client::Handle_OP_Split(const EQApplicationPacket *app) { if (app->size != sizeof(Split_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_Split, size=%i, expected %i", app->size, sizeof(Split_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_Split, size=%i, expected %i", app->size, sizeof(Split_Struct)); return; } // The client removes the money on its own, but we have to @@ -12710,7 +12822,7 @@ void Client::Handle_OP_Surname(const EQApplicationPacket *app) { if (app->size != sizeof(Surname_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in Surname expected %i got %i", sizeof(Surname_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in Surname expected %i got %i", sizeof(Surname_Struct), app->size); return; } @@ -12800,7 +12912,7 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app) void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app) { if (app->size != sizeof(ClientTarget_Struct)) { - LogFile->write(EQEMuLog::Error, "OP size error: OP_TargetMouse expected:%i got:%i", sizeof(ClientTarget_Struct), app->size); + LogFile->write(EQEmuLog::Error, "OP size error: OP_TargetMouse expected:%i got:%i", sizeof(ClientTarget_Struct), app->size); return; } @@ -13025,7 +13137,7 @@ void Client::Handle_OP_TaskHistoryRequest(const EQApplicationPacket *app) { if (app->size != sizeof(TaskHistoryRequest_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_TaskHistoryRequest expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_TaskHistoryRequest expected %i got %i", sizeof(TaskHistoryRequest_Struct), app->size); DumpPacket(app); return; @@ -13078,7 +13190,7 @@ void Client::Handle_OP_Track(const EQApplicationPacket *app) CheckIncreaseSkill(SkillTracking, nullptr, 15); if (!entity_list.MakeTrackPacket(this)) - LogFile->write(EQEMuLog::Error, "Unable to generate OP_Track packet requested by client."); + LogFile->write(EQEmuLog::Error, "Unable to generate OP_Track packet requested by client."); return; } @@ -13092,7 +13204,7 @@ void Client::Handle_OP_TrackTarget(const EQApplicationPacket *app) if (app->size != sizeof(TrackTarget_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for OP_TrackTarget: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for OP_TrackTarget: Expected: %i, Got: %i", sizeof(TrackTarget_Struct), app->size); return; } @@ -13245,7 +13357,7 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) void Client::Handle_OP_TradeBusy(const EQApplicationPacket *app) { if (app->size != sizeof(TradeBusy_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_TradeBusy, size=%i, expected %i", app->size, sizeof(TradeBusy_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_TradeBusy, size=%i, expected %i", app->size, sizeof(TradeBusy_Struct)); return; } // Trade request recipient is cancelling the trade due to being busy @@ -13391,7 +13503,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app) _log(TRADING__CLIENT, "Client::Handle_OP_Trader: Unknown TraderStruct code of: %i\n", ints->Code); - LogFile->write(EQEMuLog::Error, "Unknown TraderStruct code of: %i\n", ints->Code); + LogFile->write(EQEmuLog::Error, "Unknown TraderStruct code of: %i\n", ints->Code); } } @@ -13401,7 +13513,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app) } else { _log(TRADING__CLIENT, "Unknown size for OP_Trader: %i\n", app->size); - LogFile->write(EQEMuLog::Error, "Unknown size for OP_Trader: %i\n", app->size); + LogFile->write(EQEmuLog::Error, "Unknown size for OP_Trader: %i\n", app->size); DumpPacket(app); return; } @@ -13439,7 +13551,7 @@ void Client::Handle_OP_TraderBuy(const EQApplicationPacket *app) void Client::Handle_OP_TradeRequest(const EQApplicationPacket *app) { if (app->size != sizeof(TradeRequest_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_TradeRequest, size=%i, expected %i", app->size, sizeof(TradeRequest_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_TradeRequest, size=%i, expected %i", app->size, sizeof(TradeRequest_Struct)); return; } // Client requesting a trade session from an npc/client @@ -13475,7 +13587,7 @@ void Client::Handle_OP_TradeRequest(const EQApplicationPacket *app) void Client::Handle_OP_TradeRequestAck(const EQApplicationPacket *app) { if (app->size != sizeof(TradeRequest_Struct)) { - LogFile->write(EQEMuLog::Error, "Wrong size: OP_TradeRequestAck, size=%i, expected %i", app->size, sizeof(TradeRequest_Struct)); + LogFile->write(EQEmuLog::Error, "Wrong size: OP_TradeRequestAck, size=%i, expected %i", app->size, sizeof(TradeRequest_Struct)); return; } // Trade request recipient is acknowledging they are able to trade @@ -13546,7 +13658,7 @@ void Client::Handle_OP_TraderShop(const EQApplicationPacket *app) void Client::Handle_OP_TradeSkillCombine(const EQApplicationPacket *app) { if (app->size != sizeof(NewCombine_Struct)) { - LogFile->write(EQEMuLog::Error, "Invalid size for NewCombine_Struct: Expected: %i, Got: %i", + LogFile->write(EQEmuLog::Error, "Invalid size for NewCombine_Struct: Expected: %i, Got: %i", sizeof(NewCombine_Struct), app->size); return; } @@ -13567,7 +13679,7 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app) { if (app->size != sizeof(Translocate_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_Translocate expected %i got %i", sizeof(Translocate_Struct), app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_Translocate expected %i got %i", sizeof(Translocate_Struct), app->size); DumpPacket(app); return; } @@ -13685,7 +13797,7 @@ void Client::Handle_OP_TributeToggle(const EQApplicationPacket *app) _pkt(TRIBUTE__IN, app); if (app->size != sizeof(uint32)) - LogFile->write(EQEMuLog::Error, "Invalid size on OP_TributeToggle packet"); + LogFile->write(EQEmuLog::Error, "Invalid size on OP_TributeToggle packet"); else { uint32 *val = (uint32 *)app->pBuffer; ToggleTribute(*val ? true : false); @@ -13700,7 +13812,7 @@ void Client::Handle_OP_TributeUpdate(const EQApplicationPacket *app) //sent when the client changes their tribute settings... if (app->size != sizeof(TributeInfo_Struct)) - LogFile->write(EQEMuLog::Error, "Invalid size on OP_TributeUpdate packet"); + LogFile->write(EQEmuLog::Error, "Invalid size on OP_TributeUpdate packet"); else { TributeInfo_Struct *t = (TributeInfo_Struct *)app->pBuffer; ChangeTributeSettings(t); @@ -13712,7 +13824,7 @@ void Client::Handle_OP_VetClaimRequest(const EQApplicationPacket *app) { if (app->size < sizeof(VeteranClaimRequest)) { - LogFile->write(EQEMuLog::Debug, "OP_VetClaimRequest size lower than expected: got %u expected at least %u", + LogFile->write(EQEmuLog::Debug, "OP_VetClaimRequest size lower than expected: got %u expected at least %u", app->size, sizeof(VeteranClaimRequest)); DumpPacket(app); return; @@ -13753,7 +13865,7 @@ void Client::Handle_OP_VoiceMacroIn(const EQApplicationPacket *app) if (app->size != sizeof(VoiceMacroIn_Struct)) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_VoiceMacroIn expected %i got %i", + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_VoiceMacroIn expected %i got %i", sizeof(VoiceMacroIn_Struct), app->size); DumpPacket(app); @@ -13804,7 +13916,7 @@ void Client::Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app) { if (app->size != 1) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_XTargetAutoAddHaters, expected 1, got %i", app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_XTargetAutoAddHaters, expected 1, got %i", app->size); DumpPacket(app); return; } @@ -13816,7 +13928,7 @@ void Client::Handle_OP_XTargetRequest(const EQApplicationPacket *app) { if (app->size < 12) { - LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_XTargetRequest, expected at least 12, got %i", app->size); + LogFile->write(EQEmuLog::Debug, "Size mismatch in OP_XTargetRequest, expected at least 12, got %i", app->size); DumpPacket(app); return; } @@ -14039,7 +14151,7 @@ void Client::Handle_OP_XTargetRequest(const EQApplicationPacket *app) } default: - LogFile->write(EQEMuLog::Debug, "Unhandled XTarget Type %i", Type); + LogFile->write(EQEmuLog::Debug, "Unhandled XTarget Type %i", Type); break; } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 2c6e080c4..542390da9 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -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; } diff --git a/zone/command.cpp b/zone/command.cpp index 493555563..7bfd7ac69 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -247,7 +247,7 @@ int command_init(void) { command_add("reloadstatic","- Reload Static Zone Data",150,command_reloadstatic) || command_add("reloadquest"," - Clear quest cache (any argument causes it to also stop all timers)",150,command_reloadqst) || command_add("reloadqst"," - Clear quest cache (any argument causes it to also stop all timers)",150,command_reloadqst) || - command_add("reloadworld",nullptr,255,command_reloadworld) || + command_add("reloadworld","[0|1] - Clear quest cache (0 - no repop, 1 - repop)",255,command_reloadworld) || command_add("reloadlevelmods",nullptr,255,command_reloadlevelmods) || command_add("reloadzonepoints","- Reload zone points from database",150,command_reloadzps) || command_add("reloadzps",nullptr,0,command_reloadzps) || @@ -445,14 +445,14 @@ int command_init(void) { { cur->second->access = itr->second; #if EQDEBUG >=5 - LogFile->write(EQEMuLog::Debug, "command_init(): - Command '%s' set to access level %d." , cur->first.c_str(), itr->second); + LogFile->write(EQEmuLog::Debug, "command_init(): - Command '%s' set to access level %d." , cur->first.c_str(), itr->second); #endif } else { #ifdef COMMANDS_WARNINGS if(cur->second->access == 0) - LogFile->write(EQEMuLog::Status, "command_init(): Warning: Command '%s' defaulting to access level 0!" , cur->first.c_str()); + LogFile->write(EQEmuLog::Status, "command_init(): Warning: Command '%s' defaulting to access level 0!" , cur->first.c_str()); #endif } } @@ -497,7 +497,7 @@ int command_add(const char *command_string, const char *desc, int access, CmdFun std::string cstr(command_string); if(commandlist.count(cstr) != 0) { - LogFile->write(EQEMuLog::Error, "command_add() - Command '%s' is a duplicate - check command.cpp." , command_string); + LogFile->write(EQEmuLog::Error, "command_add() - Command '%s' is a duplicate - check command.cpp." , command_string); return(-1); } @@ -571,12 +571,12 @@ int command_realdispatch(Client *c, const char *message) #ifdef COMMANDS_LOGGING if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) { - LogFile->write(EQEMuLog::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE"); + LogFile->write(EQEmuLog::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE"); } #endif if(cur->function == nullptr) { - LogFile->write(EQEMuLog::Error, "Command '%s' has a null function\n", cstr.c_str()); + LogFile->write(EQEmuLog::Error, "Command '%s' has a null function\n", cstr.c_str()); return(-1); } else { //dispatch C++ command @@ -1348,7 +1348,7 @@ void command_viewpetition(Client *c, const Seperator *sep) if (!results.Success()) return; - LogFile->write(EQEMuLog::Normal,"View petition request from %s, petition number: %i", c->GetName(), atoi(sep->argplus[1]) ); + LogFile->write(EQEmuLog::Normal,"View petition request from %s, petition number: %i", c->GetName(), atoi(sep->argplus[1]) ); if (results.RowCount() == 0) { c->Message(13,"There was an error in your request: ID not found! Please check the Id and try again."); @@ -1373,7 +1373,7 @@ void command_petitioninfo(Client *c, const Seperator *sep) if (!results.Success()) return; - LogFile->write(EQEMuLog::Normal,"Petition information request from %s, petition number:", c->GetName(), atoi(sep->argplus[1]) ); + LogFile->write(EQEmuLog::Normal,"Petition information request from %s, petition number:", c->GetName(), atoi(sep->argplus[1]) ); if (results.RowCount() == 0) { c->Message(13,"There was an error in your request: ID not found! Please check the Id and try again."); @@ -1399,7 +1399,7 @@ void command_delpetition(Client *c, const Seperator *sep) if (!results.Success()) return; - LogFile->write(EQEMuLog::Normal,"Delete petition request from %s, petition number:", c->GetName(), atoi(sep->argplus[1]) ); + LogFile->write(EQEmuLog::Normal,"Delete petition request from %s, petition number:", c->GetName(), atoi(sep->argplus[1]) ); } @@ -1622,7 +1622,7 @@ void command_permaclass(Client *c, const Seperator *sep) c->Message(0,"Target is not a client."); else { c->Message(0, "Setting %s's class...Sending to char select.", t->GetName()); - LogFile->write(EQEMuLog::Normal,"Class change request from %s for %s, requested class:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); + LogFile->write(EQEmuLog::Normal,"Class change request from %s for %s, requested class:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); t->SetBaseClass(atoi(sep->arg[1])); t->Save(); t->Kick(); @@ -1644,7 +1644,7 @@ void command_permarace(Client *c, const Seperator *sep) c->Message(0,"Target is not a client."); else { c->Message(0, "Setting %s's race - zone to take effect",t->GetName()); - LogFile->write(EQEMuLog::Normal,"Permanant race change request from %s for %s, requested race:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); + LogFile->write(EQEmuLog::Normal,"Permanant race change request from %s for %s, requested race:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); uint32 tmp = Mob::GetDefaultGender(atoi(sep->arg[1]), t->GetBaseGender()); t->SetBaseRace(atoi(sep->arg[1])); t->SetBaseGender(tmp); @@ -1668,7 +1668,7 @@ void command_permagender(Client *c, const Seperator *sep) c->Message(0,"Target is not a client."); else { c->Message(0, "Setting %s's gender - zone to take effect",t->GetName()); - LogFile->write(EQEMuLog::Normal,"Permanant gender change request from %s for %s, requested gender:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); + LogFile->write(EQEmuLog::Normal,"Permanant gender change request from %s for %s, requested gender:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); t->SetBaseGender(atoi(sep->arg[1])); t->Save(); t->SendIllusionPacket(atoi(sep->arg[1])); @@ -2003,7 +2003,7 @@ void command_dbspawn2(Client *c, const Seperator *sep) { if (sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3)) { - LogFile->write(EQEMuLog::Normal,"Spawning database spawn"); + LogFile->write(EQEmuLog::Normal,"Spawning database spawn"); uint16 cond = 0; int16 cond_min = 0; if(sep->IsNumber(4)) { @@ -2275,7 +2275,7 @@ void command_castspell(Client *c, const Seperator *sep) void command_setlanguage(Client *c, const Seperator *sep) { - if ( strcasecmp( sep->arg[1], "list" ) == 0 ) + if (strcasecmp(sep->arg[1], "list" ) == 0 ) { c->Message(0, "Languages:"); c->Message(0, "(0) Common Tongue"); @@ -2325,7 +2325,7 @@ void command_setlanguage(Client *c, const Seperator *sep) } else { - LogFile->write(EQEMuLog::Normal,"Set language request from %s, target:%s lang_id:%i value:%i", c->GetName(), c->GetTarget()->GetName(), atoi(sep->arg[1]), atoi(sep->arg[2]) ); + LogFile->write(EQEmuLog::Normal,"Set language request from %s, target:%s lang_id:%i value:%i", c->GetName(), c->GetTarget()->GetName(), atoi(sep->arg[1]), atoi(sep->arg[2]) ); uint8 langid = (uint8)atoi(sep->arg[1]); uint8 value = (uint8)atoi(sep->arg[2]); c->GetTarget()->CastToClient()->SetLanguageSkill( langid, value ); @@ -2350,7 +2350,7 @@ void command_setskill(Client *c, const Seperator *sep) c->Message(0, " x = 0 to %d", HIGHEST_CAN_SET_SKILL); } else { - LogFile->write(EQEMuLog::Normal,"Set skill request from %s, target:%s skill_id:%i value:%i", c->GetName(), c->GetTarget()->GetName(), atoi(sep->arg[1]), atoi(sep->arg[2]) ); + LogFile->write(EQEmuLog::Normal,"Set skill request from %s, target:%s skill_id:%i value:%i", c->GetName(), c->GetTarget()->GetName(), atoi(sep->arg[1]), atoi(sep->arg[2]) ); int skill_num = atoi(sep->arg[1]); uint16 skill_value = atoi(sep->arg[2]); if(skill_num < HIGHEST_SKILL) @@ -2370,7 +2370,7 @@ void command_setskillall(Client *c, const Seperator *sep) } else { if (c->Admin() >= commandSetSkillsOther || c->GetTarget()==c || c->GetTarget()==0) { - LogFile->write(EQEMuLog::Normal,"Set ALL skill request from %s, target:%s", c->GetName(), c->GetTarget()->GetName()); + LogFile->write(EQEmuLog::Normal,"Set ALL skill request from %s, target:%s", c->GetName(), c->GetTarget()->GetName()); uint16 level = atoi(sep->arg[1]); for(SkillUseTypes skill_num=Skill1HBlunt;skill_num <= HIGHEST_SKILL;skill_num=(SkillUseTypes)(skill_num+1)) { c->GetTarget()->CastToClient()->SetSkill(skill_num, level); @@ -2460,7 +2460,7 @@ void command_spawn(Client *c, const Seperator *sep) } } #if EQDEBUG >= 11 - LogFile->write(EQEMuLog::Debug,"#spawn Spawning:"); + LogFile->write(EQEmuLog::Debug,"#spawn Spawning:"); #endif NPC* npc = NPC::SpawnNPC(sep->argplus[1], c->GetPosition(), c); @@ -2610,117 +2610,92 @@ void command_peekinv(Client *c, const Seperator *sep) } Client* targetClient = c->GetTarget()->CastToClient(); - const ItemInst* instMain = nullptr; - const ItemInst* instSub = nullptr; - const Item_Struct* itemData = nullptr; - char* itemLinkCore = nullptr; - std::string itemLink; + const ItemInst* inst_main = nullptr; + const ItemInst* inst_sub = nullptr; + const Item_Struct* item_data = nullptr; + std::string item_link; + Client::TextLink linker; + linker.SetLinkType(linker.linkItemInst); c->Message(0, "Displaying inventory for %s...", targetClient->GetName()); // worn for (int16 indexMain = EmuConstants::EQUIPMENT_BEGIN; (scopeWhere & peekWorn) && (indexMain <= EmuConstants::EQUIPMENT_END); ++indexMain) { - instMain = targetClient->GetInv().GetItem(indexMain); - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = targetClient->GetInv().GetItem(indexMain); + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), "WornSlot: %i, Item: %i (%s), Charges: %i", - indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i", + indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); } if ((scopeWhere & peekWorn) && (targetClient->GetClientVersion() >= EQClientSoF)) { - instMain = targetClient->GetInv().GetItem(MainPowerSource); - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = targetClient->GetInv().GetItem(MainPowerSource); + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), "WornSlot: %i, Item: %i (%s), Charges: %i", - MainPowerSource, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i", + MainPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); } // inv for (int16 indexMain = EmuConstants::GENERAL_BEGIN; (scopeWhere & peekInv) && (indexMain <= EmuConstants::GENERAL_END); ++indexMain) { - instMain = targetClient->GetInv().GetItem(indexMain); - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = targetClient->GetInv().GetItem(indexMain); + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); + c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i", + indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); - c->Message((itemData == 0), "InvSlot: %i, Item: %i (%s), Charges: %i", - indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); + for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { + inst_sub = inst_main->GetItem(indexSub); + item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); + linker.SetItemInst(inst_sub); - safe_delete_array(itemLinkCore); + item_link = linker.GenerateLink(); - for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { - instSub = instMain->GetItem(indexSub); - itemData = (instSub ? instSub->GetItem() : nullptr); - itemLinkCore = nullptr; - - if (itemData) - c->MakeItemLink(itemLinkCore, instSub); - - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", + Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } // cursor if (scopeWhere & peekCursor) { if (targetClient->GetInv().CursorEmpty()) { + linker.SetItemInst(nullptr); + + item_link = linker.GenerateLink(); + c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i", - MainCursor, 0, "null", 0); + MainCursor, 0, item_link.c_str(), 0); } else { int cursorDepth = 0; for (iter_queue it = targetClient->GetInv().cursor_begin(); (it != targetClient->GetInv().cursor_end()); ++it, ++cursorDepth) { - instMain = *it; - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = *it; + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); + c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i", + MainCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); - c->Message((itemData == 0), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i", - MainCursor, cursorDepth, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); + for (uint8 indexSub = SUB_BEGIN; (cursorDepth == 0) && inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { + inst_sub = inst_main->GetItem(indexSub); + item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); + linker.SetItemInst(inst_sub); - safe_delete_array(itemLinkCore); + item_link = linker.GenerateLink(); - for (uint8 indexSub = SUB_BEGIN; (cursorDepth == 0) && instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { - instSub = instMain->GetItem(indexSub); - itemData = (instSub ? instSub->GetItem() : nullptr); - itemLinkCore = nullptr; - - if (itemData) - c->MakeItemLink(itemLinkCore, instSub); - - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", + Inventory::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } } @@ -2728,116 +2703,81 @@ void command_peekinv(Client *c, const Seperator *sep) // trib for (int16 indexMain = EmuConstants::TRIBUTE_BEGIN; (scopeWhere & peekTrib) && (indexMain <= EmuConstants::TRIBUTE_END); ++indexMain) { - instMain = targetClient->GetInv().GetItem(indexMain); - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = targetClient->GetInv().GetItem(indexMain); + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), "TributeSlot: %i, Item: %i (%s), Charges: %i", - indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), "TributeSlot: %i, Item: %i (%s), Charges: %i", + indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); } // bank for (int16 indexMain = EmuConstants::BANK_BEGIN; (scopeWhere & peekBank) && (indexMain <= EmuConstants::BANK_END); ++indexMain) { - instMain = targetClient->GetInv().GetItem(indexMain); - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = targetClient->GetInv().GetItem(indexMain); + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null" ); + c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i", + indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); - c->Message((itemData == 0), "BankSlot: %i, Item: %i (%s), Charges: %i", - indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); + for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { + inst_sub = inst_main->GetItem(indexSub); + item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); + linker.SetItemInst(inst_sub); - safe_delete_array(itemLinkCore); + item_link = linker.GenerateLink(); - for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { - instSub = instMain->GetItem(indexSub); - itemData = (instSub ? instSub->GetItem() : nullptr); - itemLinkCore = nullptr; - - if (itemData) - c->MakeItemLink(itemLinkCore, instSub); - - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", + Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } for (int16 indexMain = EmuConstants::SHARED_BANK_BEGIN; (scopeWhere & peekBank) && (indexMain <= EmuConstants::SHARED_BANK_END); ++indexMain) { - instMain = targetClient->GetInv().GetItem(indexMain); - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = targetClient->GetInv().GetItem(indexMain); + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); + + c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i", + indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); + for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { + inst_sub = inst_main->GetItem(indexSub); + item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); + linker.SetItemInst(inst_sub); - c->Message((itemData == 0), "SharedBankSlot: %i, Item: %i (%s), Charges: %i", - indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); + item_link = linker.GenerateLink(); - safe_delete_array(itemLinkCore); - - for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { - instSub = instMain->GetItem(indexSub); - itemData = (instSub ? instSub->GetItem() : nullptr); - itemLinkCore = nullptr; - - if (itemData) - c->MakeItemLink(itemLinkCore, instSub); - - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", + Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } // trade for (int16 indexMain = EmuConstants::TRADE_BEGIN; (scopeWhere & peekTrade) && (indexMain <= EmuConstants::TRADE_END); ++indexMain) { - instMain = targetClient->GetInv().GetItem(indexMain); - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = targetClient->GetInv().GetItem(indexMain); + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); + c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i", + indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); - c->Message((itemData == 0), "TradeSlot: %i, Item: %i (%s), Charges: %i", - indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); + for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { + inst_sub = inst_main->GetItem(indexSub); + item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); + linker.SetItemInst(inst_sub); - safe_delete_array(itemLinkCore); + item_link = linker.GenerateLink(); - for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { - instSub = instMain->GetItem(indexSub); - itemData = (instSub ? instSub->GetItem() : nullptr); - itemLinkCore = nullptr; - - if (itemData) - c->MakeItemLink(itemLinkCore, instSub); - - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", + Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } @@ -2852,34 +2792,24 @@ void command_peekinv(Client *c, const Seperator *sep) c->Message(0, "[WorldObject DBID: %i (entityid: %i)]", objectTradeskill->GetDBID(), objectTradeskill->GetID()); for (int16 indexMain = MAIN_BEGIN; indexMain < EmuConstants::MAP_WORLD_SIZE; ++indexMain) { - instMain = objectTradeskill->GetItem(indexMain); - itemData = (instMain ? instMain->GetItem() : nullptr); - itemLinkCore = nullptr; + inst_main = objectTradeskill->GetItem(indexMain); + item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); + linker.SetItemInst(inst_main); - if (itemData) - c->MakeItemLink(itemLinkCore, instMain); + item_link = linker.GenerateLink(); - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); + c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i", + (EmuConstants::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges())); - c->Message((itemData == 0), "WorldSlot: %i, Item: %i (%s), Charges: %i", - (EmuConstants::WORLD_BEGIN + indexMain), ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges())); + for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { + inst_sub = inst_main->GetItem(indexSub); + item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem(); + linker.SetItemInst(inst_sub); - safe_delete_array(itemLinkCore); + item_link = linker.GenerateLink(); - for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { - instSub = instMain->GetItem(indexSub); - itemData = (instSub ? instSub->GetItem() : nullptr); - itemLinkCore = nullptr; - - if (itemData) - c->MakeItemLink(itemLinkCore, instSub); - - itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null"); - - c->Message((itemData == 0), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - INVALID_INDEX, indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges())); - - safe_delete_array(itemLinkCore); + c->Message((item_data == nullptr), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", + INVALID_INDEX, indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } } @@ -3091,15 +3021,12 @@ void command_reloadqst(Client *c, const Seperator *sep) void command_reloadworld(Client *c, const Seperator *sep) { - if (sep->arg[1][0] == 0) - { - c->Message(0, "Reloading quest cache and repopping zones worldwide."); - ServerPacket* pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct)); - ReloadWorld_Struct* RW = (ReloadWorld_Struct*) pack->pBuffer; - RW->Option = 1; - worldserver.SendPacket(pack); - safe_delete(pack); - } + c->Message(0, "Reloading quest cache and repopping zones worldwide."); + ServerPacket* pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct)); + ReloadWorld_Struct* RW = (ReloadWorld_Struct*) pack->pBuffer; + RW->Option = ((atoi(sep->arg[1]) == 1) ? 1 : 0); + worldserver.SendPacket(pack); + safe_delete(pack); } void command_reloadlevelmods(Client *c, const Seperator *sep) @@ -3238,7 +3165,7 @@ void command_listpetition(Client *c, const Seperator *sep) if (!results.Success()) return; - LogFile->write(EQEMuLog::Normal,"Petition list requested by %s", c->GetName()); + LogFile->write(EQEmuLog::Normal,"Petition list requested by %s", c->GetName()); if (results.RowCount() == 0) return; @@ -3895,7 +3822,7 @@ void command_lastname(Client *c, const Seperator *sep) if(c->GetTarget() && c->GetTarget()->IsClient()) t=c->GetTarget()->CastToClient(); - LogFile->write(EQEMuLog::Normal,"#lastname request from %s for %s", c->GetName(), t->GetName()); + LogFile->write(EQEmuLog::Normal,"#lastname request from %s for %s", c->GetName(), t->GetName()); if(strlen(sep->arg[1]) <= 70) t->ChangeLastName(sep->arg[1]); @@ -4518,7 +4445,7 @@ void command_time(Client *c, const Seperator *sep) ); c->Message(13, "It is now %s.", timeMessage); #if EQDEBUG >= 11 - LogFile->write(EQEMuLog::Debug,"Recieved timeMessage:%s", timeMessage); + LogFile->write(EQEmuLog::Debug,"Recieved timeMessage:%s", timeMessage); #endif } } @@ -4993,7 +4920,7 @@ void command_manaburn(Client *c, const Seperator *sep) target->Damage(c, nukedmg, 2751, SkillAbjuration/*hackish*/); c->Message(4,"You unleash an enormous blast of magical energies."); } - LogFile->write(EQEMuLog::Normal,"Manaburn request from %s, damage: %d", c->GetName(), nukedmg); + LogFile->write(EQEmuLog::Normal,"Manaburn request from %s, damage: %d", c->GetName(), nukedmg); } } else @@ -5345,7 +5272,7 @@ void command_scribespells(Client *c, const Seperator *sep) t->Message(0, "Scribing spells to spellbook."); if(t != c) c->Message(0, "Scribing spells for %s.", t->GetName()); - LogFile->write(EQEMuLog::Normal, "Scribe spells request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level); + LogFile->write(EQEmuLog::Normal, "Scribe spells request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level); for(curspell = 0, book_slot = t->GetNextAvailableSpellBookSlot(), count = 0; curspell < SPDAT_RECORDS && book_slot < MAX_PP_SPELLBOOK; curspell++, book_slot = t->GetNextAvailableSpellBookSlot(book_slot)) { @@ -5402,7 +5329,7 @@ void command_scribespell(Client *c, const Seperator *sep) { if(t != c) c->Message(0, "Scribing spell: %s (%i) for %s.", spells[spell_id].name, spell_id, t->GetName()); - LogFile->write(EQEMuLog::Normal, "Scribe spell: %s (%i) request for %s from %s.", spells[spell_id].name, spell_id, t->GetName(), c->GetName()); + LogFile->write(EQEmuLog::Normal, "Scribe spell: %s (%i) request for %s from %s.", spells[spell_id].name, spell_id, t->GetName(), c->GetName()); if (spells[spell_id].classes[WARRIOR] != 0 && spells[spell_id].skill != 52 && spells[spell_id].classes[t->GetPP().class_ - 1] > 0 && !IsDiscipline(spell_id)) { book_slot = t->GetNextAvailableSpellBookSlot(); @@ -5449,7 +5376,7 @@ void command_unscribespell(Client *c, const Seperator *sep) { if(t != c) c->Message(0, "Unscribing spell: %s (%i) for %s.", spells[spell_id].name, spell_id, t->GetName()); - LogFile->write(EQEMuLog::Normal, "Unscribe spell: %s (%i) request for %s from %s.", spells[spell_id].name, spell_id, t->GetName(), c->GetName()); + LogFile->write(EQEmuLog::Normal, "Unscribe spell: %s (%i) request for %s from %s.", spells[spell_id].name, spell_id, t->GetName(), c->GetName()); } else { t->Message(13, "Unable to unscribe spell: %s (%i) from your spellbook. This spell is not scribed.", spells[spell_id].name, spell_id); @@ -5637,64 +5564,52 @@ void command_itemsearch(Client *c, const Seperator *sep) { const char *search_criteria=sep->argplus[1]; - const Item_Struct* item = 0; + const Item_Struct* item = nullptr; + std::string item_link; + Client::TextLink linker; + linker.SetLinkType(linker.linkItemData); + if (Seperator::IsNumber(search_criteria)) { item = database.GetItem(atoi(search_criteria)); - if (item) - if (c->GetClientVersion() >= EQClientRoF2) - { - c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000000000%s%c", (int)item->ID, 0x12, item->ID, item->Name, 0x12); - } - else if (c->GetClientVersion() >= EQClientRoF) - { - c->Message(0, " %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12); - } - else if (c->GetClientVersion() >= EQClientSoF) - { - c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12); - } - else - { - c->Message(0, " %i: %c%06X000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12); - } - else + if (item) { + linker.SetItemData(item); + + item_link = linker.GenerateLink(); + + c->Message(0, "%u: %s", item->ID, item_link.c_str()); + } + else { c->Message(0, "Item #%s not found", search_criteria); + } + return; } - int count = 0; + int count = NOT_USED; char sName[64]; char sCriteria[255]; strn0cpy(sCriteria, search_criteria, sizeof(sCriteria)); strupr(sCriteria); char* pdest; - uint32 it = 0; + uint32 it = NOT_USED; while ((item = database.IterateItems(&it))) { strn0cpy(sName, item->Name, sizeof(sName)); strupr(sName); pdest = strstr(sName, sCriteria); if (pdest != nullptr) { - if (c->GetClientVersion() >= EQClientRoF2) - { - c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000000000%s%c", (int)item->ID, 0x12, item->ID, item->Name, 0x12); - } - else if (c->GetClientVersion() >= EQClientRoF) - { - c->Message(0, " %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12); - } - else if (c->GetClientVersion() >= EQClientSoF) - { - c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12); - } - else - { - c->Message(0, " %i: %c%06X000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12); - } - count++; + linker.SetItemData(item); + + item_link = linker.GenerateLink(); + + c->Message(0, "%u: %s", item->ID, item_link.c_str()); + + ++count; } + if (count == 50) break; } + if (count == 50) c->Message(0, "50 items shown...too many results."); else @@ -6089,7 +6004,7 @@ void command_npcedit(Client *c, const Seperator *sep) return; } - if ( strcasecmp( sep->arg[1], "help" ) == 0 ) { + if (strcasecmp(sep->arg[1], "help") == 0) { c->Message(0, "Help File for #npcedit. Syntax for commands are:"); c->Message(0, "#npcedit Name - Sets an NPC's name"); @@ -6102,7 +6017,13 @@ void command_npcedit(Client *c, const Seperator *sep) c->Message(0, "#npcedit HP - Sets an NPC's hitpoints"); c->Message(0, "#npcedit Gender - Sets an NPC's gender"); c->Message(0, "#npcedit Texture - Sets an NPC's texture"); - c->Message(0, "#npcedit Helmtexture - Sets an NPC's helmtexture"); + c->Message(0, "#npcedit Helmtexture - Sets an NPC's helmet texture"); + c->Message(0, "#npcedit Armtexture - Sets an NPC's arm texture"); + c->Message(0, "#npcedit Bracertexture - Sets an NPC's bracer texture"); + c->Message(0, "#npcedit Handtexture - Sets an NPC's hand texture"); + c->Message(0, "#npcedit Legtexture - Sets an NPC's leg texture"); + c->Message(0, "#npcedit Feettexture - Sets an NPC's feettexture"); + c->Message(0, "#npcedit Herosforgemodel - Sets an NPC's Hero's Forge Model"); c->Message(0, "#npcedit Size - Sets an NPC's size"); c->Message(0, "#npcedit Hpregen - Sets an NPC's hitpoint regen rate per tick"); c->Message(0, "#npcedit Manaregen - Sets an NPC's mana regen rate per tick"); @@ -6115,12 +6036,15 @@ void command_npcedit(Client *c, const Seperator *sep) c->Message(0, "#npcedit special_abilities - Sets the NPC's Special Abilities"); c->Message(0, "#npcedit Spell - Sets the npc spells list ID for an NPC"); c->Message(0, "#npcedit Faction - Sets the NPC's faction id"); - c->Message(0, "#npcedit Mindmg - Sets an NPC's minimum damage"); - c->Message(0, "#npcedit Maxdmg - Sets an NPC's maximum damage"); + c->Message(0, "#npcedit Damage - Sets an NPC's damage"); + c->Message(0, "#npcedit Meleetype - Sets an NPC's melee types"); + c->Message(0, "#npcedit Rangedtype - Sets an NPC's ranged type"); + c->Message(0, "#npcedit Ammoidfile - Sets an NPC's ammo id file"); c->Message(0, "#npcedit Aggroradius - Sets an NPC's aggro radius"); c->Message(0, "#npcedit Assistradius - Sets an NPC's assist radius"); c->Message(0, "#npcedit Social - Set to 1 if an NPC should assist others on its faction"); c->Message(0, "#npcedit Runspeed - Sets an NPC's run speed"); + c->Message(0, "#npcedit Walkspeed - Sets an NPC's walk speed"); c->Message(0, "#npcedit AGI - Sets an NPC's Agility"); c->Message(0, "#npcedit CHA - Sets an NPC's Charisma"); c->Message(0, "#npcedit DEX - Sets an NPC's Dexterity"); @@ -6132,7 +6056,7 @@ void command_npcedit(Client *c, const Seperator *sep) c->Message(0, "#npcedit PR - Sets an NPC's Poison Resistance"); c->Message(0, "#npcedit DR - Sets an NPC's Disease Resistance"); c->Message(0, "#npcedit FR - Sets an NPC's Fire Resistance"); - c->Message(0, "#npcedit CR - Sets an NPC's cold resistance"); + c->Message(0, "#npcedit CR - Sets an NPC's Cold Resistance"); c->Message(0, "#npcedit Corrup - Sets an NPC's Corruption Resistance"); c->Message(0, "#npcedit PhR - Sets and NPC's Physical Resistance"); c->Message(0, "#npcedit Seeinvis - Sets an NPC's ability to see invis"); @@ -6142,14 +6066,16 @@ void command_npcedit(Client *c, const Seperator *sep) c->Message(0, "#npcedit AC - Sets an NPC's Armor Class"); c->Message(0, "#npcedit ATK - Sets an NPC's Attack"); c->Message(0, "#npcedit Accuracy - Sets an NPC's Accuracy"); + c->Message(0, "#npcedit Avoidance - Sets an NPC's Avoidance"); c->Message(0, "#npcedit npcaggro - Sets an NPC's npc_aggro flag"); c->Message(0, "#npcedit qglobal - Sets an NPC's quest global flag"); - c->Message(0, "#npcedit limit - Sets an NPC's spawn limit counter"); + c->Message(0, "#npcedit spawn_limit - Sets an NPC's spawn limit counter"); c->Message(0, "#npcedit Attackspeed - Sets an NPC's attack speed modifier"); c->Message(0, "#npcedit Attackdelay - Sets an NPC's attack delay"); + c->Message(0, "#npcedit Attackcount - Sets an NPC's attack count"); c->Message(0, "#npcedit findable - Sets an NPC's findable flag"); - c->Message(0, "#npcedit wep1 - Sets an NPC's primary weapon model"); - c->Message(0, "#npcedit wep2 - Sets an NPC's secondary weapon model"); + c->Message(0, "#npcedit trackable - Sets an NPC's trackable flag"); + c->Message(0, "#npcedit weapon - Sets an NPC's primary and secondary weapon model"); c->Message(0, "#npcedit featuresave - Saves all current facial features to the database"); c->Message(0, "#npcedit color - Sets an NPC's red, green, and blue armor tint"); c->Message(0, "#npcedit armortint_id - Set an NPC's Armor tint ID"); @@ -6159,602 +6085,566 @@ void command_npcedit(Client *c, const Seperator *sep) c->Message(0, "#npcedit spellscale - Set an NPC's spell scaling rate"); c->Message(0, "#npcedit no_target - Set an NPC's ability to be targeted with the target hotkey"); c->Message(0, "#npcedit version - Set an NPC's version"); + c->Message(0, "#npcedit slow_mitigation - Set an NPC's slow mitigation"); } uint32 npcTypeID = c->GetTarget()->CastToNPC()->GetNPCTypeID(); - - if ( strcasecmp( sep->arg[1], "name" ) == 0 ) { + if (strcasecmp(sep->arg[1], "name") == 0) { c->Message(15,"NPCID %u now has the name %s.",npcTypeID, sep->argplus[2]); - - std::string query = StringFormat("UPDATE npc_types SET name = '%s' WHERE id = %i", - sep->argplus[2],npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET name = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "lastname" ) == 0 ) { + if (strcasecmp(sep->arg[1], "lastname") == 0) { c->Message(15,"NPCID %u now has the lastname %s.",npcTypeID, sep->argplus[2]); - - std::string query = StringFormat("UPDATE npc_types SET lastname = '%s' WHERE id = %i", - sep->argplus[2],npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET lastname = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "race" ) == 0 ) { + if (strcasecmp(sep->arg[1], "race") == 0) { c->Message(15,"NPCID %u now has the race %i.",npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET race = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET race = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "class" ) == 0 ) { + if (strcasecmp(sep->arg[1], "class") == 0) { c->Message(15,"NPCID %u is now class %i.",npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET class = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET class = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "bodytype" ) == 0 ) { + if (strcasecmp(sep->arg[1], "bodytype") == 0) { c->Message(15,"NPCID %u now has type %i bodytype.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET bodytype = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET bodytype = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "hp" ) == 0 ) { + if (strcasecmp(sep->arg[1], "hp") == 0) { c->Message(15,"NPCID %u now has %i Hitpoints.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET hp = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET hp = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "gender" ) == 0 ) { + if (strcasecmp(sep->arg[1], "gender") == 0) { c->Message(15,"NPCID %u is now gender %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET gender = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET gender = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "texture" ) == 0 ) { + if (strcasecmp(sep->arg[1], "texture") == 0) { c->Message(15,"NPCID %u now uses texture %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET texture = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET texture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "helmtexture" ) == 0 ) { + if (strcasecmp(sep->arg[1], "helmtexture") == 0) { c->Message(15,"NPCID %u now uses helmtexture %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET helmtexture = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET helmtexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "size" ) == 0 ) { + if (strcasecmp(sep->arg[1], "armtexture") == 0) { + c->Message(15,"NPCID %u now uses armtexture %i.", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET armtexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "bracertexture") == 0) { + c->Message(15,"NPCID %u now uses bracertexture %i.", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET bracertexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "handtexture") == 0) { + c->Message(15,"NPCID %u now uses handtexture %i.", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET handtexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "legtexture") == 0) { + c->Message(15,"NPCID %u now uses legtexture %i.", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET legtexture = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "feettexture") == 0) { + c->Message(15,"NPCID %u now uses feettexture %i.", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET feettexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "herosforgemodel") == 0) { + c->Message(15,"NPCID %u now uses herosforgemodel %i.", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET herosforgemodel = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "size") == 0) { c->Message(15,"NPCID %u is now size %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET size = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET size = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "hpregen" ) == 0 ) { + if (strcasecmp(sep->arg[1], "hpregen") == 0) { c->Message(15,"NPCID %u now regens %i hitpoints per tick.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET hp_regen_rate = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET hp_regen_rate = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "manaregen" ) == 0 ) { + if (strcasecmp(sep->arg[1], "manaregen") == 0) { c->Message(15,"NPCID %u now regens %i mana per tick.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET mana_regen_rate = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET mana_regen_rate = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "loottable" ) == 0 ) { + if (strcasecmp(sep->arg[1], "loottable") == 0) { c->Message(15,"NPCID %u is now on loottable_id %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET loottable_id = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET loottable_id = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "merchantid" ) == 0 ) { + if (strcasecmp(sep->arg[1], "merchantid") == 0) { c->Message(15,"NPCID %u is now merchant_id %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET merchant_id = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET merchant_id = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "alt_currency_id" ) == 0 ) { + if (strcasecmp(sep->arg[1], "alt_currency_id") == 0) { c->Message(15,"NPCID %u now has field 'alt_currency_id' set to %s.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET alt_currency_id = '%s' WHERE id = %i", - sep->argplus[2],npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET alt_currency_id = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "npc_spells_effects_id" ) == 0 ) { + if (strcasecmp(sep->arg[1], "npc_spells_effects_id") == 0) { c->Message(15,"NPCID %u now has field 'npc_spells_effects_id' set to %s.", npcTypeID, sep->argplus[2]); - - std::string query = StringFormat("UPDATE npc_types SET npc_spells_effects_id = '%s' WHERE id = %i", - sep->argplus[2],npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET npc_spells_effects_id = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "adventure_template_id" ) == 0 ) { + if (strcasecmp(sep->arg[1], "adventure_template_id") == 0) { c->Message(15,"NPCID %u now has field 'adventure_template_id' set to %s.", npcTypeID, sep->argplus[2]); - - std::string query = StringFormat("UPDATE npc_types SET adventure_template_id = '%s' WHERE id = %i", - sep->argplus[2],npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET adventure_template_id = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "trap_template" ) == 0 ) { + if (strcasecmp(sep->arg[1], "trap_template") == 0) { c->Message(15,"NPCID %u now has field 'trap_template' set to %s.", npcTypeID, sep->argplus[2]); - - std::string query = StringFormat("UPDATE npc_types SET trap_template = '%s' WHERE id = %i", - sep->argplus[2],npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET trap_template = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "special_abilities" ) == 0 ) { + if (strcasecmp(sep->arg[1], "special_abilities") == 0) { c->Message(15,"NPCID %u now has field 'special_abilities' set to %s.", npcTypeID, sep->argplus[2]); - - std::string query = StringFormat("UPDATE npc_types SET special_abilities = '%s' WHERE id = %i", - sep->argplus[2],npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET special_abilities = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "spell" ) == 0 ) { + if (strcasecmp(sep->arg[1], "spell") == 0) { c->Message(15,"NPCID %u now uses spell list %i", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET npc_spells_id = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET npc_spells_id = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "faction" ) == 0 ) { + if (strcasecmp(sep->arg[1], "faction") == 0) { c->Message(15,"NPCID %u is now faction %i", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET npc_faction_id = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET npc_faction_id = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "mindmg" ) == 0 ) { - c->Message(15,"NPCID %u now hits for a min of %i", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET mindmg = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); + if (strcasecmp(sep->arg[1], "damage") == 0) { + c->Message(15,"NPCID %u now hits from %i to %i", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); + std::string query = StringFormat("UPDATE npc_types SET mindmg = %i, maxdmg = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "meleetype") == 0) { + c->Message(15,"NPCID %u now has a primary melee type of %i and a secondary melee type of %i.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); + std::string query = StringFormat("UPDATE npc_types SET prim_melee_type = %i, sec_melee_type = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "rangedtype") == 0) { + c->Message(15,"NPCID %u now has a ranged type of %i.", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET rangedtype = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "ammoidfile") == 0) { + c->Message(15,"NPCID %u's ammo id file is now %i", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET ammoidfile = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "maxdmg" ) == 0 ) { - c->Message(15,"NPCID %u now hits for a max of %i", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET maxdmg = %i WHERE id = %i", - atoi(sep->argplus[2]),npcTypeID); - database.QueryDatabase(query); - c->LogSQL(query.c_str()); - return; - } - - if ( strcasecmp( sep->arg[1], "aggroradius" ) == 0 ) { + if (strcasecmp(sep->arg[1], "aggroradius") == 0) { c->Message(15,"NPCID %u now has an aggro radius of %i", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET aggroradius = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET aggroradius = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "assistradius" ) == 0 ) { + if (strcasecmp(sep->arg[1], "assistradius") == 0) { c->Message(15,"NPCID %u now has an assist radius of %i", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET assistradius = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET assistradius = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "social" ) == 0 ) { + if (strcasecmp(sep->arg[1], "social") == 0) { c->Message(15,"NPCID %u social status is now %i", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET social = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET social = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "runspeed" ) == 0 ) { + if (strcasecmp(sep->arg[1], "runspeed") == 0) { c->Message(15,"NPCID %u now runs at %f", npcTypeID, atof(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET runspeed = %f WHERE id = %i", - atof(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET runspeed = %f WHERE id = %i", atof(sep->argplus[2]), npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "walkspeed") == 0) { + c->Message(15,"NPCID %u now walks at %f", npcTypeID, atof(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET walkspeed = %f WHERE id = %i", atof(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "AGI" ) == 0 ) { + if (strcasecmp(sep->arg[1], "AGI") == 0) { c->Message(15,"NPCID %u now has %i Agility.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET AGI = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET AGI = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "CHA" ) == 0 ) { + if (strcasecmp(sep->arg[1], "CHA") == 0) { c->Message(15,"NPCID %u now has %i Charisma.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET CHA = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET CHA = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "DEX" ) == 0 ) { + if (strcasecmp(sep->arg[1], "DEX") == 0) { c->Message(15,"NPCID %u now has %i Dexterity.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET DEX = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET DEX = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "INT" ) == 0 ) { + if (strcasecmp(sep->arg[1], "INT") == 0) { c->Message(15,"NPCID %u now has %i Intelligence.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET _INT = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET _INT = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "STA" ) == 0 ) { + if (strcasecmp(sep->arg[1], "STA") == 0) { c->Message(15,"NPCID %u now has %i Stamina.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET STA = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET STA = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "STR" ) == 0 ) { + if (strcasecmp(sep->arg[1], "STR") == 0) { c->Message(15,"NPCID %u now has %i Strength.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET STR = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET STR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "WIS" ) == 0 ) { + if (strcasecmp(sep->arg[1], "WIS") == 0) { c->Message(15,"NPCID %u now has a Magic Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET WIS = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET WIS = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "MR" ) == 0 ) { + if (strcasecmp(sep->arg[1], "MR") == 0) { c->Message(15,"NPCID %u now has a Magic Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET MR = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET MR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "DR" ) == 0 ) { + if (strcasecmp(sep->arg[1], "DR") == 0) { c->Message(15,"NPCID %u now has a Disease Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET DR = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET DR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "CR" ) == 0 ) { + if (strcasecmp(sep->arg[1], "CR") == 0) { c->Message(15,"NPCID %u now has a Cold Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET CR = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET CR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "FR" ) == 0 ) { + if (strcasecmp(sep->arg[1], "FR") == 0) { c->Message(15,"NPCID %u now has a Fire Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET FR = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET FR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "PR" ) == 0 ) { + if (strcasecmp(sep->arg[1], "PR") == 0) { c->Message(15,"NPCID %u now has a Poison Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET PR = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET PR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "Corrup" ) == 0 ) { + if (strcasecmp(sep->arg[1], "Corrup") == 0) { c->Message(15,"NPCID %u now has a Corruption Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET corrup = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET corrup = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "PhR" ) == 0 ) { + if (strcasecmp(sep->arg[1], "PhR") == 0) { c->Message(15,"NPCID %u now has a Physical Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET PhR = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET PhR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "seeinvis" ) == 0 ) { + if (strcasecmp(sep->arg[1], "seeinvis") == 0) { c->Message(15,"NPCID %u now has seeinvis set to %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET see_invis = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET see_invis = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "seeinvisundead" ) == 0 ) { + if (strcasecmp(sep->arg[1], "seeinvisundead") == 0) { c->Message(15,"NPCID %u now has seeinvisundead set to %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET see_invis_undead = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET see_invis_undead = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "seehide" ) == 0 ) { + if (strcasecmp(sep->arg[1], "seehide") == 0) { c->Message(15,"NPCID %u now has seehide set to %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET see_hide = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET see_hide = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "seeimprovedhide" ) == 0 ) { + if (strcasecmp(sep->arg[1], "seeimprovedhide") == 0) { c->Message(15,"NPCID %u now has seeimprovedhide set to %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET see_improved_hide = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET see_improved_hide = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "AC" ) == 0 ) { + if (strcasecmp(sep->arg[1], "AC") == 0) { c->Message(15,"NPCID %u now has %i Armor Class.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET ac = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET ac = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "ATK" ) == 0 ) { + if (strcasecmp(sep->arg[1], "ATK") == 0) { c->Message(15,"NPCID %u now has %i Attack.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET atk = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET atk = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "Accuracy" ) == 0 ) { + if (strcasecmp(sep->arg[1], "Accuracy") == 0) { c->Message(15,"NPCID %u now has %i Accuracy.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET accuracy = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET accuracy = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "Avoidance") == 0) { + c->Message(15,"NPCID %u now has %i Avoidance.", npcTypeID, atoi(sep->argplus[2])); + std::string query = StringFormat("UPDATE npc_types SET avoidance = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "level" ) == 0 ) { + if (strcasecmp(sep->arg[1], "level") == 0) { c->Message(15,"NPCID %u is now level %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET level = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET level = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "maxlevel" ) == 0 ) { + if (strcasecmp(sep->arg[1], "maxlevel") == 0) { c->Message(15,"NPCID %u now has a maximum level of %i.", npcTypeID, atoi(sep->argplus[2])); - - std::string query = StringFormat("UPDATE npc_types SET maxlevel = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET maxlevel = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "qglobal" ) == 0 ) { - c->Message(15,"Quest globals have been %s for NPCID %u", - atoi(sep->arg[2]) == 0 ? "disabled" : "enabled", npcTypeID); - - std::string query = StringFormat("UPDATE npc_types SET qglobal = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "qglobal") == 0) { + c->Message(15,"Quest globals have been %s for NPCID %u", atoi(sep->arg[2]) == 0 ? "disabled" : "enabled", npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET qglobal = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "npcaggro" ) == 0 ) { - c->Message(15,"NPCID %u will now %s other NPCs with negative faction npc_value", - npcTypeID, atoi(sep->arg[2]) == 0? "not aggro": "aggro"); - - std::string query = StringFormat("UPDATE npc_types SET npc_aggro = %i WHERE id = %i", - atoi(sep->argplus[2]) == 0? 0: 1, npcTypeID); + if (strcasecmp(sep->arg[1], "npcaggro") == 0) { + c->Message(15,"NPCID %u will now %s other NPCs with negative faction npc_value", npcTypeID, atoi(sep->arg[2]) == 0? "not aggro": "aggro"); + std::string query = StringFormat("UPDATE npc_types SET npc_aggro = %i WHERE id = %i", atoi(sep->argplus[2]) == 0? 0: 1, npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "limit" ) == 0 ) { - c->Message(15,"NPCID %u now has a spawn limit of %i", - npcTypeID, atoi(sep->arg[2])); - - std::string query = StringFormat("UPDATE npc_types SET limit = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "spawn_limit") == 0) { + c->Message(15,"NPCID %u now has a spawn limit of %i", npcTypeID, atoi(sep->arg[2])); + std::string query = StringFormat("UPDATE npc_types SET spawn_limit = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "Attackspeed" ) == 0 ) { - c->Message(15,"NPCID %u now has attack_speed set to %f", - npcTypeID, atof(sep->arg[2])); - - std::string query = StringFormat("UPDATE npc_types SET attack_speed = %f WHERE id = %i", - atof(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "Attackspeed") == 0) { + c->Message(15,"NPCID %u now has attack_speed set to %f", npcTypeID, atof(sep->arg[2])); + std::string query = StringFormat("UPDATE npc_types SET attack_speed = %f WHERE id = %i", atof(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "Attackdelay" ) == 0 ) { + if (strcasecmp(sep->arg[1], "Attackdelay") == 0) { c->Message(15,"NPCID %u now has attack_delay set to %i",npcTypeID,atoi(sep->arg[2])); - std::string query = StringFormat("UPDATE npc_types SET attack_delay = %i WHERE id = %i",atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } + + if (strcasecmp(sep->arg[1], "Attackcount") == 0) { + c->Message(15,"NPCID %u now has attack_count set to %i",npcTypeID,atoi(sep->arg[2])); + std::string query = StringFormat("UPDATE npc_types SET attack_count = %i WHERE id = %i",atoi(sep->argplus[2]),npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } - if ( strcasecmp( sep->arg[1], "findable" ) == 0 ) { + if (strcasecmp(sep->arg[1], "findable") == 0) { c->Message(15,"NPCID %u is now %s", npcTypeID, atoi(sep->arg[2]) == 0? "not findable": "findable"); - - std::string query = StringFormat("UPDATE npc_types SET findable = %i WHERE id = %i", - atoi(sep->argplus[2]) == 0? 0: 1, npcTypeID); + std::string query = StringFormat("UPDATE npc_types SET findable = %i WHERE id = %i", atoi(sep->argplus[2]) == 0? 0: 1, npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "wep1" ) == 0 ) { - c->Message(15,"NPCID %u will have item graphic %i set to his primary on repop.", - npcTypeID, atoi(sep->arg[2])); - - std::string query = StringFormat("UPDATE npc_types SET d_meele_texture1 = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "trackable") == 0) { + c->Message(15,"NPCID %u is now %s", npcTypeID, atoi(sep->arg[2]) == 0? "not trackable": "trackable"); + std::string query = StringFormat("UPDATE npc_types SET trackable = %i WHERE id = %i", atoi(sep->argplus[2]) == 0? 0: 1, npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "wep2" ) == 0 ) { - c->Message(15,"NPCID %u will have item graphic %i set to his secondary on repop.", - npcTypeID, atoi(sep->arg[2])); - - std::string query = StringFormat("UPDATE npc_types SET d_meele_texture2 = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "weapon") == 0) { + c->Message(15,"NPCID %u will have item graphic %i set to his primary and item graphic %i set to his secondary on repop.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); + std::string query = StringFormat("UPDATE npc_types SET d_melee_texture1 = %i, d_melee_texture2 = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "featuresave" ) == 0 ) { - c->Message(15,"NPCID %u saved with all current facial feature settings", - npcTypeID); - + if (strcasecmp(sep->arg[1], "featuresave") == 0) { + c->Message(15,"NPCID %u saved with all current facial feature settings", npcTypeID); Mob* target = c->GetTarget(); - std::string query = StringFormat("UPDATE npc_types " "SET luclin_haircolor = %i, luclin_beardcolor = %i, " "luclin_hairstyle = %i, luclin_beard = %i, " @@ -6771,45 +6661,36 @@ void command_npcedit(Client *c, const Seperator *sep) return; } - if ( strcasecmp( sep->arg[1], "color" ) == 0 ) { - c->Message(15,"NPCID %u now has %i red, %i green, and %i blue tinting on their armor.", - npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); - - std::string query = StringFormat("UPDATE npc_types " - "SET armortint_red = %i, armortint_green = %i, armortint_blue = %i " - "WHERE id = %i", - atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), npcTypeID); + if (strcasecmp(sep->arg[1], "color") == 0) { + c->Message(15,"NPCID %u now has %i red, %i green, and %i blue tinting on their armor.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); + std::string query = StringFormat("UPDATE npc_types SET armortint_red = %i, armortint_green = %i, armortint_blue = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "armortint_id" ) == 0 ) { - c->Message(15,"NPCID %u now has field 'armortint_id' set to %s", - npcTypeID, sep->arg[2]); - - std::string query = StringFormat("UPDATE npc_types SET armortint_id = '%s' WHERE id = %i", - sep->argplus[2], npcTypeID); + if (strcasecmp(sep->arg[1], "armortint_id") == 0) { + c->Message(15,"NPCID %u now has field 'armortint_id' set to %s", npcTypeID, sep->arg[2]); + std::string query = StringFormat("UPDATE npc_types SET armortint_id = '%s' WHERE id = %i", sep->argplus[2], npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "setanimation" ) == 0 ) { + if (strcasecmp(sep->arg[1], "setanimation") == 0) { int animation = 0; if(sep->arg[2] && atoi(sep->arg[2]) <= 4) { - if((strcasecmp( sep->arg[2], "stand" ) == 0) || atoi(sep->arg[2]) == 0) + if((strcasecmp(sep->arg[2], "stand" ) == 0) || atoi(sep->arg[2]) == 0) animation = 0; //Stand - if((strcasecmp( sep->arg[2], "sit" ) == 0) || atoi(sep->arg[2]) == 1) + if((strcasecmp(sep->arg[2], "sit" ) == 0) || atoi(sep->arg[2]) == 1) animation = 1; //Sit - if((strcasecmp( sep->arg[2], "crouch" ) == 0) || atoi(sep->arg[2]) == 2) + if((strcasecmp(sep->arg[2], "crouch" ) == 0) || atoi(sep->arg[2]) == 2) animation = 2; //Crouch - if((strcasecmp( sep->arg[2], "dead" ) == 0) || atoi(sep->arg[2]) == 3) + if((strcasecmp(sep->arg[2], "dead" ) == 0) || atoi(sep->arg[2]) == 3) animation = 3; //Dead - if((strcasecmp( sep->arg[2], "loot" ) == 0) || atoi(sep->arg[2]) == 4) + if((strcasecmp(sep->arg[2], "loot" ) == 0) || atoi(sep->arg[2]) == 4) animation = 4; //Looting Animation - } - else { + } else { c->Message(0, "You must specifiy an animation stand, sit, crouch, dead, loot (0-4)"); c->Message(0, "Example: #npcedit setanimation sit"); c->Message(0, "Example: #npcedit setanimation 0"); @@ -6817,10 +6698,7 @@ void command_npcedit(Client *c, const Seperator *sep) } c->Message(15,"NPCID %u now has the animation set to %i on spawn with spawngroup %i", npcTypeID, animation, c->GetTarget()->CastToNPC()->GetSp2() ); - - std::string query = StringFormat("UPDATE spawn2 SET animation = %i " - "WHERE spawngroupID = %i", - animation, c->GetTarget()->CastToNPC()->GetSp2()); + std::string query = StringFormat("UPDATE spawn2 SET animation = %i " "WHERE spawngroupID = %i", animation, c->GetTarget()->CastToNPC()->GetSp2()); database.QueryDatabase(query); c->LogSQL(query.c_str()); @@ -6828,56 +6706,49 @@ void command_npcedit(Client *c, const Seperator *sep) return; } - if ( strcasecmp( sep->arg[1], "scalerate" ) == 0 ) { - c->Message(15,"NPCID %u now has a scaling rate of %i.", - npcTypeID, atoi(sep->arg[2])); - - std::string query = StringFormat("UPDATE npc_types SET scalerate = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "scalerate") == 0) { + c->Message(15,"NPCID %u now has a scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); + std::string query = StringFormat("UPDATE npc_types SET scalerate = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "healscale" ) == 0 ) { - c->Message(15, "NPCID %u now has a heal scaling rate of %i.", - npcTypeID, atoi(sep->arg[2])); - - std::string query = StringFormat("UPDATE npc_types SET healscale = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "healscale") == 0) { + c->Message(15, "NPCID %u now has a heal scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); + std::string query = StringFormat("UPDATE npc_types SET healscale = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "spellscale" ) == 0 ) { - c->Message(15, "NPCID %u now has a spell scaling rate of %i.", - npcTypeID, atoi(sep->arg[2])); - - std::string query = StringFormat("UPDATE npc_types SET spellscale = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "spellscale") == 0) { + c->Message(15, "NPCID %u now has a spell scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); + std::string query = StringFormat("UPDATE npc_types SET spellscale = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "no_target" ) == 0 ) { - c->Message(15, "NPCID %u is now %s.", - npcTypeID, atoi(sep->arg[2]) == 0? "targetable": "untargetable"); - - std::string query = StringFormat("UPDATE npc_types SET no_target_hotkey = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "no_target") == 0) { + c->Message(15, "NPCID %u is now %s.", npcTypeID, atoi(sep->arg[2]) == 0? "targetable": "untargetable"); + std::string query = StringFormat("UPDATE npc_types SET no_target_hotkey = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; } - if ( strcasecmp( sep->arg[1], "version" ) == 0 ) { - c->Message(15, "NPCID %u is now version %i.", - npcTypeID, atoi(sep->arg[2])); - - std::string query = StringFormat("UPDATE npc_types SET version = %i WHERE id = %i", - atoi(sep->argplus[2]), npcTypeID); + if (strcasecmp(sep->arg[1], "version") == 0) { + c->Message(15, "NPCID %u is now version %i.", npcTypeID, atoi(sep->arg[2])); + std::string query = StringFormat("UPDATE npc_types SET version = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); + database.QueryDatabase(query); + c->LogSQL(query.c_str()); + return; + } + + if (strcasecmp(sep->arg[1], "slow_mitigation") == 0) { + c->Message(15, "NPCID %u's slow mitigation limit is now %i.", npcTypeID, atoi(sep->arg[2])); + std::string query = StringFormat("UPDATE npc_types SET slow_mitigation = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); c->LogSQL(query.c_str()); return; @@ -6909,14 +6780,14 @@ void command_profilereset(Client *c, const Seperator *sep) { #endif void command_opcode(Client *c, const Seperator *sep) { - if(!strcasecmp( sep->arg[1], "reload" )) { + if(!strcasecmp(sep->arg[1], "reload" )) { ReloadAllPatches(); c->Message(0, "Opcodes for all patches have been reloaded"); } } void command_logsql(Client *c, const Seperator *sep) { - if(!strcasecmp( sep->arg[1], "off" )) { + if(!strcasecmp(sep->arg[1], "off" )) { c->ChangeSQLLog(nullptr); } else if(sep->arg[1][0] != '\0') { c->ChangeSQLLog(sep->argplus[1]); @@ -6933,17 +6804,17 @@ void command_logs(Client *c, const Seperator *sep) t = c->GetTarget()->CastToClient(); } - if(!strcasecmp( sep->arg[1], "status" ) ) - client_logs.subscribe(EQEMuLog::Status, t); - else if(!strcasecmp( sep->arg[1], "normal" ) ) - client_logs.subscribe(EQEMuLog::Normal, t); - else if(!strcasecmp( sep->arg[1], "error" ) ) - client_logs.subscribe(EQEMuLog::Error, t); - else if(!strcasecmp( sep->arg[1], "debug" ) ) - client_logs.subscribe(EQEMuLog::Debug, t); - else if(!strcasecmp( sep->arg[1], "quest" ) ) - client_logs.subscribe(EQEMuLog::Quest, t); - else if(!strcasecmp( sep->arg[1], "all" ) ) + if(!strcasecmp(sep->arg[1], "status" ) ) + client_logs.subscribe(EQEmuLog::Status, t); + else if(!strcasecmp(sep->arg[1], "normal" ) ) + client_logs.subscribe(EQEmuLog::Normal, t); + else if(!strcasecmp(sep->arg[1], "error" ) ) + client_logs.subscribe(EQEmuLog::Error, t); + else if(!strcasecmp(sep->arg[1], "debug" ) ) + client_logs.subscribe(EQEmuLog::Debug, t); + else if(!strcasecmp(sep->arg[1], "quest" ) ) + client_logs.subscribe(EQEmuLog::Quest, t); + else if(!strcasecmp(sep->arg[1], "all" ) ) client_logs.subscribeAll(t); else { c->Message(0, "Usage: #logs [status|normal|error|debug|quest|all]"); @@ -6965,17 +6836,17 @@ void command_nologs(Client *c, const Seperator *sep) t = c; } - if(!strcasecmp( sep->arg[1], "status" ) ) - client_logs.unsubscribe(EQEMuLog::Status, t); - else if(!strcasecmp( sep->arg[1], "normal" ) ) - client_logs.unsubscribe(EQEMuLog::Normal, t); - else if(!strcasecmp( sep->arg[1], "error" ) ) - client_logs.unsubscribe(EQEMuLog::Error, t); - else if(!strcasecmp( sep->arg[1], "debug" ) ) - client_logs.unsubscribe(EQEMuLog::Debug, t); - else if(!strcasecmp( sep->arg[1], "quest" ) ) - client_logs.unsubscribe(EQEMuLog::Quest, t); - else if(!strcasecmp( sep->arg[1], "all" ) ) + if(!strcasecmp(sep->arg[1], "status" ) ) + client_logs.unsubscribe(EQEmuLog::Status, t); + else if(!strcasecmp(sep->arg[1], "normal" ) ) + client_logs.unsubscribe(EQEmuLog::Normal, t); + else if(!strcasecmp(sep->arg[1], "error" ) ) + client_logs.unsubscribe(EQEmuLog::Error, t); + else if(!strcasecmp(sep->arg[1], "debug" ) ) + client_logs.unsubscribe(EQEmuLog::Debug, t); + else if(!strcasecmp(sep->arg[1], "quest" ) ) + client_logs.unsubscribe(EQEmuLog::Quest, t); + else if(!strcasecmp(sep->arg[1], "all" ) ) client_logs.unsubscribeAll(t); else { c->Message(0, "Usage: #logs [status|normal|error|debug|quest|all]"); @@ -8267,7 +8138,7 @@ void command_traindisc(Client *c, const Seperator *sep) t->Message(0, "Training disciplines"); if(t != c) c->Message(0, "Training disciplines for %s.", t->GetName()); - LogFile->write(EQEMuLog::Normal, "Train disciplines request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level); + LogFile->write(EQEmuLog::Normal, "Train disciplines request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level); for(curspell = 0, count = 0; curspell < SPDAT_RECORDS; curspell++) { @@ -8701,8 +8572,8 @@ void command_aggrozone(Client *c, const Seperator *sep) { if (!m) return; - int hate = atoi(sep->arg[1]); //should default to 0 if we don't enter anything - entity_list.AggroZone(m,hate); + uint32 hate = atoi(sep->arg[1]); //should default to 0 if we don't enter anything + entity_list.AggroZone(m, hate); c->Message(0, "Train to you! Last chance to go invulnerable..."); } @@ -10503,7 +10374,7 @@ void command_mysql(Client *c, const Seperator *sep) return; } - if ( strcasecmp( sep->arg[1], "help" ) == 0 ) { + if (strcasecmp(sep->arg[1], "help") == 0) { c->Message(0, "MYSQL In-Game CLI Interface:"); c->Message(0, "Example: #mysql query \"Query goes here quoted\" -s -h"); c->Message(0, "To use 'like \"%%something%%\" replace the %% with #"); @@ -10513,7 +10384,7 @@ void command_mysql(Client *c, const Seperator *sep) return; } - if ( strcasecmp( sep->arg[1], "query" ) == 0 ) { + if (strcasecmp(sep->arg[1], "query") == 0) { ///Parse switches here int argnum = 3; bool optionS = false; diff --git a/zone/common.h b/zone/common.h index aa24964fd..45f3bdb09 100644 --- a/zone/common.h +++ b/zone/common.h @@ -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 diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 93d8e4712..7c47f4fd8 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -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); diff --git a/zone/doors.cpp b/zone/doors.cpp index 1645cb6f9..b6f529e91 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -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; diff --git a/zone/effects.cpp b/zone/effects.cpp index c236fb942..ec463bddf 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -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); } diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 3a27fc42f..c39426953 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -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 *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); diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 5579b13f3..435dd6eea 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -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; } diff --git a/zone/embperl.cpp b/zone/embperl.cpp index 9f05d8711..e356ff7ac 100644 --- a/zone/embperl.cpp +++ b/zone/embperl.cpp @@ -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; diff --git a/zone/embxs.cpp b/zone/embxs.cpp index 164a0b2af..11b444ef0 100644 --- a/zone/embxs.cpp +++ b/zone/embxs.cpp @@ -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); } } diff --git a/zone/entity.cpp b/zone/entity.cpp index 0a4ab46b1..bfae263e9 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -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 &a, const std::pair &b) -{ - return a.first->GetSpawnTimeStamp() > b.first->GetSpawnTimeStamp(); -} - bool EntityList::MakeTrackPacket(Client *client) { std::list > 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 &a, const std::pair &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; diff --git a/zone/entity.h b/zone/entity.h index f8038cf9f..9d30e5af3 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -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); diff --git a/zone/exp.cpp b/zone/exp.cpp index 1aafb8a3f..7edd70864 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -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(); diff --git a/zone/forage.cpp b/zone/forage.cpp index c808fc418..24c621c52 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -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; } diff --git a/zone/groups.cpp b/zone/groups.cpp index 3395833bf..cf016e759 100644 --- a/zone/groups.cpp +++ b/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(); diff --git a/zone/guild.cpp b/zone/guild.cpp index 58b0f006e..39785f3dd 100644 --- a/zone/guild.cpp +++ b/zone/guild.cpp @@ -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; } diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 47cd3ceb1..b37b07f59 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -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::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::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++; } } - diff --git a/zone/hate_list.h b/zone/hate_list.h index 97f16f9d7..dda8cb21d 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -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& GetHateList() { return list; } - //For accessing the hate list via perl; don't use for anything else - std::list& 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 list; - Mob *owner; + std::list list; + Mob *hate_owner; }; -#endif +#endif \ No newline at end of file diff --git a/zone/horse.cpp b/zone/horse.cpp index 3d0863381..8c7bc23ba 100644 --- a/zone/horse.cpp +++ b/zone/horse.cpp @@ -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; } diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 343f6e337..42a05e175 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -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::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... 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: "" "%s" "", ret_link, inst->GetItem()->name - Master's Book of Wood Elven Culture - http://eqitems.13th-floor.org/phpBB2/viewtopic.php?p=510#510 -*/ + Master's Book of Wood Elven Culture + 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::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + if (src_slot_id == MainCursor) + { + if (dstitemid == 0) + { + SendCursorBuffer(); + } + std::list::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::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::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::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++) { diff --git a/zone/loottables.cpp b/zone/loottables.cpp index b6a2c8092..f652cdbe0 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -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; diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 7003378e9..b0127137f 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -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); diff --git a/zone/lua_hate_list.cpp b/zone/lua_hate_list.cpp index edca6ee11..e8c6a52df 100644 --- a/zone/lua_hate_list.cpp +++ b/zone/lua_hate_list.cpp @@ -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() { diff --git a/zone/lua_hate_list.h b/zone/lua_hate_list.h index 4dc6502f3..41d5d75f9 100644 --- a/zone/lua_hate_list.h +++ b/zone/lua_hate_list.h @@ -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 +class Lua_HateEntry : public Lua_Ptr { - 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(); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 089f311bf..054bb7728 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -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) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index a5c00c5f0..f272cd440 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -128,6 +128,7 @@ public: int GetPR(); int GetCR(); int GetCorruption(); + int GetPhR(); int GetMaxSTR(); int GetMaxSTA(); int GetMaxDEX(); diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index b05e7619f..1b1bfb8e8 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -695,6 +695,9 @@ bool LuaParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) { } bool LuaParser::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) { + if (itm == nullptr) { + return false; + } evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return false; @@ -738,6 +741,8 @@ void LuaParser::LoadGlobalPlayerScript(std::string filename) { } void LuaParser::LoadItemScript(std::string filename, ItemInst *item) { + if (item == nullptr) + return; std::string package_name = "item_"; package_name += std::to_string(static_cast(item->GetID())); diff --git a/zone/map.cpp b/zone/map.cpp index b6f4de2b5..5c917b955 100644 --- a/zone/map.cpp +++ b/zone/map.cpp @@ -58,6 +58,7 @@ Map::Map() { Map::~Map() { if(imp) { imp->rm->release(); + safe_delete(imp); } } @@ -887,4 +888,4 @@ void Map::TranslateVertex(Vertex &v, float tx, float ty, float tz) { v.x = v.x + tx; v.y = v.y + ty; v.z = v.z + tz; -} \ No newline at end of file +} diff --git a/zone/merc.cpp b/zone/merc.cpp index 56b68e84e..e50cb04c5 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -884,7 +884,7 @@ int32 Merc::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; } @@ -905,7 +905,7 @@ int32 Merc::CalcMaxMana() } #if EQDEBUG >= 11 - LogFile->write(EQEMuLog::Debug, "Merc::CalcMaxMana() called for %s - returning %d", GetName(), max_mana); + LogFile->write(EQEmuLog::Debug, "Merc::CalcMaxMana() called for %s - returning %d", GetName(), max_mana); #endif return max_mana; } @@ -1385,7 +1385,7 @@ void Merc::AI_Process() { rest_timer.Disable(); if(IsRooted()) - SetTarget(hate_list.GetClosest(this)); + SetTarget(hate_list.GetClosestEntOnHateList(this)); else FindTarget(); @@ -2454,11 +2454,11 @@ void Merc::CheckHateList() { Mob* groupMember = g->members[counter]; if(groupMember) { if(npc->IsOnHatelist(groupMember)) { - if(!hate_list.IsOnHateList(npc)) { + if(!hate_list.IsEntOnHateList(npc)) { float range = g->HasRole(groupMember, RolePuller) ? RuleI(Mercs, AggroRadiusPuller) : RuleI(Mercs, AggroRadius); range *= range; if(npc->DistNoRootNoZ(*this) < range) { - hate_list.Add(npc, 1); + hate_list.AddEntToHateList(npc, 1); } } } @@ -4450,7 +4450,7 @@ bool Merc::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, boo { if (!other) { SetTarget(nullptr); - LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Merc::Attack() for evaluation!"); + LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Merc::Attack() for evaluation!"); return false; } @@ -4644,13 +4644,6 @@ const char* Merc::GetRandomName(){ return name; } -bool Compare_Merc_Spells(MercSpell i, MercSpell j); - -bool Compare_Merc_Spells(MercSpell i, MercSpell j) -{ - return(i.slot > j.slot); -} - bool Merc::LoadMercSpells() { // loads mercs spells into list merc_spells.clear(); @@ -4683,7 +4676,9 @@ bool Merc::LoadMercSpells() { AddProcToWeapon(mercSpellEntryItr->spellid, true, mercSpellEntryItr->proc_chance); } } - std::sort(merc_spells.begin(), merc_spells.end(), Compare_Merc_Spells); + std::sort(merc_spells.begin(), merc_spells.end(), [](const MercSpell& a, const MercSpell& b) { + return a.slot > b.slot; + }); if (merc_spells.size() == 0) AIautocastspell_timer->Disable(); @@ -5990,7 +5985,7 @@ void NPC::LoadMercTypes() { auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in NPC::LoadMercTypes()"); + LogFile->write(EQEmuLog::Error, "Error in NPC::LoadMercTypes()"); return; } @@ -6023,7 +6018,7 @@ void NPC::LoadMercs() { if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in NPC::LoadMercTypes()"); + LogFile->write(EQEmuLog::Error, "Error in NPC::LoadMercTypes()"); return; } diff --git a/zone/merc.h b/zone/merc.h index f604d485c..3d181a82e 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -287,8 +287,8 @@ protected: uint16 skills[HIGHEST_SKILL+1]; uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs - uint16 d_meele_texture1; //this is an item Material value - uint16 d_meele_texture2; //this is an item Material value (offhand) + uint16 d_melee_texture1; //this is an item Material value + uint16 d_melee_texture2; //this is an item Material value (offhand) uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation uint8 sec_melee_type; //Sets the Secondary Weapon attack message and animation diff --git a/zone/mob.cpp b/zone/mob.cpp index 343f78d6e..4aa9a7305 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -375,7 +375,7 @@ Mob::Mob(const char* in_name, PathingRouteUpdateTimerLong = new Timer(RuleI(Pathing, RouteUpdateFrequencyLong)); DistractedFromGrid = false; PathingTraversedNodes = 0; - hate_list.SetOwner(this); + hate_list.SetHateOwner(this); m_AllowBeneficial = false; m_DisableMelee = false; @@ -899,7 +899,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.animation = 0; ns->spawn.findable = findable?1:0; ns->spawn.light = light; - ns->spawn.showhelm = 1; + ns->spawn.showhelm = (helmtexture && helmtexture != 0xFF) ? 1 : 0; ns->spawn.invis = (invisible || hidden) ? 1 : 0; // TODO: load this before spawning players ns->spawn.NPC = IsClient() ? 0 : 1; @@ -919,11 +919,11 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.drakkin_heritage = drakkin_heritage; ns->spawn.drakkin_tattoo = drakkin_tattoo; ns->spawn.drakkin_details = drakkin_details; - ns->spawn.equip_chest2 = texture; + ns->spawn.equip_chest2 = GetHerosForgeModel(1) != 0 ? 0xff : texture; // ns->spawn.invis2 = 0xff;//this used to be labeled beard.. if its not FF it will turn mob invis - if(helmtexture && helmtexture != 0xFF) + if (helmtexture && helmtexture != 0xFF && GetHerosForgeModel(0) == 0) { ns->spawn.helm=helmtexture; } else { @@ -948,7 +948,8 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName)); - for (i = 0; i < _MaterialCount; i++) + //for (i = 0; i < _MaterialCount; i++) + for (i = 0; i < 9; i++) { // Only Player Races Wear Armor if (Mob::IsPlayerRace(race) || i > 6) @@ -1265,7 +1266,7 @@ void Mob::ShowStats(Client* client) client->Message(0, " Mana: %i Max Mana: %i", GetMana(), GetMaxMana()); client->Message(0, " Total ATK: %i Worn/Spell ATK (Cap %i): %i", GetATK(), RuleI(Character, ItemATKCap), GetATKBonus()); 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, " 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, " Race: %i BaseRace: %i Texture: %i HelmTexture: %i Gender: %i BaseGender: %i", GetRace(), GetBaseRace(), GetTexture(), GetHelmTexture(), GetGender(), GetBaseGender()); if (client->Admin() >= 100) client->Message(0, " EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted); @@ -2523,8 +2524,8 @@ bool Mob::RemoveFromHateList(Mob* mob) bool bFound = false; if(IsEngaged()) { - bFound = hate_list.RemoveEnt(mob); - if(hate_list.IsEmpty()) + bFound = hate_list.RemoveEntFromHateList(mob); + if(hate_list.IsHateListEmpty()) { AI_Event_NoLongerEngaged(); zone->DelAggroMob(); @@ -2532,7 +2533,7 @@ bool Mob::RemoveFromHateList(Mob* mob) } if(GetTarget() == mob) { - SetTarget(hate_list.GetTop(this)); + SetTarget(hate_list.GetEntWithMostHateOnList(this)); } return bFound; @@ -2542,12 +2543,12 @@ void Mob::WipeHateList() { if(IsEngaged()) { - hate_list.Wipe(); + hate_list.WipeHateList(); AI_Event_NoLongerEngaged(); } else { - hate_list.Wipe(); + hate_list.WipeHateList(); } } @@ -2701,7 +2702,6 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const int32 Mob::GetHerosForgeModel(uint8 material_slot) const { - uint32 HeroModel = 0; if (material_slot >= 0 && material_slot < MaterialPrimary) { @@ -2712,7 +2712,7 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const if (item != 0 && invslot != INVALID_INDEX) { - if (this->IsClient()) + if (IsClient()) { const ItemInst* inst = CastToClient()->m_inv[invslot]; if (inst) @@ -2734,9 +2734,22 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const HeroModel = item->HerosForgeModel; } } + + if (IsNPC()) + { + HeroModel = CastToNPC()->GetHeroForgeModel(); + // Robes require full model number, and should only be sent to chest, arms, wrists, and legs slots + if (HeroModel > 1000 && material_slot != 1 && material_slot != 2 && material_slot != 3 && material_slot != 5) + { + HeroModel = 0; + } + } } - if (HeroModel > 0) + // Auto-Convert Hero Model to match the slot + // Otherwise, use the exact Model if model is > 999 + // Robes for example are 11607 to 12107 in RoF + if (HeroModel > 0 && HeroModel < 1000) { HeroModel *= 100; HeroModel += material_slot; @@ -3446,7 +3459,7 @@ void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsP } else if (IsPet){ - int count = hate_list.SummonedPetCount(this); + int count = hate_list.GetSummonedPetCountOnHateList(this); if ((base2 >= 220 && base2 <= 250) && count >= (base2 - 220)){ use_spell = true; } diff --git a/zone/mob.h b/zone/mob.h index 0bd95fef1..1890ac2bf 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -369,7 +369,7 @@ public: inline virtual int32 GetPR() const { return PR + itembonuses.PR + spellbonuses.PR; } inline virtual int32 GetCR() const { return CR + itembonuses.CR + spellbonuses.CR; } inline virtual int32 GetCorrup() const { return Corrup + itembonuses.Corrup + spellbonuses.Corrup; } - inline virtual int32 GetPhR() const { return PhR; } + inline virtual int32 GetPhR() const { return PhR; } // PhR bonuses not implemented yet inline StatBonuses GetItemBonuses() const { return itembonuses; } inline StatBonuses GetSpellBonuses() const { return spellbonuses; } inline StatBonuses GetAABonuses() const { return aabonuses; } @@ -451,19 +451,19 @@ public: static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel); inline uint32 GetLevelCon(uint8 iOtherLevel) const { return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GREEN; } - virtual void AddToHateList(Mob* other, int32 hate = 0, int32 damage = 0, bool iYellForHelp = true, + virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false); bool RemoveFromHateList(Mob* mob); - void SetHate(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.Set(other,hate,damage);} - void HalveAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHate(other, (in_hate > 1 ? in_hate / 2 : 1)); } - void DoubleAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHate(other, (in_hate ? in_hate * 2 : 1)); } - uint32 GetHateAmount(Mob* tmob, bool is_dam = false) { return hate_list.GetEntHate(tmob,is_dam);} - uint32 GetDamageAmount(Mob* tmob) { return hate_list.GetEntHate(tmob, true);} - Mob* GetHateTop() { return hate_list.GetTop(this);} - Mob* GetHateDamageTop(Mob* other) { return hate_list.GetDamageTop(other);} - Mob* GetHateRandom() { return hate_list.GetRandom();} - Mob* GetHateMost() { return hate_list.GetMostHate();} - bool IsEngaged() { return(!hate_list.IsEmpty()); } + void SetHateAmountOnEnt(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.SetHateAmountOnEnt(other,hate,damage);} + void HalveAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHateAmountOnEnt(other, (in_hate > 1 ? in_hate / 2 : 1)); } + void DoubleAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHateAmountOnEnt(other, (in_hate ? in_hate * 2 : 1)); } + uint32 GetHateAmount(Mob* tmob, bool is_dam = false) { return hate_list.GetEntHateAmount(tmob,is_dam);} + uint32 GetDamageAmount(Mob* tmob) { return hate_list.GetEntHateAmount(tmob, true);} + Mob* GetHateTop() { return hate_list.GetEntWithMostHateOnList(this);} + Mob* GetHateDamageTop(Mob* other) { return hate_list.GetDamageTopOnHateList(other);} + Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();} + Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();} + bool IsEngaged() { return(!hate_list.IsHateListEmpty()); } bool HateSummon(); void FaceTarget(Mob* MobToFace = 0); void SetHeading(float iHeading) { if(m_Position.m_Heading != iHeading) { pLastChange = Timer::GetCurrentTime(); @@ -472,8 +472,8 @@ public: void AddFeignMemory(Client* attacker); void RemoveFromFeignMemory(Client* attacker); void ClearFeignMemory(); - void PrintHateListToClient(Client *who) { hate_list.PrintToClient(who); } - std::list& GetHateList() { return hate_list.GetHateList(); } + void PrintHateListToClient(Client *who) { hate_list.PrintHateListToClient(who); } + std::list& GetHateList() { return hate_list.GetHateList(); } bool CheckLosFN(Mob* other); bool CheckLosFN(float posX, float posY, float posZ, float mobSize); inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); } @@ -797,7 +797,7 @@ public: void CheckFlee(); inline bool IsBlind() { return spellbonuses.IsBlind; } - inline bool CheckAggro(Mob* other) {return hate_list.IsOnHateList(other);} + inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);} float CalculateHeadingToTarget(float in_x, float in_y); bool CalculateNewPosition(float x, float y, float z, float speed, bool checkZ = false); virtual bool CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ = true); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 00921948d..f6310801d 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -491,7 +491,7 @@ void Mob::AI_Start(uint32 iMoveDelay) { pAggroRange = 70; if (GetAssistRange() == 0) pAssistRange = 70; - hate_list.Wipe(); + hate_list.WipeHateList(); m_Delta = xyz_heading::Origin(); pRunAnimSpeed = 0; @@ -548,7 +548,7 @@ void Mob::AI_Stop() { safe_delete(AIscanarea_timer); safe_delete(AIfeignremember_timer); - hate_list.Wipe(); + hate_list.WipeHateList(); } void NPC::AI_Stop() { @@ -811,12 +811,12 @@ void Client::AI_Process() if (engaged) { if (IsRooted()) - SetTarget(hate_list.GetClosest(this)); + SetTarget(hate_list.GetClosestEntOnHateList(this)); else { if(AItarget_check_timer->Check()) { - SetTarget(hate_list.GetTop(this)); + SetTarget(hate_list.GetEntWithMostHateOnList(this)); } } @@ -1036,7 +1036,7 @@ void Mob::AI_Process() { // if(RuleB(Combat, EnableFearPathing)){ if(curfp) { - if(IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosest(this)))) { + if(IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) { //make sure everybody knows were not moving, for appearance sake if(IsMoving()) { @@ -1086,18 +1086,18 @@ void Mob::AI_Process() { // we are prevented from getting here if we are blind and don't have a target in range // from above, so no extra blind checks needed if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind()) - SetTarget(hate_list.GetClosest(this)); + SetTarget(hate_list.GetClosestEntOnHateList(this)); else { if(AItarget_check_timer->Check()) { if (IsFocused()) { if (!target) { - SetTarget(hate_list.GetTop(this)); + SetTarget(hate_list.GetEntWithMostHateOnList(this)); } } else { if (!ImprovedTaunt()) - SetTarget(hate_list.GetTop(this)); + SetTarget(hate_list.GetEntWithMostHateOnList(this)); } } @@ -1373,7 +1373,7 @@ void Mob::AI_Process() { if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { auto targetPosition = xyz_location(target->GetX(), target->GetY(), target->GetZ()); if(!zone->watermap->InLiquid(targetPosition)) { - Mob *tar = hate_list.GetTop(this); + Mob *tar = hate_list.GetEntWithMostHateOnList(this); if(tar == target) { WipeHateList(); Heal(); @@ -2333,7 +2333,6 @@ create table npc_spells_entries ( bool IsSpellInList(DBnpcspells_Struct* spell_list, int16 iSpellID); bool IsSpellEffectInList(DBnpcspellseffects_Struct* spelleffect_list, uint16 iSpellEffectID, int32 base, int32 limit, int32 max); -bool Compare_AI_Spells(AISpells_Struct i, AISpells_Struct j); bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) { // ok, this function should load the list, and the parent list then shove them into the struct and sort @@ -2458,7 +2457,9 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) { spell_list->entries[i].resist_adjust); } } - std::sort(AIspells.begin(), AIspells.end(), Compare_AI_Spells); + std::sort(AIspells.begin(), AIspells.end(), [](const AISpells_Struct& a, const AISpells_Struct& b) { + return a.priority > b.priority; + }); if (IsValidSpell(attack_proc_spell)) AddProcToWeapon(attack_proc_spell, true, proc_chance); @@ -2598,11 +2599,6 @@ bool IsSpellInList(DBnpcspells_Struct* spell_list, int16 iSpellID) { return false; } -bool Compare_AI_Spells(AISpells_Struct i, AISpells_Struct j) -{ - return(i.priority > j.priority); -} - // adds a spell to the list, taking into account priority and resorting list as needed. void NPC::AddSpellToNPCList(int16 iPriority, int16 iSpellID, uint16 iType, int16 iManaCost, int32 iRecastDelay, int16 iResistAdjust) diff --git a/zone/net.cpp b/zone/net.cpp index 9b4080eb2..25c770f14 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -609,7 +609,7 @@ void LoadSpells(EQEmu::MemoryMappedFile **mmf) { spells = reinterpret_cast((*mmf)->Get()); mutex.Unlock(); } catch(std::exception &ex) { - LogFile->write(EQEMuLog::Error, "Error loading spells: %s", ex.what()); + LogFile->write(EQEmuLog::Error, "Error loading spells: %s", ex.what()); return; } diff --git a/zone/npc.cpp b/zone/npc.cpp index 0212a91ed..c48254768 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -253,8 +253,10 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const xyz_heading& position, int if(!IsMerc()) AI_Start(); - d_meele_texture1 = d->d_meele_texture1; - d_meele_texture2 = d->d_meele_texture2; + d_melee_texture1 = d->d_melee_texture1; + d_melee_texture2 = d->d_melee_texture2; + herosforgemodel = d->herosforgemodel; + ammo_idfile = d->ammo_idfile; memset(equipment, 0, sizeof(equipment)); prim_melee_type = d->prim_melee_type; @@ -262,9 +264,9 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const xyz_heading& position, int ranged_type = d->ranged_type; // If Melee Textures are not set, set attack type to Hand to Hand as default - if(!d_meele_texture1) + if(!d_melee_texture1) prim_melee_type = 28; - if(!d_meele_texture2) + if(!d_melee_texture2) sec_melee_type = 28; //give NPCs skill values... @@ -486,32 +488,27 @@ void NPC::ClearItemList() { itemlist.clear(); } -void NPC::QueryLoot(Client* to) { - int x = 0; +void NPC::QueryLoot(Client* to) +{ to->Message(0, "Coin: %ip %ig %is %ic", platinum, gold, silver, copper); - ItemList::iterator cur,end; - cur = itemlist.begin(); - end = itemlist.end(); - for(; cur != end; ++cur) { + int x = 0; + for(ItemList::iterator cur = itemlist.begin(); cur != itemlist.end(); ++cur, ++x) { const Item_Struct* item = database.GetItem((*cur)->item_id); - if (item) - if (to->GetClientVersion() >= EQClientRoF) - { - to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12); - } - else if (to->GetClientVersion() >= EQClientSoF) - { - to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X00000000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12); - } - else - { - to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12); - } - else - LogFile->write(EQEMuLog::Error, "Database error, invalid item"); - x++; + if (item == nullptr) { + LogFile->write(EQEmuLog::Error, "Database error, invalid item"); + continue; + } + + Client::TextLink linker; + linker.SetLinkType(linker.linkItemData); + linker.SetItemData(item); + + auto item_link = linker.GenerateLink(); + + to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", item_link.c_str(), item->ID, (*cur)->min_level, (*cur)->max_level); } + to->Message(0, "%i items on %s.", x, GetName()); } @@ -912,8 +909,8 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const xyz_heading& position, Client npc_type->texture = atoi(sep.arg[3]); npc_type->light = 0; npc_type->runspeed = 1.25; - npc_type->d_meele_texture1 = atoi(sep.arg[7]); - npc_type->d_meele_texture2 = atoi(sep.arg[8]); + npc_type->d_melee_texture1 = atoi(sep.arg[7]); + npc_type->d_melee_texture2 = atoi(sep.arg[8]); npc_type->merchanttype = atoi(sep.arg[9]); npc_type->bodytype = atoi(sep.arg[10]); @@ -945,7 +942,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const xyz_heading& position, Client client->Message(0, "Current/Max HP: %i", npc->max_hp); client->Message(0, "Gender: %u", npc->gender); client->Message(0, "Class: %u", npc->class_); - client->Message(0, "Weapon Item Number: %u/%u", npc->d_meele_texture1, npc->d_meele_texture2); + client->Message(0, "Weapon Item Number: %u/%u", npc->d_melee_texture1, npc->d_melee_texture2); client->Message(0, "MerchantID: %u", npc->MerchantType); client->Message(0, "Bodytype: %u", npc->bodytype); } @@ -995,7 +992,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); return false; } npc_type_id = results.LastInsertedID(); @@ -1012,7 +1009,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); return false; } npc_type_id = results.LastInsertedID(); @@ -1024,7 +1021,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C query = StringFormat("INSERT INTO spawngroup (id, name) VALUES(%i, '%s-%s')", 0, zone, spawn->GetName()); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); return false; } uint32 spawngroupid = results.LastInsertedID(); @@ -1038,7 +1035,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C spawn->GetHeading(), spawngroupid); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -1049,7 +1046,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C spawngroupid, npc_type_id, 100); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -1066,7 +1063,7 @@ uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_ve zone, spawn->GetName(), Timer::GetCurrentTime()); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } last_insert_id = results.LastInsertedID(); @@ -1089,7 +1086,7 @@ uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_ve spawn->GetHeading(), last_insert_id); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } spawnid = results.LastInsertedID(); @@ -1101,7 +1098,7 @@ uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_ve last_insert_id, spawn->GetNPCTypeID(), 100); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -1323,9 +1320,9 @@ int32 NPC::GetEquipmentMaterial(uint8 material_slot) const case MaterialChest: return texture; case MaterialPrimary: - return d_meele_texture1; + return d_melee_texture1; case MaterialSecondary: - return d_meele_texture2; + return d_melee_texture2; default: //they have nothing in the slot, and its not a special slot... they get nothing. return(0); @@ -1663,7 +1660,7 @@ void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool rem { if(database.SetSpecialAttkFlag(this->GetNPCTypeID(), orig_parse)) { - LogFile->write(EQEMuLog::Normal, "NPCTypeID: %i flagged to '%s' for Special Attacks.\n",this->GetNPCTypeID(),orig_parse); + LogFile->write(EQEmuLog::Normal, "NPCTypeID: %i flagged to '%s' for Special Attacks.\n",this->GetNPCTypeID(),orig_parse); } } } @@ -2124,10 +2121,10 @@ uint32 NPC::GetSpawnPointID() const void NPC::NPCSlotTexture(uint8 slot, uint16 texture) { if (slot == 7) { - d_meele_texture1 = texture; + d_melee_texture1 = texture; } else if (slot == 8) { - d_meele_texture2 = texture; + d_melee_texture2 = texture; } else if (slot < 6) { // Reserved for texturing individual armor slots diff --git a/zone/npc.h b/zone/npc.h index a54d3e0ba..7e16c02f3 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -243,8 +243,8 @@ public: inline int32 GetNPCFactionID() const { return npc_faction_id; } inline int32 GetPrimaryFaction() const { return primary_faction; } - int32 GetNPCHate(Mob* in_ent) {return hate_list.GetEntHate(in_ent);} - bool IsOnHatelist(Mob*p) { return hate_list.IsOnHateList(p);} + int32 GetNPCHate(Mob* in_ent) {return hate_list.GetEntHateAmount(in_ent);} + bool IsOnHatelist(Mob*p) { return hate_list.IsEntOnHateList(p);} void SetNPCFactionID(int32 in) { npc_faction_id = in; database.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction); } @@ -260,6 +260,7 @@ public: void SetPetSpellID(uint16 amt) {pet_spell_id = amt;} uint32 GetMaxDamage(uint8 tlevel); void SetTaunting(bool tog) {taunting = tog;} + bool IsTaunting() const { return taunting; } void PickPocket(Client* thief); void StartSwarmTimer(uint32 duration) { swarm_timer.Start(duration); } void AddLootDrop(const Item_Struct*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false); @@ -397,6 +398,9 @@ public: void mod_npc_killed(Mob* oos); void AISpellsList(Client *c); + uint32 GetHeroForgeModel() const { return herosforgemodel; } + void SetHeroForgeModel(uint32 model) { herosforgemodel = model; } + bool IsRaidTarget() const { return raid_target; }; protected: @@ -485,8 +489,10 @@ protected: uint16 skills[HIGHEST_SKILL+1]; uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs - uint16 d_meele_texture1; //this is an item Material value - uint16 d_meele_texture2; //this is an item Material value (offhand) + + uint32 herosforgemodel; //this is the Hero Forge Armor Model (i.e 63 or 84 or 203) + uint16 d_melee_texture1; //this is an item Material value + uint16 d_melee_texture2; //this is an item Material value (offhand) const char* ammo_idfile; //this determines projectile graphic "IT###" (see item field 'idfile') uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation uint8 sec_melee_type; //Sets the Secondary Weapon attack message and animation diff --git a/zone/object.cpp b/zone/object.cpp index fa7598d39..c8bde8f1f 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -118,7 +118,15 @@ Object::Object(Client* client, const ItemInst* inst) m_data.heading = client->GetHeading(); m_data.x = client->GetX(); m_data.y = client->GetY(); - m_data.z = client->GetZ(); + if (client->GetClientVersion() >= EQClientRoF2) + { + // RoF2 places items at player's Z, which is 0.625 of their height. + m_data.z = client->GetZ() - (client->GetSize() * 0.625f); + } + else + { + m_data.z = client->GetZ(); + } m_data.zone_id = zone->GetZoneID(); decay_timer.Start(); @@ -328,7 +336,7 @@ const ItemInst* Object::GetItem(uint8 index) { void Object::PutItem(uint8 index, const ItemInst* inst) { if (index > 9) { - LogFile->write(EQEMuLog::Error, "Object::PutItem: Invalid index specified (%i)", index); + LogFile->write(EQEmuLog::Error, "Object::PutItem: Invalid index specified (%i)", index); return; } @@ -590,7 +598,7 @@ uint32 ZoneDatabase::AddObject(uint32 type, uint32 icon, const Object_Struct& ob safe_delete_array(object_name); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Unable to insert object: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Unable to insert object: %s", results.ErrorMessage().c_str()); return 0; } @@ -627,7 +635,7 @@ void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Objec safe_delete_array(object_name); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Unable to update object: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Unable to update object: %s", results.ErrorMessage().c_str()); return; } @@ -672,7 +680,7 @@ void ZoneDatabase::DeleteObject(uint32 id) std::string query = StringFormat("DELETE FROM object WHERE id = %i", id); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Unable to delete object: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Unable to delete object: %s", results.ErrorMessage().c_str()); } } diff --git a/zone/pathing.cpp b/zone/pathing.cpp index a9a481d5b..aba968f0b 100644 --- a/zone/pathing.cpp +++ b/zone/pathing.cpp @@ -61,19 +61,19 @@ PathManager* PathManager::LoadPathFile(const char* ZoneName) if(Ret->loadPaths(PathFile)) { - LogFile->write(EQEMuLog::Status, "Path File %s loaded.", ZonePathFileName); + LogFile->write(EQEmuLog::Status, "Path File %s loaded.", ZonePathFileName); } else { - LogFile->write(EQEMuLog::Error, "Path File %s failed to load.", ZonePathFileName); + LogFile->write(EQEmuLog::Error, "Path File %s failed to load.", ZonePathFileName); safe_delete(Ret); } fclose(PathFile); } else { - LogFile->write(EQEMuLog::Error, "Path File %s not found.", ZonePathFileName); + LogFile->write(EQEmuLog::Error, "Path File %s not found.", ZonePathFileName); } return Ret; @@ -103,18 +103,18 @@ bool PathManager::loadPaths(FILE *PathFile) if(strncmp(Magic, "EQEMUPATH", 9)) { - LogFile->write(EQEMuLog::Error, "Bad Magic String in .path file."); + LogFile->write(EQEmuLog::Error, "Bad Magic String in .path file."); return false; } fread(&Head, sizeof(Head), 1, PathFile); - LogFile->write(EQEMuLog::Status, "Path File Header: Version %ld, PathNodes %ld", + LogFile->write(EQEmuLog::Status, "Path File Header: Version %ld, PathNodes %ld", (long)Head.version, (long)Head.PathNodeCount); if(Head.version != 2) { - LogFile->write(EQEMuLog::Error, "Unsupported path file version."); + LogFile->write(EQEmuLog::Error, "Unsupported path file version."); return false; } @@ -138,7 +138,7 @@ bool PathManager::loadPaths(FILE *PathFile) { if(PathNodes[i].Neighbours[j].id > MaxNodeID) { - LogFile->write(EQEMuLog::Error, "Path Node %i, Neighbour %i (%i) out of range.", i, j, PathNodes[i].Neighbours[j].id); + LogFile->write(EQEmuLog::Error, "Path Node %i, Neighbour %i (%i) out of range.", i, j, PathNodes[i].Neighbours[j].id); PathFileValid = false; } @@ -345,10 +345,10 @@ bool CheckLOSBetweenPoints(Map::Vertex start, Map::Vertex end) { return true; } -bool SortPathNodesByDistance(PathNodeSortStruct n1, PathNodeSortStruct n2) +auto path_compare = [](const PathNodeSortStruct& a, const PathNodeSortStruct& b) { - return n1.Distance < n2.Distance; -} + return a.Distance < b.Distance; +}; std::deque PathManager::FindRoute(Map::Vertex Start, Map::Vertex End) { @@ -382,7 +382,7 @@ std::deque PathManager::FindRoute(Map::Vertex Start, Map::Vertex End) } } - std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance); + std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare); for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator) { @@ -420,7 +420,7 @@ std::deque PathManager::FindRoute(Map::Vertex Start, Map::Vertex End) } } - std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance); + std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare); for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator) { @@ -573,8 +573,8 @@ void PathManager::SpawnPathNodes() npc_type->texture = 1; npc_type->light = 0; npc_type->runspeed = 0; - npc_type->d_meele_texture1 = 1; - npc_type->d_meele_texture2 = 1; + npc_type->d_melee_texture1 = 1; + npc_type->d_melee_texture2 = 1; npc_type->merchanttype = 1; npc_type->bodytype = 1; @@ -1120,7 +1120,7 @@ int PathManager::FindNearestPathNode(Map::Vertex Position) } } - std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance); + std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare); for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator) { @@ -1563,8 +1563,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques npc_type->texture = 1; npc_type->light = 0; npc_type->runspeed = 0; - npc_type->d_meele_texture1 = 1; - npc_type->d_meele_texture2 = 1; + npc_type->d_melee_texture1 = 1; + npc_type->d_melee_texture2 = 1; npc_type->merchanttype = 1; npc_type->bodytype = 1; npc_type->STR = 150; @@ -1624,8 +1624,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques npc_type->texture = 1; npc_type->light = 0; npc_type->runspeed = 0; - npc_type->d_meele_texture1 = 1; - npc_type->d_meele_texture2 = 1; + npc_type->d_melee_texture1 = 1; + npc_type->d_melee_texture2 = 1; npc_type->merchanttype = 1; npc_type->bodytype = 1; npc_type->STR = 150; diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 95c96fd96..df0a48e69 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -5057,14 +5057,21 @@ XS(XS_Client_UpdateTaskActivity); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_UpdateTaskActivity) { dXSARGS; - if (items != 4) - Perl_croak(aTHX_ "Usage: Client::UpdateTaskActivity(THIS, TaskID, ActivityID, Count)"); + if (items < 4) + Perl_croak(aTHX_ "Usage: Client::UpdateTaskActivity(THIS, TaskID, ActivityID, Count, [ignore_quest_update])"); { + bool ignore_quest_update = false; + Client * THIS; + int TaskID = (int)SvIV(ST(1)); int ActivityID = (int)SvIV(ST(2)); int Count = (int)SvUV(ST(3)); + if (items == 5){ + ignore_quest_update = (bool)SvTRUE(ST(4)); + } + if (sv_derived_from(ST(0), "Client")) { IV tmp = SvIV((SV*)SvRV(ST(0))); THIS = INT2PTR(Client *,tmp); @@ -5074,7 +5081,7 @@ XS(XS_Client_UpdateTaskActivity) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->UpdateTaskActivity(TaskID, ActivityID, Count); + THIS->UpdateTaskActivity(TaskID, ActivityID, Count, ignore_quest_update); } XSRETURN_EMPTY; } @@ -6305,7 +6312,7 @@ XS(boot_Client) newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$"); newXSproto(strcpy(buf, "GetFreeSpellBookSlot"), XS_Client_GetFreeSpellBookSlot, file, "$;$"); newXSproto(strcpy(buf, "GetSpellBookSlotBySpellID"), XS_Client_GetSpellBookSlotBySpellID, file, "$$"); - newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$"); + newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$;$"); newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$"); newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$"); newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$"); diff --git a/zone/perl_hateentry.cpp b/zone/perl_hateentry.cpp index fa65e8b39..6e8b2de9e 100644 --- a/zone/perl_hateentry.cpp +++ b/zone/perl_hateentry.cpp @@ -40,19 +40,19 @@ XS(XS_HateEntry_GetEnt) if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetData(THIS)"); { - tHateEntry * THIS; + struct_HateList * THIS; Mob * RETVAL; if (sv_derived_from(ST(0), "HateEntry")) { IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(tHateEntry *,tmp); + THIS = INT2PTR(struct_HateList *,tmp); } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->ent; + RETVAL = THIS->entity_on_hatelist; ST(0) = sv_newmortal(); sv_setref_pv(ST(0), "Mob", (void*)RETVAL); } @@ -66,20 +66,20 @@ XS(XS_HateEntry_GetHate) if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetHate(THIS)"); { - tHateEntry * THIS; + struct_HateList * THIS; int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "HateEntry")) { IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(tHateEntry *,tmp); + THIS = INT2PTR(struct_HateList *,tmp); } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->hate; + RETVAL = THIS->stored_hate_amount; XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); @@ -92,20 +92,20 @@ XS(XS_HateEntry_GetDamage) if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetDamage(THIS)"); { - tHateEntry * THIS; + struct_HateList * THIS; int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "HateEntry")) { IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(tHateEntry *,tmp); + THIS = INT2PTR(struct_HateList *,tmp); } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->damage; + RETVAL = THIS->hatelist_damage; XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 00939ed31..790651459 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -2933,6 +2933,32 @@ XS(XS_Mob_GetCorruption) XSRETURN(1); } +XS(XS_Mob_GetPhR); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_GetPhR) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Mob::GetPhR(THIS)"); + { + Mob * THIS; + int32 RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Mob"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetPhR(); + XSprePUSH; PUSHi((IV)RETVAL); + } + XSRETURN(1); +} + XS(XS_Mob_GetMaxSTR); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_GetMaxSTR) { @@ -5354,7 +5380,7 @@ XS(XS_Mob_SetHate) damage = (int32)SvIV(ST(3)); } - THIS->SetHate(other, hate, damage); + THIS->SetHateAmountOnEnt(other, hate, damage); } XSRETURN_EMPTY; } @@ -6599,7 +6625,7 @@ XS(XS_Mob_GetHateList) while(iter != hate_list.end()) { - tHateEntry *entry = (*iter); + struct_HateList *entry = (*iter); ST(0) = sv_newmortal(); sv_setref_pv(ST(0), "HateEntry", (void*)entry); XPUSHs(ST(0)); @@ -8459,7 +8485,8 @@ XS(boot_Mob) newXSproto(strcpy(buf, "GetDR"), XS_Mob_GetDR, file, "$"); newXSproto(strcpy(buf, "GetPR"), XS_Mob_GetPR, file, "$"); newXSproto(strcpy(buf, "GetCR"), XS_Mob_GetCR, file, "$"); - newXSproto(strcpy(buf, "GetCorruption"), XS_Mob_GetCR, file, "$"); + newXSproto(strcpy(buf, "GetCorruption"), XS_Mob_GetCorruption, file, "$"); + newXSproto(strcpy(buf, "GetPhR"), XS_Mob_GetPhR, file, "$"); newXSproto(strcpy(buf, "GetMaxSTR"), XS_Mob_GetMaxSTR, file, "$"); newXSproto(strcpy(buf, "GetMaxSTA"), XS_Mob_GetMaxSTA, file, "$"); newXSproto(strcpy(buf, "GetMaxDEX"), XS_Mob_GetMaxDEX, file, "$"); diff --git a/zone/petitions.cpp b/zone/petitions.cpp index 76f902a9d..0329675d7 100644 --- a/zone/petitions.cpp +++ b/zone/petitions.cpp @@ -212,7 +212,7 @@ void ZoneDatabase::DeletePetitionFromDB(Petition* wpet) { std::string query = StringFormat("DELETE FROM petitions WHERE petid = %i", wpet->GetID()); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in DeletePetitionFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in DeletePetitionFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); } @@ -226,7 +226,7 @@ void ZoneDatabase::UpdatePetitionToDB(Petition* wpet) { wpet->CheckedOut() ? 1: 0, wpet->GetID()); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in UpdatePetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in UpdatePetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); } @@ -253,12 +253,12 @@ void ZoneDatabase::InsertPetitionToDB(Petition* wpet) safe_delete_array(petitiontext); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in InsertPetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in InsertPetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } #if EQDEBUG >= 5 - LogFile->write(EQEMuLog::Debug, "New petition created"); + LogFile->write(EQEmuLog::Debug, "New petition created"); #endif } @@ -272,7 +272,7 @@ void ZoneDatabase::RefreshPetitionsFromDB() "FROM petitions ORDER BY petid"; auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in RefreshPetitionsFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in RefreshPetitionsFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } diff --git a/zone/pets.cpp b/zone/pets.cpp index a36acd9d6..051eb3253 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -243,7 +243,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, PetRecord record; if(!database.GetPoweredPetEntry(pettype, act_power, &record)) { Message(13, "Unable to find data for pet %s", pettype); - LogFile->write(EQEMuLog::Error, "Unable to find data for pet %s, check pets table.", pettype); + LogFile->write(EQEmuLog::Error, "Unable to find data for pet %s, check pets table.", pettype); return; } @@ -251,7 +251,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, const NPCType *base = database.GetNPCType(record.npc_type); if(base == nullptr) { Message(13, "Unable to load NPC data for pet %s", pettype); - LogFile->write(EQEMuLog::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type); + LogFile->write(EQEmuLog::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type); return; } @@ -372,7 +372,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, auto results = database.QueryDatabase(query); if (!results.Success()) { // if the database query failed - LogFile->write(EQEMuLog::Error, "Error querying database for monster summoning pet in zone %s (%s)", zone->GetShortName(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error querying database for monster summoning pet in zone %s (%s)", zone->GetShortName(), results.ErrorMessage().c_str()); } if (results.RowCount() != 0) { @@ -393,8 +393,9 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, npc_type->gender = monster->gender; npc_type->luclinface = monster->luclinface; npc_type->helmtexture = monster->helmtexture; + npc_type->herosforgemodel = monster->herosforgemodel; } else - LogFile->write(EQEMuLog::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid); + LogFile->write(EQEmuLog::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid); } @@ -455,7 +456,7 @@ bool ZoneDatabase::GetPoweredPetEntry(const char *pet_type, int16 petpower, PetR pet_type, petpower); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetPoweredPetEntry query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetPoweredPetEntry query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -655,13 +656,13 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) { std::string query = StringFormat("SELECT nested_set FROM pets_equipmentset WHERE set_id = '%s'", curset); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } if (results.RowCount() != 1) { // invalid set reference, it doesn't exist - LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems equipment set '%d' does not exist", curset); + LogFile->write(EQEmuLog::Error, "Error in GetBasePetItems equipment set '%d' does not exist", curset); return false; } @@ -671,7 +672,7 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) { query = StringFormat("SELECT slot, item_id FROM pets_equipmentset_entries WHERE set_id='%s'", curset); results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); else { for (row = results.begin(); row != results.end(); ++row) { diff --git a/zone/pets.h b/zone/pets.h index db78accea..f0c71fbe7 100644 --- a/zone/pets.h +++ b/zone/pets.h @@ -1,26 +1,37 @@ #ifndef PETS_H #define PETS_H -#define PET_BACKOFF 1 -#define PET_GETLOST 2 -#define PET_HEALTHREPORT 4 -#define PET_GUARDHERE 5 -#define PET_GUARDME 6 -#define PET_ATTACK 7 -#define PET_FOLLOWME 8 -#define PET_SITDOWN 9 -#define PET_STANDUP 10 -#define PET_TAUNT 11 -#define PET_HOLD 12 -#define PET_NOTAUNT 14 -#define PET_LEADER 16 -#define PET_SLUMBER 17 -#define PET_NOCAST 18 -#define PET_FOCUS 19 -#define PET_FOCUS_ON 25 -#define PET_FOCUS_OFF 26 -#define PET_HOLD_ON 27 -#define PET_HOLD_OFF 28 +// Defines based on the RoF2 Client +#define PET_HEALTHREPORT 0 // 0x00 - /pet health or Pet Window +#define PET_LEADER 1 // 0x01 - /pet leader or Pet Window +#define PET_ATTACK 2 // 0x02 - /pet attack or Pet Window +#define PET_QATTACK 3 // 0x03 - /pet qattack or Pet Window +#define PET_FOLLOWME 4 // 0x04 - /pet follow or Pet Window +#define PET_GUARDHERE 5 // 0x05 - /pet guard or Pet Window +#define PET_SIT 6 // 0x06 - /pet sit or Pet Window +#define PET_SITDOWN 7 // 0x07 - /pet sit on +#define PET_STANDUP 8 // 0x08 - /pet sit off +#define PET_STOP 9 // 0x09 - /pet stop or Pet Window - Not implemented +#define PET_STOP_ON 10 // 0x0a - /pet stop on - Not implemented +#define PET_STOP_OFF 11 // 0x0b - /pet stop off - Not implemented +#define PET_TAUNT 12 // 0x0c - /pet taunt or Pet Window +#define PET_TAUNT_ON 13 // 0x0d - /pet taunt on +#define PET_TAUNT_OFF 14 // 0x0e - /pet taunt off +#define PET_HOLD 15 // 0x0f - /pet hold or Pet Window +#define PET_HOLD_ON 16 // 0x10 - /pet hold on +#define PET_HOLD_OFF 17 // 0x11 - /pet hold off +#define PET_SLUMBER 18 // 0x12 - What activates this? - define guessed +#define PET_SLUMBER_ON 19 // 0x13 - What activates this? - define guessed +#define PET_SLUMBER_OFF 20 // 0x14 - What activates this? - define guessed +#define PET_SPELLHOLD 21 // 0x15 - /pet no cast or /pet spellhold or Pet Window +#define PET_SPELLHOLD_ON 22 // 0x16 - /pet spellhold on +#define PET_SPELLHOLD_OFF 23 // 0x17 - /pet spellhold off +#define PET_FOCUS 24 // 0x18 - /pet focus or Pet Window +#define PET_FOCUS_ON 25 // 0x19 - /pet focus on +#define PET_FOCUS_OFF 26 // 0x1a - /pet focus off +#define PET_BACKOFF 28 // 0x1c - /pet back off +#define PET_GETLOST 29 // 0x1d - /pet get lost +#define PET_GUARDME 30 // 0x1e - Same as /pet follow, but different message in older clients - define not from client class Mob; struct NPCType; diff --git a/zone/quest_parser_collection.cpp b/zone/quest_parser_collection.cpp index c0680b43f..d3bde0d5b 100644 --- a/zone/quest_parser_collection.cpp +++ b/zone/quest_parser_collection.cpp @@ -200,6 +200,9 @@ bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) } bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) { + if (itm == nullptr) + return false; + std::string item_script; if(itm->GetItem()->ScriptFileID != 0) { item_script = "script_"; @@ -350,6 +353,8 @@ int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, s int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers) { + // needs pointer validation check on 'item' argument + std::string item_script; if(item->GetItem()->ScriptFileID != 0) { item_script = "script_"; diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 3cc329ae8..dd15c925d 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -154,7 +154,7 @@ void QuestManager::echo(int colour, const char *str) { void QuestManager::say(const char *str) { QuestManagerCurrentQuestVars(); if (!owner) { - LogFile->write(EQEMuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file."); return; } else { @@ -170,7 +170,7 @@ void QuestManager::say(const char *str) { void QuestManager::say(const char *str, uint8 language) { QuestManagerCurrentQuestVars(); if (!owner) { - LogFile->write(EQEMuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file."); return; } else { @@ -548,7 +548,7 @@ void QuestManager::stopalltimers(Mob *mob) { void QuestManager::emote(const char *str) { QuestManagerCurrentQuestVars(); if (!owner) { - LogFile->write(EQEMuLog::Quest, "QuestManager::emote called with nullptr owner. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::emote called with nullptr owner. Probably syntax error in quest file."); return; } else { @@ -559,7 +559,7 @@ void QuestManager::emote(const char *str) { void QuestManager::shout(const char *str) { QuestManagerCurrentQuestVars(); if (!owner) { - LogFile->write(EQEMuLog::Quest, "QuestManager::shout called with nullptr owner. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::shout called with nullptr owner. Probably syntax error in quest file."); return; } else { @@ -570,7 +570,7 @@ void QuestManager::shout(const char *str) { void QuestManager::shout2(const char *str) { QuestManagerCurrentQuestVars(); if (!owner) { - LogFile->write(EQEMuLog::Quest, "QuestManager::shout2 called with nullptr owner. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::shout2 called with nullptr owner. Probably syntax error in quest file."); return; } else { @@ -589,7 +589,7 @@ void QuestManager::gmsay(const char *str, uint32 color, bool send_to_world, uint void QuestManager::depop(int npc_type) { QuestManagerCurrentQuestVars(); if (!owner || !owner->IsNPC()) { - LogFile->write(EQEMuLog::Quest, "QuestManager::depop called with nullptr owner or non-NPC owner. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::depop called with nullptr owner or non-NPC owner. Probably syntax error in quest file."); return; } else { @@ -619,7 +619,7 @@ void QuestManager::depop(int npc_type) { void QuestManager::depop_withtimer(int npc_type) { QuestManagerCurrentQuestVars(); if (!owner || !owner->IsNPC()) { - LogFile->write(EQEMuLog::Quest, "QuestManager::depop_withtimer called with nullptr owner or non-NPC owner. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::depop_withtimer called with nullptr owner or non-NPC owner. Probably syntax error in quest file."); return; } else { @@ -646,7 +646,7 @@ void QuestManager::depopall(int npc_type) { entity_list.DepopAll(npc_type); } else { - LogFile->write(EQEMuLog::Quest, "QuestManager::depopall called with nullptr owner, non-NPC owner, or invalid NPC Type ID. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::depopall called with nullptr owner, non-NPC owner, or invalid NPC Type ID. Probably syntax error in quest file."); } } @@ -655,7 +655,7 @@ void QuestManager::depopzone(bool StartSpawnTimer) { zone->Depop(StartSpawnTimer); } else { - LogFile->write(EQEMuLog::Quest, "QuestManager::depopzone called with nullptr zone. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::depopzone called with nullptr zone. Probably syntax error in quest file."); } } @@ -664,7 +664,7 @@ void QuestManager::repopzone() { zone->Repop(); } else { - LogFile->write(EQEMuLog::Quest, "QuestManager::repopzone called with nullptr zone. Probably syntax error in quest file."); + LogFile->write(EQEmuLog::Quest, "QuestManager::repopzone called with nullptr zone. Probably syntax error in quest file."); } } @@ -1227,13 +1227,17 @@ void QuestManager::settime(uint8 new_hour, uint8 new_min) { void QuestManager::itemlink(int item_id) { QuestManagerCurrentQuestVars(); if (initiator) { - const ItemInst* inst = database.CreateItem(item_id); - char* link = 0; - if (initiator->MakeItemLink(link, inst)) - initiator->Message(0, "%s tells you, %c%s%s%c", owner->GetCleanName(), - 0x12, link, inst->GetItem()->Name, 0x12); - safe_delete_array(link); - safe_delete(inst); + const Item_Struct* item = database.GetItem(item_id); + if (item == nullptr) + return; + + Client::TextLink linker; + linker.SetLinkType(linker.linkItemData); + linker.SetItemData(item); + + auto item_link = linker.GenerateLink(); + + initiator->Message(0, "%s tells you, %s", owner->GetCleanName(), item_link.c_str()); } } @@ -1642,7 +1646,7 @@ void QuestManager::showgrid(int grid) { "ORDER BY `number`", grid, zone->GetZoneID()); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Quest, "Error loading grid %d for showgrid(): %s", grid, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Quest, "Error loading grid %d for showgrid(): %s", grid, results.ErrorMessage().c_str()); return; } @@ -2098,11 +2102,12 @@ int QuestManager::gettaskactivitydonecount(int task, int activity) { } -void QuestManager::updatetaskactivity(int task, int activity, int count) { +void QuestManager::updatetaskactivity(int task, int activity, int count, bool ignore_quest_update /*= false*/) +{ QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) - initiator->UpdateTaskActivity(task, activity, count); + initiator->UpdateTaskActivity(task, activity, count, ignore_quest_update); } void QuestManager::resettaskactivity(int task, int activity) { @@ -2331,7 +2336,7 @@ int QuestManager::collectitems_processSlot(int16 slot_id, uint32 item_id, bool remove) { QuestManagerCurrentQuestVars(); - ItemInst *item; + ItemInst *item = nullptr; int quantity = 0; item = initiator->GetInv().GetItem(slot_id); @@ -2456,16 +2461,17 @@ uint32 QuestManager::MerchantCountItem(uint32 NPCid, uint32 itemid) { // Item Link for use in Variables - "my $example_link = quest::varlink(item_id);" const char* QuestManager::varlink(char* perltext, int item_id) { QuestManagerCurrentQuestVars(); - const ItemInst* inst = database.CreateItem(item_id); - if (!inst) + const Item_Struct* item = database.GetItem(item_id); + if (!item) return "INVALID ITEM ID IN VARLINK"; - char* link = 0; - char* tempstr = 0; - if (initiator->MakeItemLink(link, inst)) { // make a link to the item - snprintf(perltext, 250, "%c%s%s%c", 0x12, link, inst->GetItem()->Name, 0x12); - } - safe_delete_array(link); // MakeItemLink() uses new also - safe_delete(inst); + + Client::TextLink linker; + linker.SetLinkType(linker.linkItemData); + linker.SetItemData(item); + + auto item_link = linker.GenerateLink(); + strcpy(perltext, item_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink() + return perltext; } @@ -2630,7 +2636,7 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam std::string insert_query = StringFormat("INSERT INTO `saylink` (`phrase`) VALUES ('%s')", escaped_string); results = database.QueryDatabase(insert_query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str()); } else { results = database.QueryDatabase(query); if (results.Success()) { @@ -2638,7 +2644,7 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam for(auto row = results.begin(); row != results.end(); ++row) sayid = atoi(row[0]); } else { - LogFile->write(EQEMuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str()); } } } @@ -2651,24 +2657,14 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam sayid = sayid + 500000; //Create the say link as an item link hash - char linktext[250]; + Client::TextLink linker; + linker.SetProxyItemID(sayid); + linker.SetProxyText(LinkName); - if (initiator) { - if (initiator->GetClientVersion() >= EQClientRoF2) - sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000000000", LinkName, 0x12); - else if (initiator->GetClientVersion() >= EQClientRoF) - sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "0000000000000000000000000000000000000000000000000", LinkName, 0x12); - else if (initiator->GetClientVersion() >= EQClientSoF) - sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000", LinkName, 0x12); - else - sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "000000000000000000000000000000000000000", LinkName, 0x12); - } else { // If no initiator, create an RoF2 saylink, since older clients handle RoF2 ones better than RoF2 handles older ones. - sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000000000", LinkName, 0x12); - } + auto say_link = linker.GenerateLink(); + strcpy(Phrase, say_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink() - strcpy(Phrase,linktext); return Phrase; - } const char* QuestManager::getguildnamebyid(int guild_id) { @@ -2808,7 +2804,7 @@ void QuestManager::voicetell(const char *str, int macronum, int racenum, int gen safe_delete(outapp); } else - LogFile->write(EQEMuLog::Quest, "QuestManager::voicetell from %s. Client %s not found.", owner->GetName(), str); + LogFile->write(EQEmuLog::Quest, "QuestManager::voicetell from %s. Client %s not found.", owner->GetName(), str); } } diff --git a/zone/questmgr.h b/zone/questmgr.h index 63768f4df..522aef961 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -183,7 +183,7 @@ public: bool istaskactive(int task); bool istaskactivityactive(int task, int activity); int gettaskactivitydonecount(int task, int activity); - void updatetaskactivity(int task, int activity, int count); + void updatetaskactivity(int task, int activity, int count, bool ignore_quest_update = false); void resettaskactivity(int task, int activity); void taskexploredarea(int exploreid); void assigntask(int taskid); diff --git a/zone/raids.cpp b/zone/raids.cpp index 31d2b63c9..b01d169fd 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -99,7 +99,7 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error inserting into raid members: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error inserting into raid members: %s", results.ErrorMessage().c_str()); } LearnMembers(); @@ -233,12 +233,12 @@ void Raid::SetRaidLeader(const char *wasLead, const char *name) std::string query = StringFormat("UPDATE raid_members SET israidleader = 0 WHERE name = '%s'", wasLead); auto results = database.QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str()); query = StringFormat("UPDATE raid_members SET israidleader = 1 WHERE name = '%s'", name); results = database.QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str()); strn0cpy(leadername, name, 64); @@ -271,7 +271,7 @@ void Raid::SaveGroupLeaderAA(uint32 gid) 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()); } void Raid::SaveRaidLeaderAA() @@ -285,7 +285,7 @@ void Raid::SaveRaidLeaderAA() 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()); } void Raid::UpdateGroupAAs(uint32 gid) @@ -1407,7 +1407,7 @@ void Raid::GetRaidDetails() return; if (results.RowCount() == 0) { - LogFile->write(EQEMuLog::Error, "Error getting raid details for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error getting raid details for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str()); return; } @@ -1439,7 +1439,7 @@ bool Raid::LearnMembers() return false; if(results.RowCount() == 0) { - LogFile->write(EQEMuLog::Error, "Error getting raid members for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error getting raid members for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str()); disbandCheck = true; return false; } @@ -1643,7 +1643,7 @@ void Raid::SetGroupMentor(uint32 group_id, int percent, char *name) name, percent, group_id, GetID()); auto results = database.QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Unable to set raid group mentor: %s\n", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Unable to set raid group mentor: %s\n", results.ErrorMessage().c_str()); } void Raid::ClearGroupMentor(uint32 group_id) @@ -1658,7 +1658,7 @@ void Raid::ClearGroupMentor(uint32 group_id) group_id, GetID()); auto results = database.QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Unable to clear raid group mentor: %s\n", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Unable to clear raid group mentor: %s\n", results.ErrorMessage().c_str()); } // there isn't a nice place to add this in another function, unlike groups diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index a2be18813..6be939e35 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -364,7 +364,7 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList &spa zone_name, version); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in PopulateZoneLists query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -392,12 +392,12 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2 "WHERE id = %i", spawn2id); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return nullptr; } if (results.RowCount() != 1) { - LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return nullptr; } @@ -424,7 +424,7 @@ bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* z respawn, variance, condition, cond_value); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in CreateSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in CreateSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -674,7 +674,7 @@ void SpawnConditionManager::UpdateDBEvent(SpawnEvent &event) { event.strict? 1: 0, event.id); auto results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Unable to update spawn event '%s': %s\n", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Unable to update spawn event '%s': %s\n", query.c_str(), results.ErrorMessage().c_str()); } @@ -686,7 +686,7 @@ void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 inst cond_id, value, zone_name, instance_id); auto results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Unable to update spawn condition '%s': %s\n", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Unable to update spawn condition '%s': %s\n", query.c_str(), results.ErrorMessage().c_str()); } @@ -699,7 +699,7 @@ bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std: "FROM spawn_events WHERE id = %d", event_id); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadDBEvent query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadDBEvent query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -742,7 +742,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in "WHERE zone = '%s'", zone_name); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -764,7 +764,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in zone_name, instance_id); results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); spawn_conditions.clear(); return false; } @@ -782,7 +782,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in "FROM spawn_events WHERE zone = '%s'", zone_name); results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -794,7 +794,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in event.period = atoi(row[2]); if(event.period == 0) { - LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id); + LogFile->write(EQEmuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id); continue; } diff --git a/zone/spawngroup.cpp b/zone/spawngroup.cpp index 487e66a6d..bb9cb8abf 100644 --- a/zone/spawngroup.cpp +++ b/zone/spawngroup.cpp @@ -51,7 +51,7 @@ SpawnGroup::SpawnGroup( uint32 in_id, char* name, int in_group_spawn_limit, floa uint32 SpawnGroup::GetNPCType() { #if EQDEBUG >= 10 - LogFile->write(EQEMuLog::Debug, "SpawnGroup[%08x]::GetNPCType()", (uint32) this); + LogFile->write(EQEmuLog::Debug, "SpawnGroup[%08x]::GetNPCType()", (uint32) this); #endif int npcType = 0; int totalchance = 0; diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index f74949a0b..94da26e45 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -106,7 +106,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, if(who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE) || who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE)) return; //-5? - int32 hate = max_damage; + uint32 hate = max_damage; if(hate_override > -1) hate = hate_override; @@ -583,7 +583,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) int32 ndamage = 0; int32 max_hit = 0; int32 min_hit = 0; - int32 hate = 0; + uint32 hate = 0; int32 primaryweapondamage = 0; int32 backstab_dmg = 0; @@ -889,7 +889,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite if (HeadShot_Dmg) HeadShot = true; - int32 hate = 0; + uint32 hate = 0; int32 TotalDmg = 0; int16 WDmg = 0; int16 ADmg = 0; @@ -2354,7 +2354,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse = SkillOffense; int damage = 0; - int32 hate = 0; + uint32 hate = 0; int Hand = MainPrimary; if (hate == 0 && weapon_damage > 1) hate = weapon_damage; diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 56611024b..70a7d3981 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -475,7 +475,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if(!target_zone) { #ifdef SPELL_EFFECT_SPAM - LogFile->write(EQEMuLog::Debug, "Succor/Evacuation Spell In Same Zone."); + LogFile->write(EQEmuLog::Debug, "Succor/Evacuation Spell In Same Zone."); #endif if(IsClient()) CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords); @@ -484,7 +484,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) } else { #ifdef SPELL_EFFECT_SPAM - LogFile->write(EQEMuLog::Debug, "Succor/Evacuation Spell To Another Zone."); + LogFile->write(EQEmuLog::Debug, "Succor/Evacuation Spell To Another Zone."); #endif if(IsClient()) CastToClient()->MovePC(target_zone, x, y, z, heading); @@ -1771,7 +1771,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) } else { Message_StringID(4, TARGET_NOT_FOUND); - LogFile->write(EQEMuLog::Error, "%s attempted to cast spell id %u with spell effect SE_SummonCorpse, but could not cast target into a Client object.", GetCleanName(), spell_id); + LogFile->write(EQEmuLog::Error, "%s attempted to cast spell id %u with spell effect SE_SummonCorpse, but could not cast target into a Client object.", GetCleanName(), spell_id); } } @@ -1897,10 +1897,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if (CalculatePoisonCounters(buffs[j].spellid) == 0) continue; if (effect_value >= static_cast(buffs[j].counters)) { - if (caster) + if (caster) { caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); caster->CastOnCurer(buffs[j].spellid); CastOnCure(buffs[j].spellid); + } effect_value -= buffs[j].counters; buffs[j].counters = 0; BuffFadeBySlot(j); @@ -1930,10 +1931,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) continue; if (effect_value >= static_cast(buffs[j].counters)) { - if (caster) + if (caster) { caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); caster->CastOnCurer(buffs[j].spellid); CastOnCure(buffs[j].spellid); + } effect_value -= buffs[j].counters; buffs[j].counters = 0; BuffFadeBySlot(j); @@ -1965,10 +1967,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) continue; if (effect_value >= static_cast(buffs[j].counters)) { - if (caster) + if (caster) { caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); caster->CastOnCurer(buffs[j].spellid); CastOnCure(buffs[j].spellid); + } effect_value -= buffs[j].counters; buffs[j].counters = 0; BuffFadeBySlot(j); @@ -1999,10 +2002,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if (CalculateCorruptionCounters(buffs[j].spellid) == 0) continue; if (effect_value >= static_cast(buffs[j].counters)) { - if (caster) + if (caster) { caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); caster->CastOnCurer(buffs[j].spellid); CastOnCure(buffs[j].spellid); + } effect_value -= buffs[j].counters; buffs[j].counters = 0; BuffFadeBySlot(j); @@ -2658,7 +2662,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) caster->Taunt(this->CastToNPC(), false, static_cast(spell.base[i])); if (spell.base2[i] > 0) - CastToNPC()->SetHate(caster, (CastToNPC()->GetHateAmount(caster) + spell.base2[i])); + CastToNPC()->SetHateAmountOnEnt(caster, (CastToNPC()->GetHateAmount(caster) + spell.base2[i])); } break; } @@ -2689,7 +2693,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if (new_hate <= 0) new_hate = 1; - CastToNPC()->SetHate(caster, new_hate); + CastToNPC()->SetHateAmountOnEnt(caster, new_hate); } break; } @@ -2710,9 +2714,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) }else{ int32 newhate = GetHateAmount(caster) + effect_value; if (newhate < 1) - SetHate(caster,1); + SetHateAmountOnEnt(caster,1); else - SetHate(caster,newhate); + SetHateAmountOnEnt(caster,newhate); } } break; @@ -3321,7 +3325,7 @@ snare has both of them negative, yet their range should work the same: result = ubase * (caster_level * (formula - 2000) + 1); } else - LogFile->write(EQEMuLog::Debug, "Unknown spell effect value forumula %d", formula); + LogFile->write(EQEmuLog::Debug, "Unknown spell effect value forumula %d", formula); } } @@ -3542,9 +3546,9 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste }else{ int32 newhate = GetHateAmount(caster) + effect_value; if (newhate < 1) { - SetHate(caster,1); + SetHateAmountOnEnt(caster,1); } else { - SetHate(caster,newhate); + SetHateAmountOnEnt(caster,newhate); } } } @@ -3724,11 +3728,11 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste case SE_AddHateOverTimePct: { if (IsNPC()){ - int32 new_hate = CastToNPC()->GetHateAmount(caster) * (100 + spell.base[i]) / 100; + uint32 new_hate = CastToNPC()->GetHateAmount(caster) * (100 + spell.base[i]) / 100; if (new_hate <= 0) new_hate = 1; - CastToNPC()->SetHate(caster, new_hate); + CastToNPC()->SetHateAmountOnEnt(caster, new_hate); } break; } @@ -4812,7 +4816,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo 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; @@ -5151,7 +5155,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo //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 } @@ -6420,7 +6424,7 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama //Limit to amount of pets if (value >= 221 && value <= 249){ - int count = hate_list.SummonedPetCount(this); + int count = hate_list.GetSummonedPetCountOnHateList(this); for (int base2_value = 221; base2_value <= 249; ++base2_value){ if (value == base2_value){ diff --git a/zone/spells.cpp b/zone/spells.cpp index 68b26450b..ee89a03e4 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -257,7 +257,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, if ((itm->GetItem()->Click.Type == ET_EquipClick) && !(itm->GetItem()->Classes & bitmask)) { if (CastToClient()->GetClientVersion() < EQClientSoF) { // They are casting a spell from an item that requires equipping but shouldn't let them equip it - LogFile->write(EQEMuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) which they shouldn't be able to equip!", + LogFile->write(EQEmuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) which they shouldn't be able to equip!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID); database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item with an invalid class"); } @@ -269,12 +269,20 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, if ((itm->GetItem()->Click.Type == ET_ClickEffect2) && !(itm->GetItem()->Classes & bitmask)) { if (CastToClient()->GetClientVersion() < EQClientSoF) { // They are casting a spell from an item that they don't meet the race/class requirements to cast - LogFile->write(EQEMuLog::Error, "HACKER: %s (account: %s) attempted to click a race/class restricted effect on item %s (id: %d) which they shouldn't be able to click!", + LogFile->write(EQEmuLog::Error, "HACKER: %s (account: %s) attempted to click a race/class restricted effect on item %s (id: %d) which they shouldn't be able to click!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID); database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking race/class restricted item with an invalid class"); } else { - Message_StringID(13, CANNOT_USE_ITEM); + if (CastToClient()->GetClientVersion() >= EQClientRoF) + { + // Line 181 in eqstr_us.txt was changed in RoF+ + Message(15, "Your race, class, or deity cannot use this item."); + } + else + { + Message_StringID(13, CANNOT_USE_ITEM); + } } return(false); } @@ -282,7 +290,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, if( itm && (itm->GetItem()->Click.Type == ET_EquipClick) && !(item_slot <= MainAmmo || item_slot == MainPowerSource) ){ if (CastToClient()->GetClientVersion() < EQClientSoF) { // They are attempting to cast a must equip clicky without having it equipped - LogFile->write(EQEMuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID); + LogFile->write(EQEmuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID); database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item without equiping it"); } else { @@ -1195,22 +1203,29 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, uint32 recastdelay = 0; uint32 recasttype = 0; - for (int r = 0; r < EmuConstants::ITEM_COMMON_SIZE; r++) { - const ItemInst* aug_i = inst->GetAugment(r); - - if(!aug_i) - continue; - const Item_Struct* aug = aug_i->GetItem(); - if(!aug) - continue; - - if ( aug->Click.Effect == spell_id ) - { - recastdelay = aug_i->GetItem()->RecastDelay; - recasttype = aug_i->GetItem()->RecastType; - fromaug = true; + while (true) { + if (inst == nullptr) break; + + for (int r = AUG_BEGIN; r < EmuConstants::ITEM_COMMON_SIZE; r++) { + const ItemInst* aug_i = inst->GetAugment(r); + + if (!aug_i) + continue; + const Item_Struct* aug = aug_i->GetItem(); + if (!aug) + continue; + + if (aug->Click.Effect == spell_id) + { + recastdelay = aug_i->GetItem()->RecastDelay; + recasttype = aug_i->GetItem()->RecastType; + fromaug = true; + break; + } } + + break; } //Test the aug recast delay @@ -2657,7 +2672,7 @@ int CalcBuffDuration_formula(int level, int formula, int duration) return duration ? duration : 3600; default: - LogFile->write(EQEMuLog::Debug, "CalcBuffDuration_formula: unknown formula %d", formula); + LogFile->write(EQEmuLog::Debug, "CalcBuffDuration_formula: unknown formula %d", formula); return 0; } } @@ -3649,11 +3664,11 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r spelltar->AddToHateList(this, aggro); } else{ - int32 newhate = spelltar->GetHateAmount(this) + aggro; + uint32 newhate = spelltar->GetHateAmount(this) + aggro; if (newhate < 1) { - spelltar->SetHate(this,1); + spelltar->SetHateAmountOnEnt(this,1); } else { - spelltar->SetHate(this,newhate); + spelltar->SetHateAmountOnEnt(this,newhate); } } } @@ -3681,9 +3696,9 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r spelltar->AddToHateList(this, aggro_amount); else{ int32 newhate = spelltar->GetHateAmount(this) + aggro_amount; if (newhate < 1) { - spelltar->SetHate(this,1); + spelltar->SetHateAmountOnEnt(this,1); } else { - spelltar->SetHate(this,newhate); + spelltar->SetHateAmountOnEnt(this,newhate); } } } @@ -3896,6 +3911,8 @@ void Mob::BuffFadeDetrimental() { BuffFadeBySlot(j, false); } } + //we tell BuffFadeBySlot not to recalc, so we can do it only once when were done + CalcBonuses(); } void Mob::BuffFadeDetrimentalByCaster(Mob *caster) @@ -3916,6 +3933,8 @@ void Mob::BuffFadeDetrimentalByCaster(Mob *caster) } } } + //we tell BuffFadeBySlot not to recalc, so we can do it only once when were done + CalcBonuses(); } void Mob::BuffFadeBySitModifier() @@ -4195,6 +4214,10 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use //Get resist modifier and adjust it based on focus 2 resist about eq to 1% resist chance int resist_modifier = (use_resist_override) ? resist_override : spells[spell_id].ResistDiff; + + if(caster->GetSpecialAbility(CASTING_RESIST_DIFF)) + resist_modifier += caster->GetSpecialAbilityParam(CASTING_RESIST_DIFF, 0); + int focus_resist = caster->GetFocusEffect(focusResistRate, spell_id); resist_modifier -= 2 * focus_resist; @@ -4939,7 +4962,7 @@ bool Client::SpellGlobalCheck(uint16 spell_ID, uint32 char_ID) { "WHERE spellid = %i", spell_ID); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", spell_ID, query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", spell_ID, query.c_str(), results.ErrorMessage().c_str()); return false; // Query failed, so prevent spell from scribing just in case } @@ -4958,12 +4981,12 @@ bool Client::SpellGlobalCheck(uint16 spell_ID, uint32 char_ID) { char_ID, spell_Global_Name.c_str()); results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_ID, spell_Global_Name.c_str(), spell_Global_Value); + LogFile->write(EQEmuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_ID, spell_Global_Name.c_str(), spell_Global_Value); return false; } if (results.RowCount() != 1) { - LogFile->write(EQEMuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_ID); + LogFile->write(EQEmuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_ID); return false; } @@ -4977,7 +5000,7 @@ bool Client::SpellGlobalCheck(uint16 spell_ID, uint32 char_ID) { return true; // Check if the qglobal value is greater than the require spellglobal value // If no matching result found in qglobals, don't scribe this spell - LogFile->write(EQEMuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_Global_Value, global_Value, spell_ID); + LogFile->write(EQEmuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_Global_Value, global_Value, spell_ID); return false; } @@ -5016,7 +5039,7 @@ bool Mob::FindType(uint16 type, bool bOffensive, uint16 threshold) { spells[buffs[i].spellid].base[j], spells[buffs[i].spellid].max[j], buffs[i].casterlevel, buffs[i].spellid); - LogFile->write(EQEMuLog::Normal, + LogFile->write(EQEmuLog::Normal, "FindType: type = %d; value = %d; threshold = %d", type, value, threshold); if (value < threshold) diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 1e73e3150..d6f285de6 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -74,7 +74,7 @@ bool TaskManager::LoadTaskSets() { MAXTASKSETS, MAXTASKS); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadTaskSets: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadTaskSets: %s", results.ErrorMessage().c_str()); return false; } @@ -146,7 +146,7 @@ bool TaskManager::LoadTasks(int singleTask) { auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); return false; } @@ -155,7 +155,7 @@ bool TaskManager::LoadTasks(int singleTask) { if((taskID <= 0) || (taskID >= MAXTASKS)) { // This shouldn't happen, as the SELECT is bounded by MAXTASKS - LogFile->write(EQEMuLog::Error, "[TASKS]Task ID %i out of range while loading tasks from database", taskID); + LogFile->write(EQEmuLog::Error, "[TASKS]Task ID %i out of range while loading tasks from database", taskID); continue; } @@ -203,7 +203,7 @@ bool TaskManager::LoadTasks(int singleTask) { "ORDER BY taskid, activityid ASC", singleTask, MAXACTIVITIESPERTASK); results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); return false; } @@ -215,13 +215,13 @@ bool TaskManager::LoadTasks(int singleTask) { if((taskID <= 0) || (taskID >= MAXTASKS) || (activityID < 0) || (activityID >= MAXACTIVITIESPERTASK)) { // This shouldn't happen, as the SELECT is bounded by MAXTASKS - LogFile->write(EQEMuLog::Error, "[TASKS]Task or Activity ID (%i, %i) out of range while loading " + LogFile->write(EQEmuLog::Error, "[TASKS]Task or Activity ID (%i, %i) out of range while loading " "activities from database", taskID, activityID); continue; } if(Tasks[taskID]==nullptr) { - LogFile->write(EQEMuLog::Error, "[TASKS]Activity for non-existent task (%i, %i) while loading activities from database", taskID, activityID); + LogFile->write(EQEmuLog::Error, "[TASKS]Activity for non-existent task (%i, %i) while loading activities from database", taskID, activityID); continue; } @@ -238,7 +238,7 @@ bool TaskManager::LoadTasks(int singleTask) { // ERR_NOTASK errors. // Change to (activityID != (Tasks[taskID]->ActivityCount + 1)) to index from 1 if(activityID != Tasks[taskID]->ActivityCount) { - LogFile->write(EQEMuLog::Error, "[TASKS]Activities for Task %i are not sequential starting at 0. Not loading task.", taskID, activityID); + LogFile->write(EQEmuLog::Error, "[TASKS]Activities for Task %i are not sequential starting at 0. Not loading task.", taskID, activityID); Tasks[taskID] = nullptr; continue; } @@ -323,7 +323,7 @@ bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) { characterID, taskID, task, state->ActiveTasks[task].AcceptedTime); auto results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); else state->ActiveTasks[task].Updated = false; @@ -362,7 +362,7 @@ bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) { auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); continue; } @@ -396,7 +396,7 @@ bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) { std::string query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, -1); auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); continue; } @@ -413,7 +413,7 @@ bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) { query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, j); results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str()); } @@ -466,7 +466,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { "WHERE `charid` = %i ORDER BY acceptedtime", characterID); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load Tasks: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load Tasks: %s", results.ErrorMessage().c_str()); return false; } @@ -475,17 +475,17 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { int slot = atoi(row[1]); if((taskID<0) || (taskID>=MAXTASKS)) { - LogFile->write(EQEMuLog::Error, "[TASKS]Task ID %i out of range while loading character tasks from database", taskID); + LogFile->write(EQEmuLog::Error, "[TASKS]Task ID %i out of range while loading character tasks from database", taskID); continue; } if((slot<0) || (slot>=MAXACTIVETASKS)) { - LogFile->write(EQEMuLog::Error, "[TASKS] Slot %i out of range while loading character tasks from database", slot); + LogFile->write(EQEmuLog::Error, "[TASKS] Slot %i out of range while loading character tasks from database", slot); continue; } if(state->ActiveTasks[slot].TaskID != TASKSLOTEMPTY) { - LogFile->write(EQEMuLog::Error, "[TASKS] Slot %i for Task %is is already occupied.", slot, taskID); + LogFile->write(EQEmuLog::Error, "[TASKS] Slot %i for Task %is is already occupied.", slot, taskID); continue; } @@ -513,20 +513,20 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { "ORDER BY `taskid` ASC, `activityid` ASC", characterID); results = database.QueryDatabase(query); if (!results.Success()){ - LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load Activities: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load Activities: %s", results.ErrorMessage().c_str()); return false; } for (auto row = results.begin(); row != results.end(); ++row) { int taskID = atoi(row[0]); if((taskID<0) || (taskID>=MAXTASKS)) { - LogFile->write(EQEMuLog::Error, "[TASKS]Task ID %i out of range while loading character activities from database", taskID); + LogFile->write(EQEmuLog::Error, "[TASKS]Task ID %i out of range while loading character activities from database", taskID); continue; } int activityID = atoi(row[1]); if((activityID<0) || (activityID>=MAXACTIVITIESPERTASK)) { - LogFile->write(EQEMuLog::Error, "[TASKS]Activity ID %i out of range while loading character activities from database", activityID); + LogFile->write(EQEmuLog::Error, "[TASKS]Activity ID %i out of range while loading character activities from database", activityID); continue; } @@ -540,7 +540,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { } if(activeTaskIndex == -1) { - LogFile->write(EQEMuLog::Error, "[TASKS]Activity %i found for task %i which client does not have.", activityID, taskID); + LogFile->write(EQEmuLog::Error, "[TASKS]Activity %i found for task %i which client does not have.", activityID, taskID); continue; } @@ -566,7 +566,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { characterID); results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load completed tasks: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load completed tasks: %s", results.ErrorMessage().c_str()); return false; } @@ -582,7 +582,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { int taskID = atoi(row[0]); if((taskID <= 0) || (taskID >=MAXTASKS)) { - LogFile->write(EQEMuLog::Error, "[TASKS]Task ID %i out of range while loading completed tasks from database", taskID); + LogFile->write(EQEmuLog::Error, "[TASKS]Task ID %i out of range while loading completed tasks from database", taskID); continue; } @@ -592,7 +592,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { // completed. int activityID = atoi(row[1]); if((activityID<-1) || (activityID>=MAXACTIVITIESPERTASK)) { - LogFile->write(EQEMuLog::Error, "[TASKS]Activity ID %i out of range while loading completed tasks from database", activityID); + LogFile->write(EQEmuLog::Error, "[TASKS]Activity ID %i out of range while loading completed tasks from database", activityID); continue; } @@ -634,7 +634,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { characterID, MAXTASKS); results = database.QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load enabled tasks: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load enabled tasks: %s", results.ErrorMessage().c_str()); else for (auto row = results.begin(); row != results.end(); ++row) { int taskID = atoi(row[0]); @@ -652,7 +652,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { c->Message(13, "Active Task Slot %i, references a task (%i), that does not exist. " "Removing from memory. Contact a GM to resolve this.",i, taskID); - LogFile->write(EQEMuLog::Error, "[TASKS]Character %i has task %i which does not exist.", characterID, taskID); + LogFile->write(EQEmuLog::Error, "[TASKS]Character %i has task %i which does not exist.", characterID, taskID); state->ActiveTasks[i].TaskID=TASKSLOTEMPTY; continue; @@ -664,7 +664,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) { "Removing from memory. Contact a GM to resolve this.", taskID, Tasks[taskID]->Title); - LogFile->write(EQEMuLog::Error, "[TASKS]Fatal error in character %i task state. Activity %i for " + LogFile->write(EQEmuLog::Error, "[TASKS]Fatal error in character %i task state. Activity %i for " "Task %i either missing from client state or from task.", characterID, j, taskID); state->ActiveTasks[i].TaskID=TASKSLOTEMPTY; break; @@ -725,7 +725,7 @@ void ClientTaskState::EnableTask(int characterID, int taskCount, int *tasks) { _log(TASKS__UPDATE, "Executing query %s", query.c_str()); auto results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "[TASKS]Error in ClientTaskState::EnableTask %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in ClientTaskState::EnableTask %s %s", query.c_str(), results.ErrorMessage().c_str()); } @@ -774,7 +774,7 @@ void ClientTaskState::DisableTask(int charID, int taskCount, int *taskList) { _log(TASKS__UPDATE, "Executing query %s", query.c_str()); auto results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "[TASKS]Error in ClientTaskState::DisableTask %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in ClientTaskState::DisableTask %s %s", query.c_str(), results.ErrorMessage().c_str()); } bool ClientTaskState::IsTaskEnabled(int TaskID) { @@ -1280,7 +1280,7 @@ static void DeleteCompletedTaskFromDatabase(int charID, int taskID) { const std::string query = StringFormat("DELETE FROM completed_tasks WHERE charid=%i AND taskid = %i", charID, taskID); auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s, %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s, %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -1786,7 +1786,7 @@ void ClientTaskState::UpdateTasksOnTouch(Client *c, int ZoneID) { return; } -void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int TaskIndex, int ActivityID, int Count) { +void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int TaskIndex, int ActivityID, int Count, bool ignore_quest_update) { _log(TASKS__UPDATE, "IncrementDoneCount"); @@ -1795,10 +1795,12 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T if(ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount > Task->Activity[ActivityID].GoalCount) ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount = Task->Activity[ActivityID].GoalCount; - char buf[24]; - snprintf(buf, 23, "%d %d %d", ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].TaskID); - buf[23] = '\0'; - parse->EventPlayer(EVENT_TASK_UPDATE, c, buf, 0); + if (!ignore_quest_update){ + char buf[24]; + snprintf(buf, 23, "%d %d %d", ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].TaskID); + buf[23] = '\0'; + parse->EventPlayer(EVENT_TASK_UPDATE, c, buf, 0); + } ActiveTasks[TaskIndex].Activity[ActivityID].Updated=true; // Have we reached the goal count for this activity ? @@ -1821,11 +1823,12 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T c->Message(0, "Your task '%s' has been updated.", Task->Title); if(Task->Activity[ActivityID].GoalMethod != METHODQUEST) { - char buf[24]; - snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID); - buf[23] = '\0'; - parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0); - + if (!ignore_quest_update){ + char buf[24]; + snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID); + buf[23] = '\0'; + parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0); + } /* QS: PlayerLogTaskUpdates :: Update */ if (RuleB(QueryServ, PlayerLogTaskUpdates)){ std::string event_desc = StringFormat("Task Stage Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID()); @@ -2039,7 +2042,8 @@ bool ClientTaskState::IsTaskActivityActive(int TaskID, int ActivityID) { } -void ClientTaskState::UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count) { +void ClientTaskState::UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count, bool ignore_quest_update /*= false*/) +{ _log(TASKS__UPDATE, "ClientTaskState UpdateTaskActivity(%i, %i, %i).", TaskID, ActivityID, Count); @@ -2048,8 +2052,8 @@ void ClientTaskState::UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int ActiveTaskIndex = -1; - for(int i=0; i=MAXTASKS) || !Tasks[TaskID]) return; +void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceNumber, int StartTime, int Duration, bool BringUpTaskJournal) +{ + if ((TaskID < 1) || (TaskID >= MAXTASKS) || !Tasks[TaskID]) + return; int PacketLength = sizeof(TaskDescriptionHeader_Struct) + strlen(Tasks[TaskID]->Title) + 1 + sizeof(TaskDescriptionData1_Struct) + strlen(Tasks[TaskID]->Description) + 1 + sizeof(TaskDescriptionData2_Struct) + 1 + sizeof(TaskDescriptionTrailer_Struct); std::string RewardText; - int ItemID = 0; + int ItemID = NOT_USED; // If there is an item make the Reward text into a link to the item (only the first item if a list // is specified). I have been unable to get multiple item links to work. @@ -2768,62 +2772,19 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN if(ItemID < 0) ItemID = 0; } + if(ItemID) { - char *RewardTmp = 0; - if(strlen(Tasks[TaskID]->Reward) != 0) { + const Item_Struct* reward_item = database.GetItem(ItemID); - switch(c->GetClientVersion()) { - case EQClientTitanium: - { - MakeAnyLenString(&RewardTmp, "%c%06X000000000000000000000000000000014505DC2%s%c", - 0x12, ItemID, Tasks[TaskID]->Reward,0x12); - break; - } - case EQClientRoF: - { - MakeAnyLenString(&RewardTmp, "%c%06X0000000000000000000000000000000000000000014505DC2%s%c", - 0x12, ItemID, Tasks[TaskID]->Reward,0x12); - break; - } - default: - { - // All clients after Titanium - MakeAnyLenString(&RewardTmp, "%c%06X00000000000000000000000000000000000014505DC2%s%c", - 0x12, ItemID, Tasks[TaskID]->Reward,0x12); - } - } + Client::TextLink linker; + linker.SetLinkType(linker.linkItemData); + linker.SetItemData(reward_item); + linker.SetTaskUse(); + if (strlen(Tasks[TaskID]->Reward) != 0) + linker.SetProxyText(Tasks[TaskID]->Reward); - } - else { - const Item_Struct *Item = database.GetItem(ItemID); - - if(Item) { - - switch(c->GetClientVersion()) { - case EQClientTitanium: - { - MakeAnyLenString(&RewardTmp, "%c%06X000000000000000000000000000000014505DC2%s%c", - 0x12, ItemID, Item->Name ,0x12); - break; - } - case EQClientRoF: - { - MakeAnyLenString(&RewardTmp, "%c%06X0000000000000000000000000000000000000000014505DC2%s%c", - 0x12, ItemID, Item->Name ,0x12); - break; - } - default: - { - // All clients after Titanium - MakeAnyLenString(&RewardTmp, "%c%06X00000000000000000000000000000000000014505DC2%s%c", - 0x12, ItemID, Item->Name ,0x12); - } - } - } - } - - if(RewardTmp) RewardText += RewardTmp; - safe_delete_array(RewardTmp); + auto reward_link = linker.GenerateLink(); + RewardText += reward_link.c_str(); } else { RewardText += Tasks[TaskID]->Reward; @@ -2977,7 +2938,7 @@ void ClientTaskState::RemoveTask(Client *c, int sequenceNumber) { characterID, ActiveTasks[sequenceNumber].TaskID); auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str()); return; } _log(TASKS__UPDATE, "CancelTask: %s", query.c_str()); @@ -2986,7 +2947,7 @@ void ClientTaskState::RemoveTask(Client *c, int sequenceNumber) { characterID, ActiveTasks[sequenceNumber].TaskID); results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str()); _log(TASKS__UPDATE, "CancelTask: %s", query.c_str()); @@ -3127,7 +3088,7 @@ bool TaskGoalListManager::LoadLists() { "ORDER BY `listid`"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -3161,7 +3122,7 @@ bool TaskGoalListManager::LoadLists() { listID, size); results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, query.c_str(), results.ErrorMessage().c_str()); TaskGoalLists[listIndex].Size = 0; continue; } @@ -3298,7 +3259,7 @@ bool TaskProximityManager::LoadProximities(int zoneID) { "ORDER BY `zoneid` ASC", zoneID); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in TaskProximityManager::LoadProximities %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in TaskProximityManager::LoadProximities %s %s", query.c_str(), results.ErrorMessage().c_str()); return false; } diff --git a/zone/tasks.h b/zone/tasks.h index 6298fcb5c..c525bbcd8 100644 --- a/zone/tasks.h +++ b/zone/tasks.h @@ -175,7 +175,7 @@ public: bool IsTaskActive(int TaskID); bool IsTaskActivityActive(int TaskID, int ActivityID); ActivityState GetTaskActivityState(int index, int ActivityID); - void UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count); + void UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count, bool ignore_quest_update = false); void ResetTaskActivity(Client *c, int TaskID, int ActivityID); void CancelTask(Client *c, int SequenceNumber, bool RemoveFromDB = true); void CancelAllTasks(Client *c); @@ -204,7 +204,7 @@ public: private: bool UnlockActivities(int CharID, int TaskIndex); - void IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count=1); + void IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count = 1, bool ignore_quest_update = false); int ActiveTaskCount; ClientTaskInformation ActiveTasks[MAXACTIVETASKS]; std::vectorEnabledTasks; diff --git a/zone/titles.cpp b/zone/titles.cpp index a9e8454f1..109a793b3 100644 --- a/zone/titles.cpp +++ b/zone/titles.cpp @@ -40,7 +40,7 @@ bool TitleManager::LoadTitles() "`status`, `item_id`, `prefix`, `suffix`, `title_set` FROM titles"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Unable to load titles: %s : %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Unable to load titles: %s : %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -263,7 +263,7 @@ void TitleManager::CreateNewPlayerTitle(Client *client, const char *title) safe_delete_array(escTitle); results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error adding title: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error adding title: %s %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -296,7 +296,7 @@ void TitleManager::CreateNewPlayerSuffix(Client *client, const char *suffix) safe_delete_array(escSuffix); results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error adding title suffix: %s %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error adding title suffix: %s %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -351,7 +351,7 @@ void Client::EnableTitle(int titleSet) { CharacterID(), titleSet); auto results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in EnableTitle query for titleset %i and charid %i", titleSet, CharacterID()); + LogFile->write(EQEmuLog::Error, "Error in EnableTitle query for titleset %i and charid %i", titleSet, CharacterID()); } @@ -362,7 +362,7 @@ bool Client::CheckTitle(int titleSet) { titleSet, CharacterID()); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in CheckTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in CheckTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -382,7 +382,7 @@ void Client::RemoveTitle(int titleSet) { titleSet, CharacterID()); auto results = database.QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in RemoveTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in RemoveTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); } diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index f6112b560..e1cbbafc3 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -42,7 +42,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme { if (!user || !in_augment) { - LogFile->write(EQEMuLog::Error, "Client or AugmentItem_Struct not set in Object::HandleAugmentation"); + LogFile->write(EQEmuLog::Error, "Client or AugmentItem_Struct not set in Object::HandleAugmentation"); return; } @@ -89,12 +89,12 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme if(!container) { - LogFile->write(EQEMuLog::Error, "Player tried to augment an item without a container set."); + LogFile->write(EQEmuLog::Error, "Player tried to augment an item without a container set."); user->Message(13, "Error: This item is not a container!"); return; } - ItemInst *tobe_auged, *auged_with = nullptr; + ItemInst *tobe_auged = nullptr, *auged_with = nullptr; int8 slot=-1; // Verify 2 items in the augmentation device @@ -243,7 +243,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Object *worldo) { if (!user || !in_combine) { - LogFile->write(EQEMuLog::Error, "Client or NewCombine_Struct not set in Object::HandleCombine"); + LogFile->write(EQEmuLog::Error, "Client or NewCombine_Struct not set in Object::HandleCombine"); return; } @@ -418,7 +418,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob if(success && spec.replace_container) { if(worldcontainer){ //should report this error, but we dont have the recipe ID, so its not very useful - LogFile->write(EQEMuLog::Error, "Replace container combine executed in a world container."); + LogFile->write(EQEmuLog::Error, "Replace container combine executed in a world container."); } else user->DeleteItemInInventory(in_combine->container_slot, 0, true); @@ -444,7 +444,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac //ask the database for the recipe to make sure it exists... DBTradeskillRecipe_Struct spec; if (!database.GetTradeRecipe(rac->recipe_id, rac->object_type, rac->some_id, user->CharacterID(), &spec)) { - LogFile->write(EQEMuLog::Error, "Unknown recipe for HandleAutoCombine: %u\n", rac->recipe_id); + LogFile->write(EQEmuLog::Error, "Unknown recipe for HandleAutoCombine: %u\n", rac->recipe_id); user->QueuePacket(outapp); safe_delete(outapp); return; @@ -467,21 +467,21 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac rac->recipe_id); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in HandleAutoCombine query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); user->QueuePacket(outapp); safe_delete(outapp); return; } if(results.RowCount() < 1) { - LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine: no components returned"); + LogFile->write(EQEmuLog::Error, "Error in HandleAutoCombine: no components returned"); user->QueuePacket(outapp); safe_delete(outapp); return; } if(results.RowCount() > 10) { - LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine: too many components returned (%u)", results.RowCount()); + LogFile->write(EQEmuLog::Error, "Error in HandleAutoCombine: too many components returned (%u)", results.RowCount()); user->QueuePacket(outapp); safe_delete(outapp); return; @@ -676,7 +676,7 @@ void Client::TradeskillSearchResults(const std::string query, unsigned long objt auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in TradeskillSearchResults query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in TradeskillSearchResults query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -684,7 +684,7 @@ void Client::TradeskillSearchResults(const std::string query, unsigned long objt return; //search gave no results... not an error if(results.ColumnCount() != 6) { - LogFile->write(EQEMuLog::Error, "Error in TradeskillSearchResults query '%s': Invalid column count in result", query.c_str()); + LogFile->write(EQEmuLog::Error, "Error in TradeskillSearchResults query '%s': Invalid column count in result", query.c_str()); return; } @@ -730,17 +730,17 @@ void Client::SendTradeskillDetails(uint32 recipe_id) { recipe_id); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in SendTradeskillDetails query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } if(results.RowCount() < 1) { - LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails: no components returned"); + LogFile->write(EQEmuLog::Error, "Error in SendTradeskillDetails: no components returned"); return; } if(results.RowCount() > 10) { - LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails: too many components returned (%u)", results.RowCount()); + LogFile->write(EQEmuLog::Error, "Error in SendTradeskillDetails: too many components returned (%u)", results.RowCount()); return; } @@ -1185,6 +1185,8 @@ void Client::CheckIncreaseTradeskill(int16 bonusstat, int16 stat_modifier, float bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint32 some_id, uint32 char_id, DBTradeskillRecipe_Struct *spec) { + if (container == nullptr) + return false; std::string containers;// make where clause segment for container(s) if (some_id == 0) @@ -1230,8 +1232,8 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3 buf2.c_str(), containers.c_str(), count, sum); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe search, query: %s", query.c_str()); - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe search, error: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe search, query: %s", query.c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe search, error: %s", results.ErrorMessage().c_str()); return false; } @@ -1252,7 +1254,7 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3 //length limit on buf2 if(index == 214) { //Maximum number of recipe matches (19 * 215 = 4096) - LogFile->write(EQEMuLog::Error, "GetTradeRecipe warning: Too many matches. Unable to search all recipe entries. Searched %u of %u possible entries.", index + 1, results.RowCount()); + LogFile->write(EQEmuLog::Error, "GetTradeRecipe warning: Too many matches. Unable to search all recipe entries. Searched %u of %u possible entries.", index + 1, results.RowCount()); break; } } @@ -1264,8 +1266,8 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3 "AND sum(tre.item_id * tre.componentcount) = %u", buf2.c_str(), count, sum); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, re-query: %s", query.c_str()); - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, re-query: %s", query.c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str()); return false; } } @@ -1290,18 +1292,18 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3 "AND tre.item_id = %u;", buf2.c_str(), containerId); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, re-query: %s", query.c_str()); - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, re-query: %s", query.c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str()); return false; } if(results.RowCount() == 0) { //Recipe contents matched more than 1 recipe, but not in this container - LogFile->write(EQEMuLog::Error, "Combine error: Incorrect container is being used!"); + LogFile->write(EQEmuLog::Error, "Combine error: Incorrect container is being used!"); return false; } if (results.RowCount() > 1) //Recipe contents matched more than 1 recipe in this container - LogFile->write(EQEMuLog::Error, "Combine error: Recipe is not unique! %u matches found for container %u. Continuing with first recipe match.", results.RowCount(), containerId); + LogFile->write(EQEmuLog::Error, "Combine error: Recipe is not unique! %u matches found for container %u. Continuing with first recipe match.", results.RowCount(), containerId); } @@ -1318,7 +1320,7 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3 recipe_id); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in tradeskill verify query: '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in tradeskill verify query: '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return GetTradeRecipe(recipe_id, c_type, some_id, char_id, spec); } @@ -1373,8 +1375,8 @@ bool ZoneDatabase::GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id char_id, (unsigned long)recipe_id, containers.c_str()); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, query: %s", query.c_str()); - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, query: %s", query.c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str()); return false; } @@ -1405,12 +1407,12 @@ bool ZoneDatabase::GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id "WHERE successcount > 0 AND recipe_id = %u", recipe_id); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept success query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecept success query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } if(results.RowCount() < 1) { - LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept success: no success items returned"); + LogFile->write(EQEmuLog::Error, "Error in GetTradeRecept success: no success items returned"); return false; } @@ -1462,7 +1464,7 @@ void ZoneDatabase::UpdateRecipeMadecount(uint32 recipe_id, uint32 char_id, uint3 recipe_id, char_id, madeCount, madeCount); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in UpdateRecipeMadecount query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in UpdateRecipeMadecount query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); } void Client::LearnRecipe(uint32 recipeID) @@ -1475,12 +1477,12 @@ void Client::LearnRecipe(uint32 recipeID) "WHERE tr.id = %u ;", CharacterID(), recipeID); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Client::LearnRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in Client::LearnRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } if (results.RowCount() != 1) { - LogFile->write(EQEMuLog::Normal, "Client::LearnRecipe - RecipeID: %d had %d occurences.", recipeID, results.RowCount()); + LogFile->write(EQEmuLog::Normal, "Client::LearnRecipe - RecipeID: %d had %d occurences.", recipeID, results.RowCount()); return; } @@ -1501,7 +1503,7 @@ void Client::LearnRecipe(uint32 recipeID) recipeID, CharacterID()); results = database.QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in LearnRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LearnRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); } @@ -1551,7 +1553,7 @@ bool ZoneDatabase::EnableRecipe(uint32 recipe_id) "WHERE id = %u;", recipe_id); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in EnableRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in EnableRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return results.RowsAffected() > 0; } @@ -1562,7 +1564,7 @@ bool ZoneDatabase::DisableRecipe(uint32 recipe_id) "WHERE id = %u;", recipe_id); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in DisableRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in DisableRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return results.RowsAffected() > 0; } diff --git a/zone/trading.cpp b/zone/trading.cpp index b9b582bfe..d8c67588f 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -85,7 +85,7 @@ void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) { if (!owner || !owner->IsClient()) { // This should never happen - LogFile->write(EQEMuLog::Debug, "Programming error: NPC's should not call Trade::AddEntity()"); + LogFile->write(EQEmuLog::Debug, "Programming error: NPC's should not call Trade::AddEntity()"); return; } @@ -159,6 +159,9 @@ Mob* Trade::With() // Private Method: Send item data for trade item to other person involved in trade void Trade::SendItemData(const ItemInst* inst, int16 dest_slot_id) { + if (inst == nullptr) + return; + // @merth: This needs to be redone with new item classes Mob* mob = With(); if (!mob->IsClient()) @@ -292,7 +295,7 @@ void Trade::LogTrade() void Trade::DumpTrade() { Mob* with = With(); - LogFile->write(EQEMuLog::Debug, "Dumping trade data: '%s' in TradeState %i with '%s'", + LogFile->write(EQEmuLog::Debug, "Dumping trade data: '%s' in TradeState %i with '%s'", this->owner->GetName(), state, ((with==nullptr)?"(null)":with->GetName())); if (!owner->IsClient()) @@ -303,7 +306,7 @@ void Trade::DumpTrade() const ItemInst* inst = trader->GetInv().GetItem(i); if (inst) { - LogFile->write(EQEMuLog::Debug, "Item %i (Charges=%i, Slot=%i, IsBag=%s)", + LogFile->write(EQEmuLog::Debug, "Item %i (Charges=%i, Slot=%i, IsBag=%s)", inst->GetItem()->ID, inst->GetCharges(), i, ((inst->IsType(ItemClassContainer)) ? "True" : "False")); @@ -311,7 +314,7 @@ void Trade::DumpTrade() for (uint8 j = SUB_BEGIN; j < EmuConstants::ITEM_CONTAINER_SIZE; j++) { inst = trader->GetInv().GetItem(i, j); if (inst) { - LogFile->write(EQEMuLog::Debug, "\tBagItem %i (Charges=%i, Slot=%i)", + LogFile->write(EQEmuLog::Debug, "\tBagItem %i (Charges=%i, Slot=%i)", inst->GetItem()->ID, inst->GetCharges(), Inventory::CalcSlotId(i, j)); } @@ -320,7 +323,7 @@ void Trade::DumpTrade() } } - LogFile->write(EQEMuLog::Debug, "\tpp:%i, gp:%i, sp:%i, cp:%i", pp, gp, sp, cp); + LogFile->write(EQEmuLog::Debug, "\tpp:%i, gp:%i, sp:%i, cp:%i", pp, gp, sp, cp); } #endif @@ -1535,7 +1538,7 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat if((tbs->Price * outtbs->Quantity) <= 0) { Message(13, "Internal error. Aborting trade. Please report this to the ServerOP. Error code is 1"); Trader->Message(13, "Internal error. Aborting trade. Please report this to the ServerOP. Error code is 1"); - LogFile->write(EQEMuLog::Error, "Bazaar: Zero price transaction between %s and %s aborted." + LogFile->write(EQEmuLog::Error, "Bazaar: Zero price transaction between %s and %s aborted." "Item: %s, Charges: %i, TBS: Qty %i, Price: %i", GetName(), Trader->GetName(), BuyItem->GetItem()->Name, BuyItem->GetCharges(), tbs->Quantity, tbs->Price); diff --git a/zone/trap.cpp b/zone/trap.cpp index d15271d30..3cc684530 100644 --- a/zone/trap.cpp +++ b/zone/trap.cpp @@ -264,7 +264,7 @@ bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) { "FROM traps WHERE zone='%s' AND version=%u", zonename, version); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadTraps query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadTraps query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -307,8 +307,8 @@ void Trap::CreateHiddenTrigger() make_npc->gender = 0; make_npc->loottable_id = 0; make_npc->npc_spells_id = 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; make_npc->trackable = 0; make_npc->level = level; strcpy(make_npc->special_abilities, "19,1^20,1^24,1^25,1"); diff --git a/zone/tribute.cpp b/zone/tribute.cpp index bbe8c1ef9..9fc6638e1 100644 --- a/zone/tribute.cpp +++ b/zone/tribute.cpp @@ -220,7 +220,7 @@ void Client::ChangeTributeSettings(TributeInfo_Struct *t) { void Client::SendTributeDetails(uint32 client_id, uint32 tribute_id) { if(tribute_list.count(tribute_id) != 1) { - LogFile->write(EQEMuLog::Error, "Details request for invalid tribute %lu", (unsigned long)tribute_id); + LogFile->write(EQEmuLog::Error, "Details request for invalid tribute %lu", (unsigned long)tribute_id); return; } TributeData &td = tribute_list[tribute_id]; @@ -390,7 +390,7 @@ bool ZoneDatabase::LoadTributes() { const std::string query = "SELECT id, name, descr, unknown, isguild FROM tributes"; auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadTributes first query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadTributes first query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -407,7 +407,7 @@ bool ZoneDatabase::LoadTributes() { const std::string query2 = "SELECT tribute_id, level, cost, item_id FROM tribute_levels ORDER BY tribute_id, level"; results = QueryDatabase(query2); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadTributes level query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadTributes level query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -415,14 +415,14 @@ bool ZoneDatabase::LoadTributes() { uint32 id = atoul(row[0]); if(tribute_list.count(id) != 1) { - LogFile->write(EQEMuLog::Error, "Error in LoadTributes: unknown tribute %lu in tribute_levels", (unsigned long)id); + LogFile->write(EQEmuLog::Error, "Error in LoadTributes: unknown tribute %lu in tribute_levels", (unsigned long)id); continue; } TributeData &cur = tribute_list[id]; if(cur.tier_count >= MAX_TRIBUTE_TIERS) { - LogFile->write(EQEMuLog::Error, "Error in LoadTributes: on tribute %lu: more tiers defined than permitted", (unsigned long)id); + LogFile->write(EQEmuLog::Error, "Error in LoadTributes: on tribute %lu: more tiers defined than permitted", (unsigned long)id); continue; } diff --git a/zone/water_map.h b/zone/water_map.h index dd07fca5f..32047378b 100644 --- a/zone/water_map.h +++ b/zone/water_map.h @@ -5,6 +5,7 @@ #include "position.h" #include + enum WaterRegionType { RegionTypeUnsupported = -2, RegionTypeUntagged = -1, @@ -22,7 +23,7 @@ class WaterMap { public: WaterMap() { } - ~WaterMap() { } + virtual ~WaterMap() { } static WaterMap* LoadWaterMapfile(std::string zone_name); virtual WaterRegionType ReturnRegionType(const xyz_location& location) const { return RegionTypeNormal; } diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index eb616fbe8..5a315add0 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -116,7 +116,7 @@ void NPC::ResumeWandering() } else { - LogFile->write(EQEMuLog::Error, "NPC not paused - can't resume wandering: %lu", (unsigned long)GetNPCTypeID()); + LogFile->write(EQEmuLog::Error, "NPC not paused - can't resume wandering: %lu", (unsigned long)GetNPCTypeID()); return; } @@ -131,7 +131,7 @@ void NPC::ResumeWandering() } else { - LogFile->write(EQEMuLog::Error, "NPC not on grid - can't resume wandering: %lu", (unsigned long)GetNPCTypeID()); + LogFile->write(EQEmuLog::Error, "NPC not on grid - can't resume wandering: %lu", (unsigned long)GetNPCTypeID()); } return; } @@ -154,7 +154,7 @@ void NPC::PauseWandering(int pausetime) AIwalking_timer->Start(pausetime*1000); // set the timer } } else { - LogFile->write(EQEMuLog::Error, "NPC not on grid - can't pause wandering: %lu", (unsigned long)GetNPCTypeID()); + LogFile->write(EQEmuLog::Error, "NPC not on grid - can't pause wandering: %lu", (unsigned long)GetNPCTypeID()); } return; } @@ -382,7 +382,9 @@ void NPC::GetClosestWaypoint(std::list &wp_list, int count, const xyz_lo w_dist.index = i; distances.push_back(w_dist); } - distances.sort(wp_distance_pred); + distances.sort([](const wp_distance& a, const wp_distance& b) { + return a.dist < b.dist; + }); std::list::iterator iter = distances.begin(); for(int i = 0; i < count; ++i) @@ -678,7 +680,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b { Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z); - float newz = zone->zonemap->FindBestZ(dest, nullptr); + 2.0f; + float newz = zone->zonemap->FindBestZ(dest, nullptr); mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z); @@ -852,7 +854,7 @@ void NPC::AssignWaypoints(int32 grid) { std::string query = StringFormat("SELECT `type`, `type2` FROM `grid` WHERE `id` = %i AND `zoneid` = %i", grid, zone->GetZoneID()); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "MySQL Error while trying to assign grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str()); return; } @@ -873,7 +875,7 @@ void NPC::AssignWaypoints(int32 grid) { "ORDER BY `number`", grid, zone->GetZoneID()); results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign waypoints from grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "MySQL Error while trying to assign waypoints from grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str()); return; } @@ -988,7 +990,7 @@ int ZoneDatabase::GetHighestGrid(uint32 zoneid) { std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetHighestGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetHighestGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -1005,7 +1007,7 @@ uint8 ZoneDatabase::GetGridType2(uint32 grid, uint16 zoneid) { std::string query = StringFormat("SELECT type2 FROM grid WHERE id = %i AND zoneid = %i", grid, zoneid); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetGridType2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetGridType2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -1026,7 +1028,7 @@ bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* "WHERE gridid = %i AND number = %i AND zoneid = %i", grid, num, zoneid); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetWaypoints query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetWaypoints query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -1054,7 +1056,7 @@ void ZoneDatabase::AssignGrid(Client *client, const xy_location& location, uint3 zone->GetShortName(), (int)location.m_X, (int)location.m_Y); auto results = QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -1068,7 +1070,7 @@ void ZoneDatabase::AssignGrid(Client *client, const xy_location& location, uint3 zone->GetShortName(), location.m_X, _GASSIGN_TOLERANCE, location.m_Y, _GASSIGN_TOLERANCE); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -1097,7 +1099,7 @@ void ZoneDatabase::AssignGrid(Client *client, const xy_location& location, uint3 results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error updating spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error updating spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -1135,7 +1137,7 @@ void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type "VALUES (%i, %i, %i, %i)", id, zoneid, type, type2); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error creating grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error creating grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -1148,14 +1150,14 @@ void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type std::string query = StringFormat("DELETE FROM grid where id=%i", id); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error deleting grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error deleting grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) client->LogSQL(query.c_str()); query = StringFormat("DELETE FROM grid_entries WHERE zoneid = %i AND gridid = %i", zoneid, id); results = QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Error deleting grid entries '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error deleting grid entries '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) client->LogSQL(query.c_str()); @@ -1171,7 +1173,7 @@ void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, const xyz_ gridid, zoneid, wpnum, position.m_X, position.m_Y, position.m_Z, pause, position.m_Heading); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -1197,7 +1199,7 @@ void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num grid_num, zoneid, wp_num); auto results = QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error deleting waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error deleting waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -1224,7 +1226,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_he auto results = QueryDatabase(query); if (!results.Success()) { // Query error - LogFile->write(EQEMuLog::Error, "Error setting pathgrid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error setting pathgrid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -1245,14 +1247,14 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_he grid_num, zoneid, type1, type2); results = QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Error adding grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error adding grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) client->LogSQL(query.c_str()); query = StringFormat("UPDATE spawn2 SET pathgrid = '%i' WHERE id = '%i'", grid_num, spawn2id); results = QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) client->LogSQL(query.c_str()); } @@ -1264,7 +1266,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_he results = QueryDatabase(query); if(!results.Success()) { // Query error - LogFile->write(EQEMuLog::Error, "Error getting next waypoint id '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error getting next waypoint id '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -1279,7 +1281,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_he grid_num, zoneid, next_wp_num, position.m_X, position.m_Y, position.m_Z, pause, position.m_Heading); results = QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) client->LogSQL(query.c_str()); @@ -1291,7 +1293,7 @@ uint32 ZoneDatabase::GetFreeGrid(uint16 zoneid) { std::string query = StringFormat("SELECT max(id) FROM grid WHERE zoneid = %i", zoneid); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetFreeGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetFreeGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -1311,7 +1313,7 @@ int ZoneDatabase::GetHighestWaypoint(uint32 zoneid, uint32 gridid) { "WHERE zoneid = %i AND gridid = %i", zoneid, gridid); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetHighestWaypoint query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetHighestWaypoint query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index b0d958e7c..d76fec5c0 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -1384,7 +1384,7 @@ void WorldServer::Process() { if(NewCorpse) NewCorpse->Spawn(); else - LogFile->write(EQEMuLog::Error,"Unable to load player corpse id %u for zone %s.", s->player_corpse_id, zone->GetShortName()); + LogFile->write(EQEmuLog::Error,"Unable to load player corpse id %u for zone %s.", s->player_corpse_id, zone->GetShortName()); break; } diff --git a/zone/zone.cpp b/zone/zone.cpp index ca546abba..4fc9fb7e1 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -83,7 +83,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { return false; } - LogFile->write(EQEMuLog::Status, "Booting %s (%d:%d)", zonename, iZoneID, iInstanceID); + LogFile->write(EQEmuLog::Status, "Booting %s (%d:%d)", zonename, iZoneID, iInstanceID); numclients = 0; zone = new Zone(iZoneID, iInstanceID, zonename); @@ -110,13 +110,13 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { log_levels[i]=0; //set to zero on a bogue char } zone->loglevelvar = log_levels[0]; - LogFile->write(EQEMuLog::Status, "General logging level: %i", zone->loglevelvar); + LogFile->write(EQEmuLog::Status, "General logging level: %i", zone->loglevelvar); zone->merchantvar = log_levels[1]; - LogFile->write(EQEMuLog::Status, "Merchant logging level: %i", zone->merchantvar); + LogFile->write(EQEmuLog::Status, "Merchant logging level: %i", zone->merchantvar); zone->tradevar = log_levels[2]; - LogFile->write(EQEMuLog::Status, "Trade logging level: %i", zone->tradevar); + LogFile->write(EQEmuLog::Status, "Trade logging level: %i", zone->tradevar); zone->lootvar = log_levels[3]; - LogFile->write(EQEMuLog::Status, "Loot logging level: %i", zone->lootvar); + LogFile->write(EQEmuLog::Status, "Loot logging level: %i", zone->lootvar); } else { zone->loglevelvar = uint8(atoi(tmp)); //continue supporting only command logging (for now) @@ -137,8 +137,8 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { delete pack; } - LogFile->write(EQEMuLog::Normal, "---- Zone server %s, listening on port:%i ----", zonename, ZoneConfig::get()->ZonePort); - LogFile->write(EQEMuLog::Status, "Zone Bootup: %s (%i: %i)", zonename, iZoneID, iInstanceID); + LogFile->write(EQEmuLog::Normal, "---- Zone server %s, listening on port:%i ----", zonename, ZoneConfig::get()->ZonePort); + LogFile->write(EQEmuLog::Status, "Zone Bootup: %s (%i: %i)", zonename, iZoneID, iInstanceID); parse->Init(); UpdateWindowTitle(); zone->GetTimeSync(); @@ -156,11 +156,11 @@ bool Zone::LoadZoneObjects() { zoneid, instanceversion); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error Loading Objects from DB: %s",results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error Loading Objects from DB: %s",results.ErrorMessage().c_str()); return false; } - LogFile->write(EQEMuLog::Status, "Loading Objects from DB..."); + LogFile->write(EQEmuLog::Status, "Loading Objects from DB..."); for (auto row = results.begin(); row != results.end(); ++row) { if (atoi(row[9]) == 0) { @@ -277,7 +277,7 @@ bool Zone::LoadGroundSpawns() { memset(&groundspawn, 0, sizeof(groundspawn)); int gsindex=0; - LogFile->write(EQEMuLog::Status, "Loading Ground Spawns from DB..."); + LogFile->write(EQEmuLog::Status, "Loading Ground Spawns from DB..."); database.LoadGroundSpawns(zoneid, GetInstanceVersion(), &groundspawn); uint32 ix=0; char* name=0; @@ -391,7 +391,7 @@ uint32 Zone::GetTempMerchantQuantity(uint32 NPCID, uint32 Slot) { } void Zone::LoadTempMerchantData() { - LogFile->write(EQEMuLog::Status, "Loading Temporary Merchant Lists..."); + LogFile->write(EQEmuLog::Status, "Loading Temporary Merchant Lists..."); std::string query = StringFormat( "SELECT " "DISTINCT ml.npcid, " @@ -409,7 +409,7 @@ void Zone::LoadTempMerchantData() { "ORDER BY ml.slot ", GetShortName(), GetInstanceVersion()); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadTempMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadTempMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); return; } std::map >::iterator cur; @@ -442,7 +442,7 @@ void Zone::LoadNewMerchantData(uint32 merchantid) { "classes_required, probability FROM merchantlist WHERE merchantid=%d ORDER BY slot", merchantid); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadNewMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadNewMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -463,8 +463,8 @@ void Zone::LoadNewMerchantData(uint32 merchantid) { } void Zone::GetMerchantDataForZoneLoad() { - LogFile->write(EQEMuLog::Status, "Loading Merchant Lists..."); - std::string query = StringFormat( + LogFile->write(EQEmuLog::Status, "Loading Merchant Lists..."); + std::string query = StringFormat( "SELECT " "DISTINCT ml.merchantid, " "ml.slot, " @@ -486,7 +486,7 @@ void Zone::GetMerchantDataForZoneLoad() { std::map >::iterator cur; uint32 npcid = 0; if (results.RowCount() == 0) { - LogFile->write(EQEMuLog::Debug, "No Merchant Data found for %s.", GetShortName()); + LogFile->write(EQEmuLog::Debug, "No Merchant Data found for %s.", GetShortName()); return; } for (auto row = results.begin(); row != results.end(); ++row) { @@ -536,7 +536,7 @@ void Zone::LoadMercTemplates(){ "`merc_stance_entries` ORDER BY `class_id`, `proficiency_id`, `stance_id`"; auto results = database.QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadMercTemplates()"); + LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadMercTemplates()"); else { for (auto row = results.begin(); row != results.end(); ++row) { MercStanceInfo tempMercStanceInfo; @@ -559,7 +559,7 @@ void Zone::LoadMercTemplates(){ "ORDER BY MTyp.race_id, MS.class_id, MTyp.proficiency_id;"; results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadMercTemplates()"); + LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadMercTemplates()"); return; } @@ -603,7 +603,7 @@ void Zone::LoadLevelEXPMods(){ const std::string query = "SELECT level, exp_mod, aa_exp_mod FROM level_exp_mods"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadEXPLevelMods()"); + LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadEXPLevelMods()"); return; } @@ -627,7 +627,7 @@ void Zone::LoadMercSpells(){ "ORDER BY msl.class_id, msl.proficiency_id, msle.spell_type, msle.minlevel, msle.slot;"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Zone::LoadMercSpells()"); + LogFile->write(EQEmuLog::Error, "Error in Zone::LoadMercSpells()"); return; } @@ -649,7 +649,7 @@ void Zone::LoadMercSpells(){ } if(MERC_DEBUG > 0) - LogFile->write(EQEMuLog::Debug, "Mercenary Debug: Loaded %i merc spells.", merc_spells_list[1].size() + merc_spells_list[2].size() + merc_spells_list[9].size() + merc_spells_list[12].size()); + LogFile->write(EQEmuLog::Debug, "Mercenary Debug: Loaded %i merc spells.", merc_spells_list[1].size() + merc_spells_list[2].size() + merc_spells_list[9].size() + merc_spells_list[12].size()); } @@ -696,11 +696,11 @@ void Zone::Shutdown(bool quite) } zone->ldon_trap_entry_list.clear(); - LogFile->write(EQEMuLog::Status, "Zone Shutdown: %s (%i)", zone->GetShortName(), zone->GetZoneID()); + LogFile->write(EQEmuLog::Status, "Zone Shutdown: %s (%i)", zone->GetShortName(), zone->GetZoneID()); petition_list.ClearPetitions(); zone->GotCurTime(false); if (!quite) - LogFile->write(EQEMuLog::Normal, "Zone shutdown: going to sleep"); + LogFile->write(EQEmuLog::Normal, "Zone shutdown: going to sleep"); ZoneLoaded = false; zone->ResetAuth(); @@ -712,19 +712,19 @@ void Zone::Shutdown(bool quite) void Zone::LoadZoneDoors(const char* zone, int16 version) { - LogFile->write(EQEMuLog::Status, "Loading doors for %s ...", zone); + LogFile->write(EQEmuLog::Status, "Loading doors for %s ...", zone); uint32 maxid; int32 count = database.GetDoorsCount(&maxid, zone, version); if(count < 1) { - LogFile->write(EQEMuLog::Status, "... No doors loaded."); + LogFile->write(EQEmuLog::Status, "... No doors loaded."); return; } Door *dlist = new Door[count]; if(!database.LoadDoors(count, dlist, zone, version)) { - LogFile->write(EQEMuLog::Error, "... Failed to load doors."); + LogFile->write(EQEmuLog::Error, "... Failed to load doors."); delete[] dlist; return; } @@ -782,12 +782,12 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) database.GetZoneLongName(short_name, &long_name, file_name, &m_SafePoint.m_X, &m_SafePoint.m_Y, &m_SafePoint.m_Z, &pgraveyard_id, &pMaxClients); if(graveyard_id() > 0) { - LogFile->write(EQEMuLog::Debug, "Graveyard ID is %i.", graveyard_id()); + LogFile->write(EQEmuLog::Debug, "Graveyard ID is %i.", graveyard_id()); bool GraveYardLoaded = database.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &m_Graveyard.m_X, &m_Graveyard.m_Y, &m_Graveyard.m_Z, &m_Graveyard.m_Heading); if(GraveYardLoaded) - LogFile->write(EQEMuLog::Debug, "Loaded a graveyard for zone %s: graveyard zoneid is %u at %s.", short_name, graveyard_zoneid(), to_string(m_Graveyard).c_str()); + LogFile->write(EQEmuLog::Debug, "Loaded a graveyard for zone %s: graveyard zoneid is %u at %s.", short_name, graveyard_zoneid(), to_string(m_Graveyard).c_str()); else - LogFile->write(EQEMuLog::Error, "Unable to load the graveyard id %i for zone %s.", graveyard_id(), short_name); + LogFile->write(EQEmuLog::Error, "Unable to load the graveyard id %i for zone %s.", graveyard_id(), short_name); } if (long_name == 0) { long_name = strcpy(new char[18], "Long zone missing"); @@ -795,7 +795,7 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) autoshutdown_timer.Start(AUTHENTICATION_TIMEOUT * 1000, false); Weather_Timer = new Timer(60000); Weather_Timer->Start(); - LogFile->write(EQEMuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", short_name, Weather_Timer->GetRemainingTime()/1000); + LogFile->write(EQEmuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", short_name, Weather_Timer->GetRemainingTime()/1000); zone_weather = 0; weather_intensity = 0; blocked_spells = nullptr; @@ -880,56 +880,56 @@ Zone::~Zone() { bool Zone::Init(bool iStaticZone) { SetStaticZone(iStaticZone); - LogFile->write(EQEMuLog::Status, "Loading spawn conditions..."); + LogFile->write(EQEmuLog::Status, "Loading spawn conditions..."); if(!spawn_conditions.LoadSpawnConditions(short_name, instanceid)) { - LogFile->write(EQEMuLog::Error, "Loading spawn conditions failed, continuing without them."); + LogFile->write(EQEmuLog::Error, "Loading spawn conditions failed, continuing without them."); } - LogFile->write(EQEMuLog::Status, "Loading static zone points..."); + LogFile->write(EQEmuLog::Status, "Loading static zone points..."); if (!database.LoadStaticZonePoints(&zone_point_list, short_name, GetInstanceVersion())) { - LogFile->write(EQEMuLog::Error, "Loading static zone points failed."); + LogFile->write(EQEmuLog::Error, "Loading static zone points failed."); return false; } - LogFile->write(EQEMuLog::Status, "Loading spawn groups..."); + LogFile->write(EQEmuLog::Status, "Loading spawn groups..."); if (!database.LoadSpawnGroups(short_name, GetInstanceVersion(), &spawn_group_list)) { - LogFile->write(EQEMuLog::Error, "Loading spawn groups failed."); + LogFile->write(EQEmuLog::Error, "Loading spawn groups failed."); return false; } - LogFile->write(EQEMuLog::Status, "Loading spawn2 points..."); + LogFile->write(EQEmuLog::Status, "Loading spawn2 points..."); if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion())) { - LogFile->write(EQEMuLog::Error, "Loading spawn2 points failed."); + LogFile->write(EQEmuLog::Error, "Loading spawn2 points failed."); return false; } - LogFile->write(EQEMuLog::Status, "Loading player corpses..."); + LogFile->write(EQEmuLog::Status, "Loading player corpses..."); if (!database.LoadCharacterCorpses(zoneid, instanceid)) { - LogFile->write(EQEMuLog::Error, "Loading player corpses failed."); + LogFile->write(EQEmuLog::Error, "Loading player corpses failed."); return false; } - LogFile->write(EQEMuLog::Status, "Loading traps..."); + LogFile->write(EQEmuLog::Status, "Loading traps..."); if (!database.LoadTraps(short_name, GetInstanceVersion())) { - LogFile->write(EQEMuLog::Error, "Loading traps failed."); + LogFile->write(EQEmuLog::Error, "Loading traps failed."); return false; } - LogFile->write(EQEMuLog::Status, "Loading adventure flavor text..."); + LogFile->write(EQEmuLog::Status, "Loading adventure flavor text..."); LoadAdventureFlavor(); - LogFile->write(EQEMuLog::Status, "Loading ground spawns..."); + LogFile->write(EQEmuLog::Status, "Loading ground spawns..."); if (!LoadGroundSpawns()) { - LogFile->write(EQEMuLog::Error, "Loading ground spawns failed. continuing."); + LogFile->write(EQEmuLog::Error, "Loading ground spawns failed. continuing."); } - LogFile->write(EQEMuLog::Status, "Loading World Objects from DB..."); + LogFile->write(EQEmuLog::Status, "Loading World Objects from DB..."); if (!LoadZoneObjects()) { - LogFile->write(EQEMuLog::Error, "Loading World Objects failed. continuing."); + LogFile->write(EQEmuLog::Error, "Loading World Objects failed. continuing."); } //load up the zone's doors (prints inside) @@ -986,10 +986,10 @@ bool Zone::Init(bool iStaticZone) { } } - LogFile->write(EQEMuLog::Status, "Loading timezone data..."); + LogFile->write(EQEmuLog::Status, "Loading timezone data..."); zone->zone_time.setEQTimeZone(database.GetZoneTZ(zoneid, GetInstanceVersion())); - LogFile->write(EQEMuLog::Status, "Init Finished: ZoneID = %d, Time Offset = %d", zoneid, zone->zone_time.getEQTimeZone()); + LogFile->write(EQEmuLog::Status, "Init Finished: ZoneID = %d, Time Offset = %d", zoneid, zone->zone_time.getEQTimeZone()); LoadTickItems(); @@ -1000,32 +1000,32 @@ bool Zone::Init(bool iStaticZone) { } void Zone::ReloadStaticData() { - LogFile->write(EQEMuLog::Status, "Reloading Zone Static Data..."); + LogFile->write(EQEmuLog::Status, "Reloading Zone Static Data..."); - LogFile->write(EQEMuLog::Status, "Reloading static zone points..."); + LogFile->write(EQEmuLog::Status, "Reloading static zone points..."); zone_point_list.Clear(); if (!database.LoadStaticZonePoints(&zone_point_list, GetShortName(), GetInstanceVersion())) { - LogFile->write(EQEMuLog::Error, "Loading static zone points failed."); + LogFile->write(EQEmuLog::Error, "Loading static zone points failed."); } - LogFile->write(EQEMuLog::Status, "Reloading traps..."); + LogFile->write(EQEmuLog::Status, "Reloading traps..."); entity_list.RemoveAllTraps(); if (!database.LoadTraps(GetShortName(), GetInstanceVersion())) { - LogFile->write(EQEMuLog::Error, "Reloading traps failed."); + LogFile->write(EQEmuLog::Error, "Reloading traps failed."); } - LogFile->write(EQEMuLog::Status, "Reloading ground spawns..."); + LogFile->write(EQEmuLog::Status, "Reloading ground spawns..."); if (!LoadGroundSpawns()) { - LogFile->write(EQEMuLog::Error, "Reloading ground spawns failed. continuing."); + LogFile->write(EQEmuLog::Error, "Reloading ground spawns failed. continuing."); } entity_list.RemoveAllObjects(); - LogFile->write(EQEMuLog::Status, "Reloading World Objects from DB..."); + LogFile->write(EQEmuLog::Status, "Reloading World Objects from DB..."); if (!LoadZoneObjects()) { - LogFile->write(EQEMuLog::Error, "Reloading World Objects failed. continuing."); + LogFile->write(EQEmuLog::Error, "Reloading World Objects failed. continuing."); } entity_list.RemoveAllDoors(); @@ -1041,7 +1041,7 @@ void Zone::ReloadStaticData() { if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion(), true)) // try loading the zone name... LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults - LogFile->write(EQEMuLog::Status, "Zone Static Data Reloaded."); + LogFile->write(EQEmuLog::Status, "Zone Static Data Reloaded."); } bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDefault) @@ -1053,7 +1053,7 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDe if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind, can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name)) { - LogFile->write(EQEMuLog::Error, "Error loading the Zone Config."); + LogFile->write(EQEmuLog::Error, "Error loading the Zone Config."); return false; } } @@ -1068,7 +1068,7 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDe if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind, can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name)) { - LogFile->write(EQEMuLog::Error, "Error loading the Zone Config."); + LogFile->write(EQEmuLog::Error, "Error loading the Zone Config."); return false; } } @@ -1079,7 +1079,7 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDe strcpy(newzone_data.zone_long_name, GetLongName()); strcpy(newzone_data.zone_short_name2, GetShortName()); - LogFile->write(EQEMuLog::Status, "Successfully loaded Zone Config."); + LogFile->write(EQEmuLog::Status, "Successfully loaded Zone Config."); return true; } @@ -1384,11 +1384,11 @@ void Zone::ChangeWeather() weathertimer = weatherTimerRule*1000; Weather_Timer->Start(weathertimer); } - LogFile->write(EQEMuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", zone->GetShortName(), Weather_Timer->GetRemainingTime()/1000); + LogFile->write(EQEmuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", zone->GetShortName(), Weather_Timer->GetRemainingTime()/1000); } else { - LogFile->write(EQEMuLog::Debug, "The weather for zone: %s has changed. Old weather was = %i. New weather is = %i The next check will be in %i seconds. Rain chance: %i, Rain duration: %i, Snow chance %i, Snow duration: %i", zone->GetShortName(), tmpOldWeather, zone_weather,Weather_Timer->GetRemainingTime()/1000,rainchance,rainduration,snowchance,snowduration); + LogFile->write(EQEmuLog::Debug, "The weather for zone: %s has changed. Old weather was = %i. New weather is = %i The next check will be in %i seconds. Rain chance: %i, Rain duration: %i, Snow chance %i, Snow duration: %i", zone->GetShortName(), tmpOldWeather, zone_weather,Weather_Timer->GetRemainingTime()/1000,rainchance,rainduration,snowchance,snowduration); this->weatherSend(); } } @@ -1473,7 +1473,7 @@ void Zone::Repop(uint32 delay) { quest_manager.ClearAllTimers(); if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion(), delay)) - LogFile->write(EQEMuLog::Debug, "Error in Zone::Repop: database.PopulateZoneSpawnList failed"); + LogFile->write(EQEmuLog::Debug, "Error in Zone::Repop: database.PopulateZoneSpawnList failed"); initgrids_timer.Start(); @@ -1557,8 +1557,8 @@ ZonePoint* Zone::GetClosestZonePoint(const xyz_location& location, uint32 to, Cl { if(client) client->CheatDetected(MQZoneUnknownDest, location.m_X, location.m_Y, location.m_Z); // Someone is trying to use /zone - LogFile->write(EQEMuLog::Status, "WARNING: Closest zone point for zone id %d is %f, you might need to update your zone_points table if you dont arrive at the right spot.", to, closest_dist); - LogFile->write(EQEMuLog::Status, ". %s", to_string(location).c_str()); + LogFile->write(EQEmuLog::Status, "WARNING: Closest zone point for zone id %d is %f, you might need to update your zone_points table if you dont arrive at the right spot.", to, closest_dist); + LogFile->write(EQEmuLog::Status, ". %s", to_string(location).c_str()); } if(closest_dist > max_distance2) @@ -1835,7 +1835,7 @@ void Zone::LoadBlockedSpells(uint32 zoneid) blocked_spells = new ZoneSpellsBlocked[totalBS]; if(!database.LoadBlockedSpells(totalBS, blocked_spells, zoneid)) { - LogFile->write(EQEMuLog::Error, "... Failed to load blocked spells."); + LogFile->write(EQEmuLog::Error, "... Failed to load blocked spells."); ClearBlockedSpells(); } } @@ -1962,7 +1962,7 @@ void Zone::LoadLDoNTraps() const std::string query = "SELECT id, type, spell_id, skill, locked FROM ldon_trap_templates"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Zone::LoadLDoNTraps: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in Zone::LoadLDoNTraps: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -1983,7 +1983,7 @@ void Zone::LoadLDoNTrapEntries() const std::string query = "SELECT id, trap_id FROM ldon_trap_entries"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Zone::LoadLDoNTrapEntries: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in Zone::LoadLDoNTrapEntries: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -2025,7 +2025,7 @@ void Zone::LoadVeteranRewards() "ORDER by claim_id, reward_slot"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Zone::LoadVeteranRewards: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in Zone::LoadVeteranRewards: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -2071,7 +2071,7 @@ void Zone::LoadAlternateCurrencies() const std::string query = "SELECT id, item_id FROM alternate_currency"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Zone::LoadAlternateCurrencies: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in Zone::LoadAlternateCurrencies: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -2119,7 +2119,7 @@ void Zone::LoadAdventureFlavor() const std::string query = "SELECT id, text FROM adventure_template_entry_flavor"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Zone::LoadAdventureFlavor: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in Zone::LoadAdventureFlavor: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -2194,7 +2194,7 @@ void Zone::LoadNPCEmotes(LinkedList* NPCEmoteList) const std::string query = "SELECT emoteid, event_, type, text FROM npc_emotes"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Zone::LoadNPCEmotes: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in Zone::LoadNPCEmotes: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -2211,7 +2211,10 @@ void Zone::LoadNPCEmotes(LinkedList* NPCEmoteList) } void Zone::ReloadWorld(uint32 Option){ - if(Option == 1){ + if (Option == 0) { + entity_list.ClearAreas(); + parse->ReloadQuests(); + } else if(Option == 1) { zone->Repop(0); entity_list.ClearAreas(); parse->ReloadQuests(); @@ -2225,7 +2228,7 @@ void Zone::LoadTickItems() const std::string query = "SELECT it_itemid, it_chance, it_level, it_qglobal, it_bagslot FROM item_tick"; auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in Zone::LoadTickItems: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in Zone::LoadTickItems: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); return; } diff --git a/zone/zone_logsys.cpp b/zone/zone_logsys.cpp index c9ea6255d..50362c6b1 100644 --- a/zone/zone_logsys.cpp +++ b/zone/zone_logsys.cpp @@ -34,7 +34,7 @@ void log_message_mob(LogType type, Mob *who, const char *fmt, ...) { va_list args; va_start(args, fmt); - LogFile->writePVA(EQEMuLog::Debug, prefix_buffer, fmt, args); + LogFile->writePVA(EQEmuLog::Debug, prefix_buffer, fmt, args); va_end(args); } @@ -46,7 +46,7 @@ void log_message_mobVA(LogType type, Mob *who, const char *fmt, va_list args) { snprintf(prefix_buffer, 255, "[%s] %s: ", log_type_info[type].name, who->GetName()); prefix_buffer[255] = '\0'; - LogFile->writePVA(EQEMuLog::Debug, prefix_buffer, fmt, args); + LogFile->writePVA(EQEmuLog::Debug, prefix_buffer, fmt, args); } void log_hex_mob(LogType type, Mob *who, const char *data, uint32 length, uint8 padding) { diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index c1abb7003..0007b9e74 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1,4 +1,5 @@ + #include "../common/extprofile.h" #include "../common/item.h" #include "../common/rulesys.h" @@ -85,7 +86,7 @@ bool ZoneDatabase::SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct zoneid, instance_id); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in SaveZoneCFG query %s: %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in SaveZoneCFG query %s: %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -111,7 +112,7 @@ bool ZoneDatabase::GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct "FROM zone WHERE zoneidnumber = %i AND version = %i", zoneid, instance_id); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetZoneCFG query %s: %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetZoneCFG query %s: %s", query.c_str(), results.ErrorMessage().c_str()); strcpy(*map_filename, "default"); return false; } @@ -200,7 +201,7 @@ void ZoneDatabase::UpdateSpawn2Timeleft(uint32 id, uint16 instance_id, uint32 ti "AND instance_id = %lu",(unsigned long)id, (unsigned long)instance_id); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in UpdateTimeLeft query %s: %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in UpdateTimeLeft query %s: %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -211,7 +212,7 @@ void ZoneDatabase::UpdateSpawn2Timeleft(uint32 id, uint16 instance_id, uint32 ti (unsigned long)timeleft, (unsigned long)instance_id); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in UpdateTimeLeft query %s: %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in UpdateTimeLeft query %s: %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -224,7 +225,7 @@ uint32 ZoneDatabase::GetSpawnTimeLeft(uint32 id, uint16 instance_id) (unsigned long)id, (unsigned long)zone->GetInstanceID()); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetSpawnTimeLeft query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in GetSpawnTimeLeft query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -254,7 +255,7 @@ void ZoneDatabase::UpdateSpawn2Status(uint32 id, uint8 new_status) std::string query = StringFormat("UPDATE spawn2 SET enabled = %i WHERE id = %lu", new_status, (unsigned long)id); auto results = QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in UpdateSpawn2Status query %s: %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in UpdateSpawn2Status query %s: %s", query.c_str(), results.ErrorMessage().c_str()); } @@ -425,7 +426,7 @@ void ZoneDatabase::GetEventLogs(const char* name,char* target,uint32 account_id, void ZoneDatabase::LoadWorldContainer(uint32 parentid, ItemInst* container) { if (!container) { - LogFile->write(EQEMuLog::Error, "Programming error: LoadWorldContainer passed nullptr pointer"); + LogFile->write(EQEmuLog::Error, "Programming error: LoadWorldContainer passed nullptr pointer"); return; } @@ -433,7 +434,7 @@ void ZoneDatabase::LoadWorldContainer(uint32 parentid, ItemInst* container) "FROM object_contents WHERE parentid = %i", parentid); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in DB::LoadWorldContainer: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in DB::LoadWorldContainer: %s", results.ErrorMessage().c_str()); return; } @@ -498,7 +499,7 @@ void ZoneDatabase::SaveWorldContainer(uint32 zone_id, uint32 parent_id, const It augslot[0], augslot[1], augslot[2], augslot[3], augslot[4], augslot[5]); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::SaveWorldContainer: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::SaveWorldContainer: %s", results.ErrorMessage().c_str()); } @@ -510,7 +511,7 @@ void ZoneDatabase::DeleteWorldContainer(uint32 parent_id, uint32 zone_id) std::string query = StringFormat("DELETE FROM object_contents WHERE parentid = %i AND zoneid = %i", parent_id, zone_id); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::DeleteWorldContainer: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::DeleteWorldContainer: %s", results.ErrorMessage().c_str()); } @@ -1225,7 +1226,7 @@ bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Str bool ZoneDatabase::SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value){ std::string query = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, lang_id, value); QueryDatabase(query); - LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterLanguage for character ID: %i, lang_id:%u value:%u done", character_id, lang_id, value); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterLanguage for character ID: %i, lang_id:%u value:%u done", character_id, lang_id, value); return true; } @@ -1237,10 +1238,10 @@ bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, u /* Save Home Bind Point */ std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" " VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", character_id, zone_id, instance_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading, is_home); - LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u instance_id: %u position: %s ishome: %u", character_id, zone_id, instance_id, to_string(position).c_str(), is_home); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u instance_id: %u position: %s ishome: %u", character_id, zone_id, instance_id, to_string(position).c_str(), is_home); auto results = QueryDatabase(query); if (!results.RowsAffected()) { - LogFile->write(EQEMuLog::Debug, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str()); + LogFile->write(EQEmuLog::Debug, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str()); } return true; } @@ -1251,20 +1252,20 @@ bool ZoneDatabase::SaveCharacterMaterialColor(uint32 character_id, uint32 slot_i uint8 blue = (color & 0x000000FF); std::string query = StringFormat("REPLACE INTO `character_material` (id, slot, red, green, blue, color, use_tint) VALUES (%u, %u, %u, %u, %u, %u, 255)", character_id, slot_id, red, green, blue, color); auto results = QueryDatabase(query); - LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterMaterialColor for character ID: %i, slot_id: %u color: %u done", character_id, slot_id, color); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterMaterialColor for character ID: %i, slot_id: %u color: %u done", character_id, slot_id, color); return true; } bool ZoneDatabase::SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value){ std::string query = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, skill_id, value); auto results = QueryDatabase(query); - LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterSkill for character ID: %i, skill_id:%u value:%u done", character_id, skill_id, value); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterSkill for character ID: %i, skill_id:%u value:%u done", character_id, skill_id, value); return true; } bool ZoneDatabase::SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id){ std::string query = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, slot_id, disc_id); auto results = QueryDatabase(query); - LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterDisc for character ID: %i, slot:%u disc_id:%u done", character_id, slot_id, disc_id); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterDisc for character ID: %i, slot:%u disc_id:%u done", character_id, slot_id, disc_id); return true; } @@ -1276,7 +1277,7 @@ bool ZoneDatabase::SaveCharacterTribute(uint32 character_id, PlayerProfile_Struc if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != TRIBUTE_NONE){ std::string query = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); QueryDatabase(query); - LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterTribute for character ID: %i, tier:%u tribute:%u done", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterTribute for character ID: %i, tier:%u tribute:%u done", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); } } return true; @@ -1287,7 +1288,7 @@ bool ZoneDatabase::SaveCharacterBandolier(uint32 character_id, uint8 bandolier_i DoEscapeString(bandolier_name_esc, bandolier_name, strlen(bandolier_name)); std::string query = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%u, %u, %u, %u, %u,'%s')", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name_esc); auto results = QueryDatabase(query); - LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterBandolier for character ID: %i, bandolier_id: %u, bandolier_slot: %u item_id: %u, icon:%u band_name:%s done", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterBandolier for character ID: %i, bandolier_id: %u, bandolier_slot: %u item_id: %u, icon:%u band_name:%s done", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name); if (!results.RowsAffected()){ std::cout << "ERROR Bandolier Save: " << results.ErrorMessage() << "\n\n" << query << "\n" << std::endl; } return true; } @@ -1602,7 +1603,7 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla m_epp->expended_aa ); auto results = database.QueryDatabase(query); - LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC); return true; } @@ -1642,8 +1643,8 @@ bool ZoneDatabase::SaveCharacterCurrency(uint32 character_id, PlayerProfile_Stru pp->careerRadCrystals, pp->currentEbonCrystals, pp->careerEbonCrystals); - auto results = database.QueryDatabase(query); - LogFile->write(EQEMuLog::Debug, "Saving Currency for character ID: %i, done", character_id); + auto results = database.QueryDatabase(query); + LogFile->write(EQEmuLog::Debug, "Saving Currency for character ID: %i, done", character_id); return true; } @@ -1652,7 +1653,7 @@ bool ZoneDatabase::SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 cur " VALUES (%u, %u, %u)", character_id, aa_id, current_level); auto results = QueryDatabase(rquery); - LogFile->write(EQEMuLog::Debug, "Saving AA for character ID: %u, aa_id: %u current_level: %u", character_id, aa_id, current_level); + LogFile->write(EQEmuLog::Debug, "Saving AA for character ID: %u, aa_id: %u current_level: %u", character_id, aa_id, current_level); return true; } @@ -1746,15 +1747,15 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { // according to spawn2. std::string query = StringFormat("SELECT npc_types.id, npc_types.name, npc_types.level, npc_types.race, " "npc_types.class, npc_types.hp, npc_types.mana, npc_types.gender, " - "npc_types.texture, npc_types.helmtexture, npc_types.size, " + "npc_types.texture, npc_types.helmtexture, npc_types.herosforgemodel, npc_types.size, " "npc_types.loottable_id, npc_types.merchant_id, npc_types.alt_currency_id, " "npc_types.adventure_template_id, npc_types.trap_template, npc_types.attack_speed, " "npc_types.STR, npc_types.STA, npc_types.DEX, npc_types.AGI, npc_types._INT, " "npc_types.WIS, npc_types.CHA, npc_types.MR, npc_types.CR, npc_types.DR, " "npc_types.FR, npc_types.PR, npc_types.Corrup, npc_types.PhR," "npc_types.mindmg, npc_types.maxdmg, npc_types.attack_count, npc_types.special_abilities," - "npc_types.npc_spells_id, npc_types.npc_spells_effects_id, npc_types.d_meele_texture1," - "npc_types.d_meele_texture2, npc_types.ammo_idfile, npc_types.prim_melee_type," + "npc_types.npc_spells_id, npc_types.npc_spells_effects_id, npc_types.d_melee_texture1," + "npc_types.d_melee_texture2, npc_types.ammo_idfile, npc_types.prim_melee_type," "npc_types.sec_melee_type, npc_types.ranged_type, npc_types.runspeed, npc_types.findable," "npc_types.trackable, npc_types.hp_regen_rate, npc_types.mana_regen_rate, " "npc_types.aggroradius, npc_types.assistradius, npc_types.bodytype, npc_types.npc_faction_id, " @@ -1796,88 +1797,86 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { tmpNPCType->gender = atoi(row[7]); tmpNPCType->texture = atoi(row[8]); tmpNPCType->helmtexture = atoi(row[9]); - tmpNPCType->size = atof(row[10]); - tmpNPCType->loottable_id = atoi(row[11]); - tmpNPCType->merchanttype = atoi(row[12]); - tmpNPCType->alt_currency_type = atoi(row[13]); - tmpNPCType->adventure_template = atoi(row[14]); - tmpNPCType->trap_template = atoi(row[15]); - tmpNPCType->attack_speed = atof(row[16]); - tmpNPCType->STR = atoi(row[17]); - tmpNPCType->STA = atoi(row[18]); - tmpNPCType->DEX = atoi(row[19]); - tmpNPCType->AGI = atoi(row[20]); - tmpNPCType->INT = atoi(row[21]); - tmpNPCType->WIS = atoi(row[22]); - tmpNPCType->CHA = atoi(row[23]); - tmpNPCType->MR = atoi(row[24]); - tmpNPCType->CR = atoi(row[25]); - tmpNPCType->DR = atoi(row[26]); - tmpNPCType->FR = atoi(row[27]); - tmpNPCType->PR = atoi(row[28]); - tmpNPCType->Corrup = atoi(row[29]); - tmpNPCType->PhR = atoi(row[30]); - tmpNPCType->min_dmg = atoi(row[31]); - tmpNPCType->max_dmg = atoi(row[32]); - tmpNPCType->attack_count = atoi(row[33]); + tmpNPCType->herosforgemodel = atoul(row[10]); + tmpNPCType->size = atof(row[11]); + tmpNPCType->loottable_id = atoi(row[12]); + tmpNPCType->merchanttype = atoi(row[13]); + tmpNPCType->alt_currency_type = atoi(row[14]); + tmpNPCType->adventure_template = atoi(row[15]); + tmpNPCType->trap_template = atoi(row[16]); + tmpNPCType->attack_speed = atof(row[17]); + tmpNPCType->STR = atoi(row[18]); + tmpNPCType->STA = atoi(row[19]); + tmpNPCType->DEX = atoi(row[20]); + tmpNPCType->AGI = atoi(row[21]); + tmpNPCType->INT = atoi(row[22]); + tmpNPCType->WIS = atoi(row[23]); + tmpNPCType->CHA = atoi(row[24]); + tmpNPCType->MR = atoi(row[25]); + tmpNPCType->CR = atoi(row[26]); + tmpNPCType->DR = atoi(row[27]); + tmpNPCType->FR = atoi(row[28]); + tmpNPCType->PR = atoi(row[29]); + tmpNPCType->Corrup = atoi(row[30]); + tmpNPCType->PhR = atoi(row[31]); + tmpNPCType->min_dmg = atoi(row[32]); + tmpNPCType->max_dmg = atoi(row[33]); + tmpNPCType->attack_count = atoi(row[34]); - if (row[34] != nullptr) - strn0cpy(tmpNPCType->special_abilities, row[34], 512); + if (row[35] != nullptr) + strn0cpy(tmpNPCType->special_abilities, row[35], 512); else tmpNPCType->special_abilities[0] = '\0'; - tmpNPCType->npc_spells_id = atoi(row[35]); - tmpNPCType->npc_spells_effects_id = atoi(row[36]); - tmpNPCType->d_meele_texture1 = atoi(row[37]); - tmpNPCType->d_meele_texture2 = atoi(row[38]); - strn0cpy(tmpNPCType->ammo_idfile, row[39], 30); - tmpNPCType->prim_melee_type = atoi(row[40]); - tmpNPCType->sec_melee_type = atoi(row[41]); - tmpNPCType->ranged_type = atoi(row[42]); - tmpNPCType->runspeed= atof(row[43]); - tmpNPCType->findable = atoi(row[44]) == 0? false : true; - tmpNPCType->trackable = atoi(row[45]) == 0? false : true; - tmpNPCType->hp_regen = atoi(row[46]); - tmpNPCType->mana_regen = atoi(row[47]); + tmpNPCType->npc_spells_id = atoi(row[36]); + tmpNPCType->npc_spells_effects_id = atoi(row[37]); + tmpNPCType->d_melee_texture1 = atoi(row[38]); + tmpNPCType->d_melee_texture2 = atoi(row[39]); + strn0cpy(tmpNPCType->ammo_idfile, row[40], 30); + tmpNPCType->prim_melee_type = atoi(row[41]); + tmpNPCType->sec_melee_type = atoi(row[42]); + tmpNPCType->ranged_type = atoi(row[43]); + tmpNPCType->runspeed= atof(row[44]); + tmpNPCType->findable = atoi(row[45]) == 0? false : true; + tmpNPCType->trackable = atoi(row[46]) == 0? false : true; + tmpNPCType->hp_regen = atoi(row[47]); + tmpNPCType->mana_regen = atoi(row[48]); - // set defaultvalue for aggroradius - tmpNPCType->aggroradius = (int32)atoi(row[48]); + // set default value for aggroradius + tmpNPCType->aggroradius = (int32)atoi(row[49]); if (tmpNPCType->aggroradius <= 0) tmpNPCType->aggroradius = 70; - tmpNPCType->assistradius = (int32)atoi(row[49]); + tmpNPCType->assistradius = (int32)atoi(row[50]); if (tmpNPCType->assistradius <= 0) tmpNPCType->assistradius = tmpNPCType->aggroradius; - if (row[50] && strlen(row[50])) - tmpNPCType->bodytype = (uint8)atoi(row[50]); + if (row[51] && strlen(row[51])) + tmpNPCType->bodytype = (uint8)atoi(row[51]); else tmpNPCType->bodytype = 0; - tmpNPCType->npc_faction_id = atoi(row[51]); + tmpNPCType->npc_faction_id = atoi(row[52]); - tmpNPCType->luclinface = atoi(row[52]); - tmpNPCType->hairstyle = atoi(row[53]); - tmpNPCType->haircolor = atoi(row[54]); - tmpNPCType->eyecolor1 = atoi(row[55]); - tmpNPCType->eyecolor2 = atoi(row[56]); - tmpNPCType->beardcolor = atoi(row[57]); - tmpNPCType->beard = atoi(row[58]); - tmpNPCType->drakkin_heritage = atoi(row[59]); - tmpNPCType->drakkin_tattoo = atoi(row[60]); - tmpNPCType->drakkin_details = atoi(row[61]); + tmpNPCType->luclinface = atoi(row[53]); + tmpNPCType->hairstyle = atoi(row[54]); + tmpNPCType->haircolor = atoi(row[55]); + tmpNPCType->eyecolor1 = atoi(row[56]); + tmpNPCType->eyecolor2 = atoi(row[57]); + tmpNPCType->beardcolor = atoi(row[58]); + tmpNPCType->beard = atoi(row[59]); + tmpNPCType->drakkin_heritage = atoi(row[60]); + tmpNPCType->drakkin_tattoo = atoi(row[61]); + tmpNPCType->drakkin_details = atoi(row[62]); - uint32 armor_tint_id = atoi(row[62]); + uint32 armor_tint_id = atoi(row[63]); - tmpNPCType->armor_tint[0] = (atoi(row[63]) & 0xFF) << 16; - tmpNPCType->armor_tint[0] |= (atoi(row[64]) & 0xFF) << 8; - tmpNPCType->armor_tint[0] |= (atoi(row[65]) & 0xFF); + tmpNPCType->armor_tint[0] = (atoi(row[64]) & 0xFF) << 16; + tmpNPCType->armor_tint[0] |= (atoi(row[65]) & 0xFF) << 8; + tmpNPCType->armor_tint[0] |= (atoi(row[66]) & 0xFF); tmpNPCType->armor_tint[0] |= (tmpNPCType->armor_tint[0]) ? (0xFF << 24) : 0; - if (armor_tint_id == 0) - for (int index = MaterialChest; index <= EmuConstants::MATERIAL_END; index++) - tmpNPCType->armor_tint[index] = tmpNPCType->armor_tint[0]; - else if (tmpNPCType->armor_tint[0] == 0) + if (armor_tint_id != 0) { std::string armortint_query = StringFormat("SELECT red1h, grn1h, blu1h, " "red2c, grn2c, blu2c, " @@ -1903,35 +1902,42 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { tmpNPCType->armor_tint[index] |= (tmpNPCType->armor_tint[index]) ? (0xFF << 24) : 0; } } - } else - armor_tint_id = 0; + } + // Try loading npc_types tint fields if armor tint is 0 or query failed to get results + if (armor_tint_id == 0) + { + for (int index = MaterialChest; index < _MaterialCount; index++) + { + tmpNPCType->armor_tint[index] = tmpNPCType->armor_tint[0]; + } + } - tmpNPCType->see_invis = atoi(row[66]); - tmpNPCType->see_invis_undead = atoi(row[67]) == 0? false: true; // Set see_invis_undead flag - if (row[68] != nullptr) - strn0cpy(tmpNPCType->lastname, row[68], 32); + tmpNPCType->see_invis = atoi(row[67]); + tmpNPCType->see_invis_undead = atoi(row[68]) == 0? false: true; // Set see_invis_undead flag + if (row[69] != nullptr) + strn0cpy(tmpNPCType->lastname, row[69], 32); - tmpNPCType->qglobal = atoi(row[69]) == 0? false: true; // qglobal - tmpNPCType->AC = atoi(row[70]); - tmpNPCType->npc_aggro = atoi(row[71]) == 0? false: true; - tmpNPCType->spawn_limit = atoi(row[72]); - tmpNPCType->see_hide = atoi(row[73]) == 0? false: true; - tmpNPCType->see_improved_hide = atoi(row[74]) == 0? false: true; - tmpNPCType->ATK = atoi(row[75]); - tmpNPCType->accuracy_rating = atoi(row[76]); - tmpNPCType->avoidance_rating = atoi(row[77]); - tmpNPCType->slow_mitigation = atoi(row[78]); - tmpNPCType->maxlevel = atoi(row[79]); - tmpNPCType->scalerate = atoi(row[80]); - tmpNPCType->private_corpse = atoi(row[81]) == 1 ? true: false; - tmpNPCType->unique_spawn_by_name = atoi(row[82]) == 1 ? true: false; - tmpNPCType->underwater = atoi(row[83]) == 1 ? true: false; - tmpNPCType->emoteid = atoi(row[84]); - tmpNPCType->spellscale = atoi(row[85]); - tmpNPCType->healscale = atoi(row[86]); - tmpNPCType->no_target_hotkey = atoi(row[87]) == 1 ? true: false; - tmpNPCType->raid_target = atoi(row[88]) == 0 ? false: true; - tmpNPCType->attack_delay = atoi(row[89]); + tmpNPCType->qglobal = atoi(row[70]) == 0? false: true; // qglobal + tmpNPCType->AC = atoi(row[71]); + tmpNPCType->npc_aggro = atoi(row[72]) == 0? false: true; + tmpNPCType->spawn_limit = atoi(row[73]); + tmpNPCType->see_hide = atoi(row[74]) == 0? false: true; + tmpNPCType->see_improved_hide = atoi(row[75]) == 0? false: true; + tmpNPCType->ATK = atoi(row[76]); + tmpNPCType->accuracy_rating = atoi(row[77]); + tmpNPCType->avoidance_rating = atoi(row[78]); + tmpNPCType->slow_mitigation = atoi(row[79]); + tmpNPCType->maxlevel = atoi(row[80]); + tmpNPCType->scalerate = atoi(row[81]); + tmpNPCType->private_corpse = atoi(row[82]) == 1 ? true: false; + tmpNPCType->unique_spawn_by_name = atoi(row[83]) == 1 ? true: false; + tmpNPCType->underwater = atoi(row[84]) == 1 ? true: false; + tmpNPCType->emoteid = atoi(row[85]); + tmpNPCType->spellscale = atoi(row[86]); + tmpNPCType->healscale = atoi(row[87]); + tmpNPCType->no_target_hotkey = atoi(row[88]) == 1 ? true: false; + tmpNPCType->raid_target = atoi(row[89]) == 0 ? false: true; + tmpNPCType->attack_delay = atoi(row[90]); // If NPC with duplicate NPC id already in table, // free item we attempted to add. @@ -1953,39 +1959,81 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client //need to save based on merc_npc_type & client level uint32 merc_type_id = id * 100 + clientlevel; - // If NPC is already in tree, return it. + // If Merc is already in tree, return it. auto itr = zone->merctable.find(merc_type_id); if(itr != zone->merctable.end()) return itr->second; - //If the NPC type is 0, return nullptr. (sanity check) + //If the id is 0, return nullptr. (sanity check) if(id == 0) return nullptr; - // Otherwise, get NPCs from database. - // If id is 0, load all npc_types for the current zone, - // according to spawn2. - std::string query = StringFormat("SELECT vwMercNpcTypes.merc_npc_type_id, vwMercNpcTypes.name, " - "vwMercNpcTypes.level, vwMercNpcTypes.race_id, vwMercNpcTypes.class_id, " - "vwMercNpcTypes.hp, vwMercNpcTypes.mana, vwMercNpcTypes.gender, " - "vwMercNpcTypes.texture, vwMercNpcTypes.helmtexture, vwMercNpcTypes.attack_speed, " - "vwMercNpcTypes.STR, vwMercNpcTypes.STA, vwMercNpcTypes.DEX, vwMercNpcTypes.AGI, " - "vwMercNpcTypes._INT, vwMercNpcTypes.WIS, vwMercNpcTypes.CHA, vwMercNpcTypes.MR, " - "vwMercNpcTypes.CR, vwMercNpcTypes.DR, vwMercNpcTypes.FR, vwMercNpcTypes.PR, " - "vwMercNpcTypes.Corrup, vwMercNpcTypes.mindmg, vwMercNpcTypes.maxdmg, " - "vwMercNpcTypes.attack_count, vwMercNpcTypes.special_abilities, " - "vwMercNpcTypes.d_meele_texture1, vwMercNpcTypes.d_meele_texture2, " - "vwMercNpcTypes.prim_melee_type, vwMercNpcTypes.sec_melee_type, " - "vwMercNpcTypes.runspeed, vwMercNpcTypes.hp_regen_rate, vwMercNpcTypes.mana_regen_rate, " - "vwMercNpcTypes.bodytype, vwMercNpcTypes.armortint_id, " - "vwMercNpcTypes.armortint_red, vwMercNpcTypes.armortint_green, vwMercNpcTypes.armortint_blue, " - "vwMercNpcTypes.AC, vwMercNpcTypes.ATK, vwMercNpcTypes.Accuracy, vwMercNpcTypes.spellscale, " - "vwMercNpcTypes.healscale FROM vwMercNpcTypes " - "WHERE merc_npc_type_id = %d AND clientlevel = %d AND race_id = %d", - id, clientlevel, raceid); //dual primary keys. one is ID, one is level. + // Otherwise, load Merc data on demand + std::string query = StringFormat("SELECT " + "m_stats.merc_npc_type_id, " + "'' AS name, " + "m_stats.level, " + "m_types.race_id, " + "m_subtypes.class_id, " + "m_stats.hp, " + "m_stats.mana, " + "0 AS gender, " + "m_armorinfo.texture, " + "m_armorinfo.helmtexture, " + "m_stats.attack_speed, " + "m_stats.STR, " + "m_stats.STA, " + "m_stats.DEX, " + "m_stats.AGI, " + "m_stats._INT, " + "m_stats.WIS, " + "m_stats.CHA, " + "m_stats.MR, " + "m_stats.CR, " + "m_stats.DR, " + "m_stats.FR, " + "m_stats.PR, " + "m_stats.Corrup, " + "m_stats.mindmg, " + "m_stats.maxdmg, " + "m_stats.attack_count, " + "m_stats.special_abilities, " + "m_weaponinfo.d_melee_texture1, " + "m_weaponinfo.d_melee_texture2, " + "m_weaponinfo.prim_melee_type, " + "m_weaponinfo.sec_melee_type, " + "m_stats.runspeed, " + "m_stats.hp_regen_rate, " + "m_stats.mana_regen_rate, " + "1 AS bodytype, " + "m_armorinfo.armortint_id, " + "m_armorinfo.armortint_red, " + "m_armorinfo.armortint_green, " + "m_armorinfo.armortint_blue, " + "m_stats.AC, " + "m_stats.ATK, " + "m_stats.Accuracy, " + "m_stats.spellscale, " + "m_stats.healscale " + "FROM merc_stats m_stats " + "INNER JOIN merc_armorinfo m_armorinfo " + "ON m_stats.merc_npc_type_id = m_armorinfo.merc_npc_type_id " + "AND m_armorinfo.minlevel <= m_stats.level AND m_armorinfo.maxlevel >= m_stats.level " + "INNER JOIN merc_weaponinfo m_weaponinfo " + "ON m_stats.merc_npc_type_id = m_weaponinfo.merc_npc_type_id " + "AND m_weaponinfo.minlevel <= m_stats.level AND m_weaponinfo.maxlevel >= m_stats.level " + "INNER JOIN merc_templates m_templates " + "ON m_templates.merc_npc_type_id = m_stats.merc_npc_type_id " + "INNER JOIN merc_types m_types " + "ON m_templates.merc_type_id = m_types.merc_type_id " + "INNER JOIN merc_subtypes m_subtypes " + "ON m_templates.merc_subtype_id = m_subtypes.merc_subtype_id " + "WHERE m_templates.merc_npc_type_id = %d AND m_stats.clientlevel = %d AND m_types.race_id = %d", + id, clientlevel, raceid); //dual primary keys. one is ID, one is level. + auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error loading NPCs from database. Bad query: " << results.ErrorMessage() << std::endl; + std::cerr << "Error loading Mercenaries from database. Bad query: " << results.ErrorMessage() << std::endl; return nullptr; } @@ -2033,8 +2081,8 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client else tmpNPCType->special_abilities[0] = '\0'; - tmpNPCType->d_meele_texture1 = atoi(row[28]); - tmpNPCType->d_meele_texture2 = atoi(row[29]); + tmpNPCType->d_melee_texture1 = atoi(row[28]); + tmpNPCType->d_melee_texture2 = atoi(row[29]); tmpNPCType->prim_melee_type = atoi(row[30]); tmpNPCType->sec_melee_type = atoi(row[31]); tmpNPCType->runspeed= atof(row[32]); @@ -2091,16 +2139,16 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client tmpNPCType->accuracy_rating = atoi(row[42]); tmpNPCType->scalerate = RuleI(Mercs, ScaleRate); tmpNPCType->spellscale = atoi(row[43]); - tmpNPCType->healscale = atoi(row[4]); + tmpNPCType->healscale = atoi(row[44]); - // If NPC with duplicate NPC id already in table, + // If Merc with duplicate NPC id already in table, // free item we attempted to add. - if (zone->merctable.find(tmpNPCType->npc_id * 100 + clientlevel) != zone->merctable.end()) { + if (zone->merctable.find(merc_type_id) != zone->merctable.end()) { delete tmpNPCType; return nullptr; } - zone->merctable[tmpNPCType->npc_id * 100 + clientlevel]=tmpNPCType; + zone->merctable[merc_type_id] = tmpNPCType; npc = tmpNPCType; } @@ -2296,7 +2344,7 @@ void ZoneDatabase::SaveMercBuffs(Merc *merc) { std::string query = StringFormat("DELETE FROM merc_buffs WHERE MercId = %u", merc->GetMercID()); auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error While Deleting Merc Buffs before save: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error While Deleting Merc Buffs before save: %s", results.ErrorMessage().c_str()); return; } @@ -2322,7 +2370,7 @@ void ZoneDatabase::SaveMercBuffs(Merc *merc) { buffs[buffCount].caston_z, buffs[buffCount].ExtraDIChance); results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error Saving Merc Buffs: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error Saving Merc Buffs: %s", results.ErrorMessage().c_str()); break; } } @@ -2341,7 +2389,7 @@ void ZoneDatabase::LoadMercBuffs(Merc *merc) { merc->GetMercID()); auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error Loading Merc Buffs: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error Loading Merc Buffs: %s", results.ErrorMessage().c_str()); return; } @@ -2386,7 +2434,7 @@ void ZoneDatabase::LoadMercBuffs(Merc *merc) { query = StringFormat("DELETE FROM merc_buffs WHERE MercId = %u", merc->GetMercID()); results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "Error Loading Merc Buffs: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error Loading Merc Buffs: %s", results.ErrorMessage().c_str()); } @@ -2402,14 +2450,14 @@ bool ZoneDatabase::DeleteMerc(uint32 merc_id) { auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error Deleting Merc Buffs: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error Deleting Merc Buffs: %s", results.ErrorMessage().c_str()); } query = StringFormat("DELETE FROM mercs WHERE MercID = '%u'", merc_id); results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error Deleting Merc: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error Deleting Merc: %s", results.ErrorMessage().c_str()); return false; } @@ -2427,7 +2475,7 @@ void ZoneDatabase::LoadMercEquipment(Merc *merc) { merc->GetLevel(), merc->GetLevel()); auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error Loading Merc Inventory: %s", results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error Loading Merc Inventory: %s", results.ErrorMessage().c_str()); return; } @@ -2602,7 +2650,7 @@ uint8 ZoneDatabase::GroupCount(uint32 groupid) { std::string query = StringFormat("SELECT count(charid) FROM group_id WHERE groupid = %d", groupid); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::GroupCount query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::GroupCount query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -2621,7 +2669,7 @@ uint8 ZoneDatabase::RaidGroupCount(uint32 raidid, uint32 groupid) { auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::RaidGroupCount query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::RaidGroupCount query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -2652,7 +2700,7 @@ int32 ZoneDatabase::GetBlockedSpellsCount(uint32 zoneid) bool ZoneDatabase::LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked* into, uint32 zoneid) { - LogFile->write(EQEMuLog::Status, "Loading Blocked Spells from database..."); + LogFile->write(EQEmuLog::Status, "Loading Blocked Spells from database..."); std::string query = StringFormat("SELECT id, spellid, type, x, y, z, x_diff, y_diff, z_diff, message " "FROM blocked_spells WHERE zoneid = %d ORDER BY id ASC", zoneid); @@ -2777,7 +2825,7 @@ void ZoneDatabase::LoadAltCurrencyValues(uint32 char_id, std::mapwrite(EQEMuLog::Error, "Error in LoadAltCurrencyValues query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadAltCurrencyValues query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -2818,7 +2866,7 @@ void ZoneDatabase::SaveBuffs(Client *client) { buffs[index].ExtraDIChance); auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error in SaveBuffs query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in SaveBuffs query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); } } @@ -2837,7 +2885,7 @@ void ZoneDatabase::LoadBuffs(Client *client) { "FROM `character_buffs` WHERE `character_id` = '%u'", client->CharacterID()); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadBuffs query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadBuffs query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -3011,7 +3059,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) { "WHERE `char_id` = %u", client->CharacterID()); auto results = database.QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -3039,7 +3087,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) { "WHERE `char_id` = %u", client->CharacterID()); results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -3080,7 +3128,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) { "WHERE `char_id`=%u",client->CharacterID()); results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return; } @@ -3688,7 +3736,7 @@ Corpse* ZoneDatabase::SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_z corpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); corpse->Spawn(); if (!UnburyCharacterCorpse(corpse->GetCorpseDBID(), dest_zone_id, dest_instance_id, position)) - LogFile->write(EQEMuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id); + LogFile->write(EQEmuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id); } return corpse; @@ -3727,7 +3775,7 @@ bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id ++CorpseCount; } else{ - LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse for character id %u.", char_id); + LogFile->write(EQEmuLog::Error, "Unable to construct a player corpse for character id %u.", char_id); } } @@ -3844,4 +3892,3 @@ bool ZoneDatabase::DeleteCharacterCorpse(uint32 db_id) { return false; } - diff --git a/zone/zonedump.h b/zone/zonedump.h index deebf9b19..3dd6d4569 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -49,6 +49,7 @@ struct NPCType uint32 npc_id; uint8 texture; uint8 helmtexture; + uint32 herosforgemodel; uint32 loottable_id; uint32 npc_spells_id; uint32 npc_spells_effects_id; @@ -90,8 +91,8 @@ struct NPCType uint32 max_dmg; int16 attack_count; char special_abilities[512]; - uint16 d_meele_texture1; - uint16 d_meele_texture2; + uint16 d_melee_texture1; + uint16 d_melee_texture2; char ammo_idfile[30]; uint8 prim_melee_type; uint8 sec_melee_type; diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 9344c9f51..f50c6b798 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -43,12 +43,12 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { zoning = true; if (app->size != sizeof(ZoneChange_Struct)) { - LogFile->write(EQEMuLog::Debug, "Wrong size: OP_ZoneChange, size=%d, expected %d", app->size, sizeof(ZoneChange_Struct)); + LogFile->write(EQEmuLog::Debug, "Wrong size: OP_ZoneChange, size=%d, expected %d", app->size, sizeof(ZoneChange_Struct)); return; } #if EQDEBUG >= 5 - LogFile->write(EQEMuLog::Debug, "Zone request from %s", GetName()); + LogFile->write(EQEmuLog::Debug, "Zone request from %s", GetName()); DumpPacket(app); #endif ZoneChange_Struct* zc=(ZoneChange_Struct*)app->pBuffer; @@ -96,7 +96,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { CheatDetected(MQZone, zc->x, zc->y, zc->z); Message(13, "Invalid unsolicited zone request."); - LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); + LogFile->write(EQEmuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); SendZoneCancel(zc); return; } @@ -128,7 +128,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //if we didnt get a zone point, or its to a different zone, //then we assume this is invalid. if(!zone_point || zone_point->target_zone_id != target_zone_id) { - LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); + LogFile->write(EQEmuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); CheatDetected(MQGate, zc->x, zc->y, zc->z); SendZoneCancel(zc); return; @@ -159,7 +159,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { if(target_zone_name == nullptr) { //invalid zone... Message(13, "Invalid target zone ID."); - LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get zone name for zone id '%d'.", GetName(), target_zone_id); + LogFile->write(EQEmuLog::Error, "Zoning %s: Unable to get zone name for zone id '%d'.", GetName(), target_zone_id); SendZoneCancel(zc); return; } @@ -172,7 +172,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { if(!database.GetSafePoints(target_zone_name, database.GetInstanceVersion(target_instance_id), &safe_x, &safe_y, &safe_z, &minstatus, &minlevel, flag_needed)) { //invalid zone... Message(13, "Invalid target zone while getting safe points."); - LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get safe coordinates for zone '%s'.", GetName(), target_zone_name); + LogFile->write(EQEmuLog::Error, "Zoning %s: Unable to get safe coordinates for zone '%s'.", GetName(), target_zone_name); SendZoneCancel(zc); return; } @@ -192,7 +192,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { switch(zone_mode) { case EvacToSafeCoords: case ZoneToSafeCoords: - LogFile->write(EQEMuLog::Debug, "Zoning %s to safe coords (%f,%f,%f) in %s (%d)", GetName(), safe_x, safe_y, safe_z, target_zone_name, target_zone_id); + LogFile->write(EQEmuLog::Debug, "Zoning %s to safe coords (%f,%f,%f) in %s (%d)", GetName(), safe_x, safe_y, safe_z, target_zone_name, target_zone_id); dest_x = safe_x; dest_y = safe_y; dest_z = safe_z; @@ -252,7 +252,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //could not find a valid reason for them to be zoning, stop it. CheatDetected(MQZoneUnknownDest, 0.0, 0.0, 0.0); - LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name); + LogFile->write(EQEmuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name); SendZoneCancel(zc); return; default: @@ -287,7 +287,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //we have successfully zoned DoZoneSuccess(zc, target_zone_id, target_instance_id, dest_x, dest_y, dest_z, dest_h, ignorerestrictions); } else { - LogFile->write(EQEMuLog::Error, "Zoning %s: Rules prevent this char from zoning into '%s'", GetName(), target_zone_name); + LogFile->write(EQEmuLog::Error, "Zoning %s: Rules prevent this char from zoning into '%s'", GetName(), target_zone_name); SendZoneError(zc, myerror); } } @@ -311,7 +311,7 @@ void Client::SendZoneCancel(ZoneChange_Struct *zc) { void Client::SendZoneError(ZoneChange_Struct *zc, int8 err) { - LogFile->write(EQEMuLog::Error, "Zone %i is not available because target wasn't found or character insufficent level", zc->zoneID); + LogFile->write(EQEmuLog::Error, "Zone %i is not available because target wasn't found or character insufficent level", zc->zoneID); SetPortExemption(true); @@ -346,7 +346,7 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc if(this->GetPet()) entity_list.RemoveFromHateLists(this->GetPet()); - LogFile->write(EQEMuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f", m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id, dest_x, dest_y, dest_z); + LogFile->write(EQEmuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f", m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id, dest_x, dest_y, dest_z); //set the player's coordinates in the new zone so they have them //when they zone into it @@ -469,7 +469,7 @@ void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, ZonePC(zoneID, instance_id, x, y, z, heading, ignorerestrictions, zm); break; default: - LogFile->write(EQEMuLog::Error, "Client::ProcessMovePC received a reguest to perform an unsupported client zone operation."); + LogFile->write(EQEmuLog::Error, "Client::ProcessMovePC received a reguest to perform an unsupported client zone operation."); break; } } @@ -529,19 +529,19 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z heading = m_pp.binds[0].heading; zonesummon_ignorerestrictions = 1; - LogFile->write(EQEMuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading); + LogFile->write(EQEmuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading); break; case SummonPC: m_ZoneSummonLocation = m_Position = xyz_location(x, y, z); SetHeading(heading); break; case Rewind: - LogFile->write(EQEMuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), m_Position.m_X, m_Position.m_Y, m_Position.m_Z, m_RewindLocation.m_X, m_RewindLocation.m_Y, m_RewindLocation.m_Z, zone->GetShortName()); + LogFile->write(EQEmuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), m_Position.m_X, m_Position.m_Y, m_Position.m_Z, m_RewindLocation.m_X, m_RewindLocation.m_Y, m_RewindLocation.m_Z, zone->GetShortName()); m_ZoneSummonLocation = m_Position = xyz_location(x, y, z); SetHeading(heading); break; default: - LogFile->write(EQEMuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation."); + LogFile->write(EQEmuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation."); ReadyToZone = false; break; } @@ -756,7 +756,7 @@ void Client::SetZoneFlag(uint32 zone_id) { std::string query = StringFormat("INSERT INTO zone_flags (charID,zoneID) VALUES(%d,%d)", CharacterID(), zone_id); auto results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "MySQL Error while trying to set zone flag for %s: %s", GetName(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "MySQL Error while trying to set zone flag for %s: %s", GetName(), results.ErrorMessage().c_str()); } void Client::ClearZoneFlag(uint32 zone_id) { @@ -769,7 +769,7 @@ void Client::ClearZoneFlag(uint32 zone_id) { std::string query = StringFormat("DELETE FROM zone_flags WHERE charID=%d AND zoneID=%d", CharacterID(), zone_id); auto results = database.QueryDatabase(query); if(!results.Success()) - LogFile->write(EQEMuLog::Error, "MySQL Error while trying to clear zone flag for %s: %s", GetName(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "MySQL Error while trying to clear zone flag for %s: %s", GetName(), results.ErrorMessage().c_str()); } @@ -779,7 +779,7 @@ void Client::LoadZoneFlags() { std::string query = StringFormat("SELECT zoneID from zone_flags WHERE charID=%d", CharacterID()); auto results = database.QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "MySQL Error while trying to load zone flags for %s: %s", GetName(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Error, "MySQL Error while trying to load zone flags for %s: %s", GetName(), results.ErrorMessage().c_str()); return; }