From 0aba2d578ac43e37d6c191cf8cb18a2f1417d058 Mon Sep 17 00:00:00 2001 From: Trevius Date: Thu, 29 Jan 2015 23:04:41 -0600 Subject: [PATCH] Added more information to Mercenary Logging. Added potential fix for Mercenaries that fail to unsuspend. Added a new "statscale" field to the merc_stats table that can be used to quickly balance Mercenary Stats based on Level. The new "statscale" field now combines with the Mercs::ScaleRate rule value (default 100 percent for both). --- changelog.txt | 6 + common/database.cpp | 2 +- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../2015_01_29_merc_stats_table_update.sql | 1 + zone/client.cpp | 6 +- zone/client_packet.cpp | 20 +- zone/exp.cpp | 3 +- zone/merc.cpp | 278 +++++++++++++----- zone/merc.h | 4 +- zone/zonedb.cpp | 7 +- 11 files changed, 242 insertions(+), 88 deletions(-) create mode 100644 utils/sql/git/required/2015_01_29_merc_stats_table_update.sql diff --git a/changelog.txt b/changelog.txt index ea5816bde..38cc5f7ce 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 01/29/2015 == +Trevius: Added more information to Mercenary Logging. +Trevius: Added potential fix for Mercenaries that fail to unsuspend. +Trevius: Added a new "statscale" field to the merc_stats table that can be used to quickly balance Mercenary Stats based on Level. +Trevius: The new "statscale" field now combines with the Mercs::ScaleRate rule value (default 100 percent for both). + == 01/28/2015 == Akkadius: Added Logs::DebugQuest category per request from Trevius (Great idea) - Exported quest::debug(log_message, [debug_level = 1) diff --git a/common/database.cpp b/common/database.cpp index 43a08f394..98639c6af 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -1991,7 +1991,7 @@ void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid) if (results.RowsAffected() != 0) return; - query = StringFormat("INSERT INTO raid_leaders(gid, rid, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%lu, %lu, '', '', '', '', '', '', 0)", + query = StringFormat("REPLACE INTO raid_leaders(gid, rid, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%lu, %lu, '', '', '', '', '', '', 0)", (unsigned long)gid, (unsigned long)rid); results = QueryDatabase(query); diff --git a/common/version.h b/common/version.h index 33d089998..925292555 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 9070 +#define CURRENT_BINARY_DATABASE_VERSION 9071 #define COMPILE_DATE __DATE__ #define COMPILE_TIME __TIME__ #ifndef WIN32 diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 4a49c09c9..90a67a789 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -324,6 +324,7 @@ 9068|2015_01_15_logsys_categories_table.sql|SHOW TABLES LIKE 'logsys_categories'|empty| 9069|2015_01_25_logsys_Mercenaries_category.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Mercenaries'|empty| 9070|2015_01_28_quest_debug_log_category.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Quest Debug'|empty| +9071|2015_01_29_merc_stats_table_update.sql|SHOW COLUMNS FROM `merc_stats` LIKE 'statscale'|empty| # 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/2015_01_29_merc_stats_table_update.sql b/utils/sql/git/required/2015_01_29_merc_stats_table_update.sql new file mode 100644 index 000000000..9c149b825 --- /dev/null +++ b/utils/sql/git/required/2015_01_29_merc_stats_table_update.sql @@ -0,0 +1 @@ +ALTER TABLE `merc_stats` ADD `statscale` int( 11 ) NOT NULL DEFAULT '100' AFTER `runspeed`; \ No newline at end of file diff --git a/zone/client.cpp b/zone/client.cpp index 504164273..ecc7d7ca7 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7277,7 +7277,7 @@ void Client::SendMercPersonalInfo() stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size(); if(stancecount > MAX_MERC_STANCES || mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES) { - Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo canceled: (%i) (%i) (%i)", stancecount, mercCount, mercTypeCount); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo canceled: (%i) (%i) (%i) for %s", stancecount, mercCount, mercTypeCount, GetName()); SendMercMerchantResponsePacket(0); return; } @@ -7371,13 +7371,13 @@ void Client::SendMercPersonalInfo() return; } } - Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Send Successful"); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Send Successful for %s.", GetName()); SendMercMerchantResponsePacket(0); } else { - Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Send Failed Due to no MercData for %i", GetMercInfo().MercTemplateID); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Send Failed Due to no MercData (%i) for %s", GetMercInfo().MercTemplateID, GetName()); } } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 4d2d0606c..2059c262f 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -9315,7 +9315,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app) uint32 merc_command = mc->MercCommand; // Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 20 (unknown), 36 (zone in with merc) int32 option = mc->Option; // Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance) - Log.Out(Logs::General, Logs::Mercenaries, "Command %i, Option %i received.", merc_command, option); + Log.Out(Logs::General, Logs::Mercenaries, "Command %i, Option %i received from %s.", merc_command, option, GetName()); if (!RuleB(Mercs, AllowMercs)) return; @@ -9349,7 +9349,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app) merc->SetStance(mercTemplate->Stances[option]); GetMercInfo().Stance = mercTemplate->Stances[option]; - Log.Out(Logs::General, Logs::Mercenaries, "Set Stance: %u", merc->GetStance()); + Log.Out(Logs::General, Logs::Mercenaries, "Set Stance: %u for %s (%s)", merc->GetStance(), merc->GetName(), GetName()); } } } @@ -9372,7 +9372,7 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) uint32 merchant_id = mmsr->MercMerchantID; uint32 altCurrentType = 19; - Log.Out(Logs::General, Logs::Mercenaries, "Data Request for Merchant ID (%i)", merchant_id); + Log.Out(Logs::General, Logs::Mercenaries, "Data Request for Merchant ID (%i) for %s.", merchant_id, GetName()); //client is requesting data about currently owned mercenary if (merchant_id == 0) { @@ -9380,12 +9380,12 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) //send info about your current merc(s) if (GetMercInfo().mercid) { - Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Request"); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Request for %s.", GetName()); SendMercPersonalInfo(); } else { - Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Not Sent - MercID (%i)", GetMercInfo().mercid); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Not Sent - MercID (%i) for %s.", GetMercInfo().mercid, GetName()); } } @@ -9498,7 +9498,7 @@ void Client::Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app return; } - Log.Out(Logs::General, Logs::Mercenaries, "Data Update Request Received."); + Log.Out(Logs::General, Logs::Mercenaries, "Data Update Request Received for %s.", GetName()); if (GetMercID()) { @@ -9524,7 +9524,7 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app) Command = VARSTRUCT_DECODE_TYPE(uint8, InBuffer); } - Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Request ( %i ) Received.", Command); + Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Request ( %i ) Received for %s.", Command, GetName()); // Handle the dismiss here... DismissMerc(GetMercInfo().mercid); @@ -9549,7 +9549,7 @@ void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app) uint32 merc_unk1 = mmrq->MercUnk01; uint32 merc_unk2 = mmrq->MercUnk02; - Log.Out(Logs::General, Logs::Mercenaries, "Template ID (%i), Merchant ID (%i), Unknown1 (%i), Unknown2 (%i)", merc_template_id, merchant_id, merc_unk1, merc_unk2); + Log.Out(Logs::General, Logs::Mercenaries, "Template ID (%i), Merchant ID (%i), Unknown1 (%i), Unknown2 (%i), Client: %s", merc_template_id, merchant_id, merc_unk1, merc_unk2, GetName()); //HirePending = true; SetHoTT(0); @@ -9615,7 +9615,7 @@ void Client::Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app) SuspendMercenary_Struct* sm = (SuspendMercenary_Struct*)app->pBuffer; uint32 merc_suspend = sm->SuspendMerc; // Seen 30 for suspending or unsuspending - Log.Out(Logs::General, Logs::Mercenaries, "Suspend ( %i ) received.", merc_suspend); + Log.Out(Logs::General, Logs::Mercenaries, "Suspend ( %i ) received for %s.", merc_suspend, GetName()); if (!RuleB(Mercs, AllowMercs)) return; @@ -9635,7 +9635,7 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app) return; } - Log.Out(Logs::General, Logs::Mercenaries, "Timer Request received."); + Log.Out(Logs::General, Logs::Mercenaries, "Timer Request received for %s.", GetName()); if (!RuleB(Mercs, AllowMercs)) { return; diff --git a/zone/exp.cpp b/zone/exp.cpp index 7eb2189df..7e878206a 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -506,8 +506,7 @@ void Client::SetLevel(uint8 set_level, bool command) SetMana(CalcMaxMana()); UpdateWho(); - if(GetMerc()) - UpdateMercLevel(); + UpdateMercLevel(); Save(); } diff --git a/zone/merc.cpp b/zone/merc.cpp index 01b4fbee7..86225e6ab 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -2242,7 +2242,7 @@ bool Merc::AICastSpell(int8 iChance, int32 iSpellTypes) { if(CheckAETaunt()) { //get AE taunt selectedMercSpell = GetBestMercSpellForAETaunt(this); - Log.Out(Logs::General, Logs::Mercenaries, "AE Taunting"); + Log.Out(Logs::General, Logs::Mercenaries, "%s AE Taunting.", GetName()); } if(selectedMercSpell.spellid == 0 && CheckTaunt()) { @@ -4770,7 +4770,7 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, { merc->SetMercData( merc_template->MercTemplateID ); database.LoadMercEquipment(merc); - merc->UpdateMercStats(c); + merc->UpdateMercStats(c, true); if(updateFromDB) { @@ -4808,6 +4808,7 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, merc->LoadMercSpells(); } + Log.Out(Logs::General, Logs::Mercenaries, "LoadMerc Successful for %s (%s).", merc->GetName(), c->GetName()); return merc; } } @@ -4836,50 +4837,183 @@ void Merc::UpdateMercInfo(Client *c) { c->GetMercInfo().drakkinDetails = drakkin_details; } -void Merc::UpdateMercStats(Client *c) { - if(c->GetMercInfo().MercTemplateID >0) +void Merc::UpdateMercStats(Client *c, bool setmax) { + if(c->GetMercInfo().MercTemplateID > 0) { + Log.Out(Logs::General, Logs::Mercenaries, "Updating Mercenary Stats for %s (%s).", GetName(), c->GetName()); const NPCType* npc_type = database.GetMercType( zone->GetMercTemplate(c->GetMercInfo().MercTemplateID)->MercNPCID, GetRace(), c->GetLevel()); if (npc_type) { - max_hp = (npc_type->max_hp * npc_type->scalerate) / 100; - base_hp = (npc_type->max_hp * npc_type->scalerate) / 100; - max_mana = (npc_type->Mana * npc_type->scalerate) / 100; - base_mana = (npc_type->Mana * npc_type->scalerate) / 100; - hp_regen = (npc_type->hp_regen * npc_type->scalerate) / 100; - mana_regen = (npc_type->mana_regen * npc_type->scalerate) / 100; + max_hp = npc_type->max_hp; + base_hp = npc_type->max_hp; + max_mana = npc_type->Mana; + base_mana = npc_type->Mana; + max_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet + base_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet + hp_regen = npc_type->hp_regen; + mana_regen = npc_type->mana_regen; + max_dmg = npc_type->max_dmg; + min_dmg = npc_type->min_dmg; + + _baseAC = npc_type->AC; + _baseATK = npc_type->ATK; + _baseSTR = npc_type->STR; + _baseSTA = npc_type->STA; + _baseDEX = npc_type->DEX; + _baseAGI = npc_type->AGI; + _baseWIS = npc_type->WIS; + _baseINT = npc_type->INT; + _baseCHA = npc_type->CHA; + _baseATK = npc_type->ATK; + _baseMR = npc_type->MR; + _baseFR = npc_type->FR; + _baseDR = npc_type->DR; + _basePR = npc_type->PR; + _baseCR = npc_type->CR; + _baseCorrup = npc_type->Corrup; + + uint32 scalepercent = (int)(npc_type->scalerate * RuleI(Mercs, ScaleRate) / 100); + + ScaleStats(scalepercent, setmax); + level = npc_type->level; - max_dmg = (npc_type->max_dmg * npc_type->scalerate) / 100; - min_dmg = (npc_type->min_dmg * npc_type->scalerate) / 100; - _baseSTR = (npc_type->STR * npc_type->scalerate) / 100; - _baseSTA = (npc_type->STA * npc_type->scalerate) / 100; - _baseDEX = (npc_type->DEX * npc_type->scalerate) / 100; - _baseAGI = (npc_type->AGI * npc_type->scalerate) / 100; - _baseWIS = (npc_type->WIS * npc_type->scalerate) / 100; - _baseINT = (npc_type->INT * npc_type->scalerate) / 100; - _baseCHA = (npc_type->CHA * npc_type->scalerate) / 100; - _baseATK = (npc_type->ATK * npc_type->scalerate) / 100; - _baseMR = (npc_type->MR * npc_type->scalerate) / 100; - _baseFR = (npc_type->FR * npc_type->scalerate) / 100; - _baseDR = (npc_type->DR * npc_type->scalerate) / 100; - _basePR = (npc_type->PR * npc_type->scalerate) / 100; - _baseCR = (npc_type->CR * npc_type->scalerate) / 100; - _baseCorrup = (npc_type->Corrup * npc_type->scalerate) / 100; - _baseAC = (npc_type->AC * npc_type->scalerate) / 100; - attack_speed = npc_type->attack_speed; attack_count = npc_type->attack_count; + attack_speed = npc_type->attack_speed; spellscale = npc_type->spellscale; healscale = npc_type->healscale; CalcBonuses(); - - CalcMaxEndurance(); CalcMaxHP(); CalcMaxMana(); + CalcMaxEndurance(); } } } +void Merc::ScaleStats(int scalepercent, bool setmax) { + + Log.Out(Logs::General, Logs::Mercenaries, "Scaling Mercenary Stats to %d Percent for %s.", scalepercent, GetName()); + + if (scalepercent <= 0) + return; + + float scalerate = (float)scalepercent / 100.0f; + + if ((int)((float)base_hp * scalerate) > 1) + { + max_hp = (int)((float)base_hp * scalerate); + base_hp = max_hp; + if (setmax) + cur_hp = max_hp; + } + + if (base_mana) + { + max_mana = (int)((float)base_mana * scalerate); + base_mana = max_mana; + if (setmax) + cur_mana = max_mana; + } + + if (base_end) + { + max_end = (int)((float)base_end * scalerate); + base_end = max_end; + if (setmax) + cur_end = max_end; + } + + if (_baseAC) + { + AC = (int)((float)_baseAC * scalerate); + _baseAC = AC; + } + + if (_baseATK) + { + ATK = (int)((float)_baseATK * scalerate); + _baseATK = ATK; + } + + if (_baseSTR) + { + STR = (int)((float)_baseSTR * scalerate); + _baseSTR = STR; + } + if (_baseSTA) + { + STA = (int)((float)_baseSTA * scalerate); + _baseSTA = STA; + } + if (_baseAGI) + { + AGI = (int)((float)_baseAGI * scalerate); + _baseAGI = AGI; + } + if (_baseDEX) + { + DEX = (int)((float)_baseDEX * scalerate); + _baseDEX = DEX; + } + if (_baseINT) + { + INT = (int)((float)_baseINT * scalerate); + _baseINT = INT; + } + if (_baseWIS) + { + WIS = (int)((float)_baseWIS * scalerate); + _baseWIS = WIS; + } + if (_baseCHA) + { + CHA = (int)((float)_baseCHA * scalerate); + _baseCHA = CHA; + } + + if (_baseMR) + { + MR = (int)((float)_baseMR * scalerate); + _baseMR = MR; + } + if (_baseCR) + { + CR = (int)((float)_baseCR * scalerate); + _baseCR = CR; + } + if (_baseDR) + { + DR = (int)((float)_baseDR * scalerate); + _baseDR = DR; + } + if (_baseFR) + { + FR = (int)((float)_baseFR * scalerate); + _baseFR = FR; + } + if (_basePR) + { + PR = (int)((float)_basePR * scalerate); + _basePR = PR; + } + if (_baseCorrup) + { + Corrup = (int)((float)_baseCorrup * scalerate); + _baseCorrup = Corrup; + } + + if (max_dmg) + { + max_dmg = (int)((float)max_dmg * scalerate); + } + if (min_dmg) + { + min_dmg = (int)((float)min_dmg * scalerate); + } + + return; +} + void Merc::UpdateMercAppearance() { // Copied from Bot Code: uint32 itemID = NO_ITEM; @@ -4937,7 +5071,7 @@ bool Merc::Spawn(Client *owner) { SendPosition(); - Log.Out(Logs::General, Logs::Mercenaries, "Spawn Mercenary."); + Log.Out(Logs::General, Logs::Mercenaries, "Spawn Mercenary %s.", GetName()); //UpdateMercAppearance(); @@ -5083,7 +5217,8 @@ void Client::SendMercResponsePackets(uint32 ResponseType) SendMercMerchantResponsePacket(3); break; } - Log.Out(Logs::General, Logs::Mercenaries, "SendMercResponsePackets %i.", ResponseType); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercResponsePackets %i for %s.", ResponseType, GetName()); + } void Client::UpdateMercTimer() @@ -5124,7 +5259,7 @@ void Client::UpdateMercTimer() SendMercResponsePackets(16); } - Log.Out(Logs::General, Logs::Mercenaries, "UpdateMercTimer Complete."); + Log.Out(Logs::General, Logs::Mercenaries, "UpdateMercTimer Complete for %s.", GetName()); // Normal upkeep charge message //Message(7, "You have been charged a mercenary upkeep cost of %i plat, and %i gold and your mercenary upkeep cost timer has been reset to 15 minutes.", upkeep_plat, upkeep_gold, (int)(RuleI(Mercs, UpkeepIntervalMS) / 1000 / 60)); @@ -5177,7 +5312,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) { } } - Log.Out(Logs::General, Logs::Mercenaries, "CheckCanHireMerc True."); + Log.Out(Logs::General, Logs::Mercenaries, "CheckCanHireMerc True for %s.", GetName()); return true; } @@ -5250,7 +5385,7 @@ bool Client::CheckCanSpawnMerc(uint32 template_id) { return false; } - Log.Out(Logs::General, Logs::Mercenaries, "CheckCanSpawnMerc True."); + Log.Out(Logs::General, Logs::Mercenaries, "CheckCanSpawnMerc True for %s.", GetName()); return true; } @@ -5272,7 +5407,7 @@ bool Client::CheckCanUnsuspendMerc() { return false; } - Log.Out(Logs::General, Logs::Mercenaries, "CheckCanUnsuspendMerc True."); + Log.Out(Logs::General, Logs::Mercenaries, "CheckCanUnsuspendMerc True for %s.", GetName()); return true; } @@ -5287,7 +5422,7 @@ void Client::CheckMercSuspendTimer() { GetMercInfo().SuspendedTime = 0; SendMercResponsePackets(0); SendMercSuspendResponsePacket(GetMercInfo().SuspendedTime); - Log.Out(Logs::General, Logs::Mercenaries, "CheckMercSuspendTimer Ready."); + Log.Out(Logs::General, Logs::Mercenaries, "CheckMercSuspendTimer Ready for %s.", GetName()); } } } @@ -5300,7 +5435,7 @@ void Client::SuspendMercCommand() { { if(!CheckCanUnsuspendMerc()) { - Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Unable to Unsuspend."); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Unable to Unsuspend Merc for %s.", GetName()); return; } @@ -5310,13 +5445,13 @@ void Client::SuspendMercCommand() { if(merc) { SpawnMerc(merc, true); - Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Successful Unsuspend."); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Successful Unsuspend for %s.", GetName()); } else { //merc failed to spawn SendMercResponsePackets(3); - Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Failed to Spawn Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Failed to Spawn Merc for %s.", GetName()); } } else @@ -5326,10 +5461,11 @@ void Client::SuspendMercCommand() { if(CurrentMerc && GetMercID()) { CurrentMerc->Suspend(); - Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Successful Suspend."); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Successful Suspend for %s.", GetName()); } else { + // Reset Merc Suspend State GetMercInfo().IsSuspended = true; //GetMercInfo().SuspendedTime = time(nullptr) + RuleI(Mercs, SuspendIntervalS); //GetMercInfo().MercTimerRemaining = GetMercTimer()->GetRemainingTime(); @@ -5337,9 +5473,15 @@ void Client::SuspendMercCommand() { GetMercTimer()->Disable(); SendMercSuspendResponsePacket(GetMercInfo().SuspendedTime); SendMercTimer(nullptr); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Failed to Get Merc to Suspend. Resetting Suspend State for %s.", GetName()); } } } + else + { + SpawnMercOnZone(); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Request Failed to Load Merc for %s. Trying SpawnMercOnZone.", GetName()); + } } @@ -5371,7 +5513,7 @@ void Client::SpawnMercOnZone() { { SpawnMerc(merc, false); } - Log.Out(Logs::General, Logs::Mercenaries, "SpawnMercOnZone Normal Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SpawnMercOnZone Normal Merc for %s.", GetName()); } else { @@ -5387,7 +5529,7 @@ void Client::SpawnMercOnZone() { // Send Mercenary Status/Timer packet SendMercTimer(GetMerc()); - Log.Out(Logs::General, Logs::Mercenaries, "SpawnMercOnZone Suspended Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SpawnMercOnZone Suspended Merc for %s.", GetName()); } } else @@ -5395,6 +5537,7 @@ void Client::SpawnMercOnZone() { // No Merc Hired // RoF+ displays a message from the following packet, which seems useless //SendClearMercInfo(); + Log.Out(Logs::General, Logs::Mercenaries, "SpawnMercOnZone Failed to load Merc Info from the Database for %s.", GetName()); } } @@ -5408,17 +5551,17 @@ void Client::SendMercTimer(Merc* merc) { if (!merc) { SendMercTimerPacket(NO_MERC_ID, MERC_STATE_SUSPENDED, GetMercInfo().SuspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); - Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer No Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer No Merc for %s.", GetName()); } else if (merc->IsSuspended()) { SendMercTimerPacket(NO_MERC_ID, MERC_STATE_SUSPENDED, GetMercInfo().SuspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); - Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer Suspended Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer Suspended Merc for %s.", GetName()); } else { SendMercTimerPacket(merc->GetID(), MERC_STATE_NORMAL, NOT_SUSPENDED_TIME, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); - Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer Normal Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer Normal Merc for %s.", GetName()); } } @@ -5440,7 +5583,7 @@ void Client::SpawnMerc(Merc* merc, bool setMaxStats) { merc->Unsuspend(setMaxStats); merc->SetStance(GetMercInfo().Stance); - Log.Out(Logs::General, Logs::Mercenaries, "SpawnMerc Success."); + Log.Out(Logs::General, Logs::Mercenaries, "SpawnMerc Success for %s.", GetName()); return; @@ -5469,7 +5612,7 @@ bool Merc::Suspend() { // Start the timer to send the packet that refreshes the Unsuspend Button mercOwner->GetPTimers().Start(pTimerMercSuspend, RuleI(Mercs, SuspendIntervalS)); - Log.Out(Logs::General, Logs::Mercenaries, "Suspend Complete."); + Log.Out(Logs::General, Logs::Mercenaries, "Suspend Complete for %s.", mercOwner->GetName()); return true; } @@ -5555,12 +5698,12 @@ bool Client::DismissMerc(uint32 MercID) { bool Dismissed = true; if (!database.DeleteMerc(MercID)) { - Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Failed for MercID %i", MercID); + Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Failed Database Query for MercID: %i, Client: %s.", MercID, GetName()); Dismissed = false; } else { - Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Successful."); + Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Successful for %s.", GetName()); } if (GetMerc()) @@ -5717,13 +5860,13 @@ bool Merc::MercJoinClientGroup() { database.SetGroupLeaderName(g->GetID(), mercOwner->GetName()); database.RefreshGroupFromDB(mercOwner); g->SaveGroupLeaderAA(); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary joined new group."); + Log.Out(Logs::General, Logs::Mercenaries, "Mercenary joined new group: %s (%s).", GetName(), mercOwner->GetName()); } else { g->DisbandGroup(); Suspend(); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary disbanded new group."); + Log.Out(Logs::General, Logs::Mercenaries, "Mercenary disbanded new group: %s (%s).", GetName(), mercOwner->GetName()); } } @@ -5733,12 +5876,12 @@ bool Merc::MercJoinClientGroup() { database.RefreshGroupFromDB(mercOwner); // Update members that are out of zone GetGroup()->SendGroupJoinOOZ(this); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary joined existing group."); + Log.Out(Logs::General, Logs::Mercenaries, "Mercenary %s joined existing group with %s.", GetName(), mercOwner->GetName()); } else { Suspend(); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary failed to join the group - Suspending"); + Log.Out(Logs::General, Logs::Mercenaries, "Mercenary failed to join the group - Suspending %s for (%s).", GetName(), mercOwner->GetName()); } } @@ -5789,7 +5932,7 @@ Merc* Client::GetMerc() { if(GetMercID() == 0) { - Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc 0."); + Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc - GetMercID: 0 for %s.", GetName()); return (nullptr); } @@ -5797,14 +5940,14 @@ Merc* Client::GetMerc() { if(tmp == nullptr) { SetMercID(0); - Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc No Merc."); + Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc No Merc for %s.", GetName()); return (nullptr); } if(tmp->GetOwnerID() != GetID()) { SetMercID(0); - Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc Owner Mismatch."); + Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc Owner Mismatch - OwnerID: %d, ClientID: %d, Client: %s.", tmp->GetOwnerID(), GetID(), GetName()); return (nullptr); } @@ -5822,7 +5965,7 @@ uint8 Client::GetNumMercs() { numMercs++; } } - Log.Out(Logs::General, Logs::Mercenaries, "GetNumMercs %i.", numMercs); + Log.Out(Logs::General, Logs::Mercenaries, "GetNumMercs Number: %i for %s.", numMercs, GetName()); return numMercs; } @@ -5863,7 +6006,7 @@ void Client::SetMerc(Merc* newmerc) { GetMercInfo().Gender = 0; GetMercInfo().State = 0; memset(GetMercInfo().merc_name, 0, 64); - Log.Out(Logs::General, Logs::Mercenaries, "SetMerc No Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SetMerc No Merc for %s.", GetName()); } else { @@ -5880,7 +6023,7 @@ void Client::SetMerc(Merc* newmerc) { GetMercInfo().Gender = newmerc->GetGender(); GetMercInfo().State = newmerc->IsSuspended() ? MERC_STATE_SUSPENDED : MERC_STATE_NORMAL; snprintf(GetMercInfo().merc_name, 64, "%s", newmerc->GetName()); - Log.Out(Logs::General, Logs::Mercenaries, "SetMerc New Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SetMerc New Merc for %s.", GetName()); } } @@ -5888,7 +6031,8 @@ void Client::UpdateMercLevel() { Merc* merc = GetMerc(); if (merc) { - merc->UpdateMercStats(this); + merc->UpdateMercStats(this, false); + merc->SendAppearancePacket(AT_WhoLevel, GetLevel(), true, true); } } @@ -5900,7 +6044,7 @@ void Client::SendMercMerchantResponsePacket(int32 response_type) { MercenaryMerchantResponse_Struct* mmr = (MercenaryMerchantResponse_Struct*)outapp->pBuffer; mmr->ResponseType = response_type; // send specified response type FastQueuePacket(&outapp); - Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercMerchantResponsePacket %i.", response_type); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercMerchantResponsePacket ResponseType: %i, Client: %s.", response_type, GetName()); } } @@ -5909,7 +6053,7 @@ void Client::SendMercenaryUnknownPacket(uint8 type) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryUnknown1, 1); outapp->WriteUInt8(type); FastQueuePacket(&outapp); - Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercenaryUnknownPacket %i.", type); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercenaryUnknownPacket Type: %i, Client: %s.", type, GetName()); } @@ -5918,7 +6062,7 @@ void Client::SendMercenaryUnsuspendPacket(uint8 type) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryUnsuspendResponse, 1); outapp->WriteUInt8(type); FastQueuePacket(&outapp); - Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercenaryUnsuspendPacket %i.", type); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercenaryUnsuspendPacket Type: %i, Client: %s.", type, GetName()); } @@ -5928,7 +6072,7 @@ void Client::SendMercSuspendResponsePacket(uint32 suspended_time) { SuspendMercenaryResponse_Struct* smr = (SuspendMercenaryResponse_Struct*)outapp->pBuffer; smr->SuspendTime = suspended_time; // Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp FastQueuePacket(&outapp); - Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercSuspendResponsePacket %i.", suspended_time); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercSuspendResponsePacket Time: %i, Client: %s.", suspended_time, GetName()); } @@ -5943,7 +6087,7 @@ void Client::SendMercTimerPacket(int32 entity_id, int32 merc_state, int32 suspen mss->UpdateInterval = update_interval; // Seen 900000 - 15 minutes in ms mss->MercUnk01 = unk01; // Seen 180000 - 3 minutes in ms - Used for the unsuspend button refresh timer FastQueuePacket(&outapp); - Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercTimerPacket %i, %i, %i, %i, %i.", entity_id, merc_state, suspended_time, update_interval, unk01); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercTimerPacket EndID: %i, State: %i, SuspendTime: %i, Interval: %i, Unk1: %i, Client: %s.", entity_id, merc_state, suspended_time, update_interval, unk01, GetName()); } @@ -5954,7 +6098,7 @@ void Client::SendMercAssignPacket(uint32 entityID, uint32 unk01, uint32 unk02) { mas->MercUnk01 = unk01; mas->MercUnk02 = unk02; FastQueuePacket(&outapp); - Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercAssignPacket %i, %i, %i.", entityID, unk01, unk02); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercAssignPacket EndID: %i, Unk1: %i, Unk2: %i, Client: %s.", entityID, unk01, unk02, GetName()); } void NPC::LoadMercTypes() { diff --git a/zone/merc.h b/zone/merc.h index 31433a060..82136c15d 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -137,7 +137,7 @@ public: virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, bool updateFromDB = false); void UpdateMercInfo(Client *c); - void UpdateMercStats(Client *c); + void UpdateMercStats(Client *c, bool setmax = false); void UpdateMercAppearance(); virtual void UpdateEquipLightValue(); void AddItem(uint8 slot, uint32 item_id); @@ -189,6 +189,7 @@ public: bool TryHide(); // stat functions + virtual void ScaleStats(int scalepercent, bool setmax = false); virtual void CalcBonuses(); int32 GetEndurance() const {return cur_end;} //This gets our current endurance inline virtual int32 GetAC() const { return AC; } @@ -347,6 +348,7 @@ private: // Private "base stats" Members int32 base_mana; + int32 base_end; int32 _baseAC; uint32 _baseSTR; uint32 _baseSTA; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 362155016..7f80c7b6f 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1996,6 +1996,7 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client "m_stats.AC, " "m_stats.ATK, " "m_stats.Accuracy, " + "m_stats.statscale, " "m_stats.spellscale, " "m_stats.healscale " "FROM merc_stats m_stats " @@ -2119,9 +2120,9 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client tmpNPCType->AC = atoi(row[40]); tmpNPCType->ATK = atoi(row[41]); tmpNPCType->accuracy_rating = atoi(row[42]); - tmpNPCType->scalerate = RuleI(Mercs, ScaleRate); - tmpNPCType->spellscale = atoi(row[43]); - tmpNPCType->healscale = atoi(row[44]); + tmpNPCType->scalerate = atoi(row[43]); + tmpNPCType->spellscale = atoi(row[44]); + tmpNPCType->healscale = atoi(row[45]); // If Merc with duplicate NPC id already in table, // free item we attempted to add.