From ea50543ffad76a7997744961f49bddee31a7ab25 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sat, 1 Apr 2017 23:00:16 -0400 Subject: [PATCH 01/20] First round fix for non NPC-on_NPC action --- zone/mob_ai.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 22664d87b..c44d73c3e 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1326,7 +1326,7 @@ void Mob::AI_Process() { if (m_PlayerState & static_cast(PlayerState::Aggressive)) SendRemovePlayerState(PlayerState::Aggressive); - if(!zone->CanDoCombat() && AI_feign_remember_timer->Check()) { + if(zone->CanDoCombat() && AI_feign_remember_timer->Check()) { // 6/14/06 // Improved Feign Death Memory // check to see if any of our previous feigned targets have gotten up. @@ -1351,7 +1351,7 @@ void Mob::AI_Process() { { //we processed a spell action, so do nothing else. } - else if (!zone->CanDoCombat() && AI_scan_area_timer->Check()) + else if (zone->CanDoCombat() && AI_scan_area_timer->Check()) { /* * This is where NPCs look around to see if they want to attack anybody. From d7dfc18c54090d9ae105c597960d0d96853652da Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 1 Apr 2017 23:16:27 -0500 Subject: [PATCH 02/20] Cleaned up some of the NPC to NPC aggro code, only do aggro checks to other NPC's when the NPC is flagged for it --- changelog.txt | 1 + common/features.h | 3 --- zone/aggro.cpp | 10 ++-------- zone/client.cpp | 2 -- zone/client.h | 2 -- zone/client_process.cpp | 2 -- zone/entity.h | 2 +- zone/mob_ai.cpp | 21 ++++++++------------- 8 files changed, 12 insertions(+), 31 deletions(-) diff --git a/changelog.txt b/changelog.txt index 18d35029e..7386c7602 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 4/1/2017 == +Akkadius: Cleaned up some of the NPC to NPC aggro code, only do aggro checks to other NPC's when the NPC is flagged for it Akkadius: [Performance] Reworked how all log calls are made in the source - Before we used Log.Out, we will now use a macro Log( - Before: Log.Out(Logs::General, Logs::Status, "Importing Spells..."); diff --git a/common/features.h b/common/features.h index 863004666..7e347db6d 100644 --- a/common/features.h +++ b/common/features.h @@ -111,9 +111,6 @@ Zone extensions and features //path to where sql logs should be placed #define SQL_LOG_PATH "sql_logs/" -//New aggro system to reduce overhead. -#define REVERSE_AGGRO - //The highest you can #setskill / #setallskill #define HIGHEST_CAN_SET_SKILL 400 diff --git a/zone/aggro.cpp b/zone/aggro.cpp index f717c3bdf..0e9009072 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -408,25 +408,19 @@ bool Mob::CheckWillAggro(Mob *mob) { return(false); } -Mob* EntityList::AICheckCloseAggro(Mob* sender, float iAggroRange, float iAssistRange) { +Mob* EntityList::AICheckNPCtoNPCAggro(Mob* sender, float iAggroRange, float iAssistRange) { if (!sender || !sender->IsNPC()) return(nullptr); -#ifdef REVERSE_AGGRO - //with reverse aggro, npc->client is checked elsewhere, no need to check again auto it = npc_list.begin(); while (it != npc_list.end()) { -#else - auto it = mob_list.begin(); - while (it != mob_list.end()) { -#endif Mob *mob = it->second; if (sender->CheckWillAggro(mob)) return mob; ++it; } - //LogFile->write(EQEMuLog::Debug, "Check aggro for %s no target.", sender->GetName()); + return nullptr; } diff --git a/zone/client.cpp b/zone/client.cpp index 4173eda76..ca7df4643 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -134,9 +134,7 @@ Client::Client(EQStreamInterface* ieqs) endupkeep_timer(1000), forget_timer(0), autosave_timer(RuleI(Character, AutosaveIntervalS) * 1000), -#ifdef REVERSE_AGGRO client_scan_npc_aggro_timer(RuleI(Aggro, ClientAggroCheckInterval) * 1000), -#endif tribute_timer(Tribute_duration), proximity_timer(ClientProximity_interval), TaskPeriodic_Timer(RuleI(TaskSystem, PeriodicCheckTimer) * 1000), diff --git a/zone/client.h b/zone/client.h index 43af2a841..722df5f10 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1460,9 +1460,7 @@ private: Timer endupkeep_timer; Timer forget_timer; // our 2 min everybody forgets you timer Timer autosave_timer; -#ifdef REVERSE_AGGRO Timer client_scan_npc_aggro_timer; -#endif Timer tribute_timer; Timer proximity_timer; diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 6cadc4be5..130c10c9d 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -614,7 +614,6 @@ bool Client::Process() { } } -#ifdef REVERSE_AGGRO //At this point, we are still connected, everything important has taken //place, now check to see if anybody wants to aggro us. // only if client is not feigned @@ -630,7 +629,6 @@ bool Client::Process() { } Log(Logs::General, Logs::Aggro, "Checking Reverse Aggro (client->npc) scanned_npcs (%i)", npc_scan_count); } -#endif if (client_state != CLIENT_LINKDEAD && (client_state == CLIENT_ERROR || client_state == DISCONNECTED || client_state == CLIENT_KICKED || !eqs->CheckState(ESTABLISHED))) { diff --git a/zone/entity.h b/zone/entity.h index 193a17b8d..2f2237283 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -412,7 +412,7 @@ public: bool LimitCheckName(const char* npc_name); void CheckClientAggro(Client *around); - Mob* AICheckCloseAggro(Mob* sender, float iAggroRange, float iAssistRange); + Mob* AICheckNPCtoNPCAggro(Mob* sender, float iAggroRange, float iAssistRange); int GetHatedCount(Mob *attacker, Mob *exclude); void AIYellForHelp(Mob* sender, Mob* attacker); bool AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint32 iSpellTypes); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index c44d73c3e..3f58a0854 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -479,18 +479,18 @@ void Mob::AI_Start(uint32 iMoveDelay) { AI_movement_timer = std::unique_ptr(new Timer(AImovement_duration)); AI_target_check_timer = std::unique_ptr(new Timer(AItarget_check_duration)); AI_feign_remember_timer = std::unique_ptr(new Timer(AIfeignremember_delay)); - AI_scan_area_timer = std::unique_ptr(new Timer(RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)))); + + if(CastToNPC()->WillAggroNPCs()) + AI_scan_area_timer = std::unique_ptr(new Timer(RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)))); + AI_check_signal_timer = std::unique_ptr(new Timer(AI_check_signal_timer_delay)); -#ifdef REVERSE_AGGRO - if(IsNPC() && !CastToNPC()->WillAggroNPCs()) - AI_scan_area_timer->Disable(); -#endif if (GetAggroRange() == 0) pAggroRange = 70; if (GetAssistRange() == 0) pAssistRange = 70; + hate_list.WipeHateList(); m_Delta = glm::vec4(); @@ -1351,18 +1351,13 @@ void Mob::AI_Process() { { //we processed a spell action, so do nothing else. } - else if (zone->CanDoCombat() && AI_scan_area_timer->Check()) + else if (zone->CanDoCombat() && CastToNPC()->WillAggroNPCs() && AI_scan_area_timer->Check()) { /* - * This is where NPCs look around to see if they want to attack anybody. - * - * if REVERSE_AGGRO is enabled, then this timer is disabled unless they - * have the npc_aggro flag on them, and aggro against clients is checked - * by the clients. - * + * NPC to NPC aggro checking, npc needs npc_aggro flag */ - Mob* temp_target = entity_list.AICheckCloseAggro(this, GetAggroRange(), GetAssistRange()); + Mob* temp_target = entity_list.AICheckNPCtoNPCAggro(this, GetAggroRange(), GetAssistRange()); if (temp_target){ AddToHateList(temp_target); } From 13af1bfe6f4f94ed5dccc85d3f3f8639770856c6 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 2 Apr 2017 05:06:13 -0400 Subject: [PATCH 03/20] Added messages for item equip failures --- common/inventory_profile.cpp | 52 +++++++++++++++++++++++++----------- common/inventory_profile.h | 3 ++- zone/inventory.cpp | 19 +++++++++++-- zone/lua_inventory.cpp | 3 ++- zone/lua_inventory.h | 5 ++++ 5 files changed, 63 insertions(+), 19 deletions(-) diff --git a/common/inventory_profile.cpp b/common/inventory_profile.cpp index 4f245ee58..4f64c7a58 100644 --- a/common/inventory_profile.cpp +++ b/common/inventory_profile.cpp @@ -241,48 +241,70 @@ EQEmu::ItemInstance* EQEmu::InventoryProfile::GetCursorItem() } // Swap items in inventory -bool EQEmu::InventoryProfile::SwapItem(int16 slot_a, int16 slot_b, uint16 race_id, uint8 class_id, uint16 deity_id, uint8 level) +bool EQEmu::InventoryProfile::SwapItem(int16 slot_a, int16 slot_b, SwapItemFailState& fail_state, uint16 race_id, uint8 class_id, uint16 deity_id, uint8 level) { + fail_state = swapInvalid; + // Temp holding areas for a and b ItemInstance* inst_a = GetItem(slot_a); ItemInstance* inst_b = GetItem(slot_b); if (inst_a) { - if (!inst_a->IsSlotAllowed(slot_b)) + if (!inst_a->IsSlotAllowed(slot_b)) { + fail_state = swapNotAllowed; return false; - + } if ((slot_b >= legacy::EQUIPMENT_BEGIN && slot_b <= legacy::EQUIPMENT_END) || slot_b == inventory::slotPowerSource) { auto item_a = inst_a->GetItem(); - if (!item_a) + if (!item_a) { + fail_state = swapNullData; return false; - if (race_id && class_id && !item_a->IsEquipable(race_id, class_id)) + } + if (race_id && class_id && !item_a->IsEquipable(race_id, class_id)) { + fail_state = swapRaceClass; return false; - if (deity_id && item_a->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_a->Deity)) + } + if (deity_id && item_a->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_a->Deity)) { + fail_state = swapDeity; return false; - if (level && item_a->ReqLevel && level < item_a->ReqLevel) + } + if (level && item_a->ReqLevel && level < item_a->ReqLevel) { + fail_state = swapLevel; return false; + } } } if (inst_b) { - if (!inst_b->IsSlotAllowed(slot_a)) + if (!inst_b->IsSlotAllowed(slot_a)) { + fail_state = swapNotAllowed; return false; - + } if ((slot_a >= legacy::EQUIPMENT_BEGIN && slot_a <= legacy::EQUIPMENT_END) || slot_a == inventory::slotPowerSource) { auto item_b = inst_b->GetItem(); - if (!item_b) + if (!item_b) { + fail_state = swapNullData; return false; - if (race_id && class_id && !item_b->IsEquipable(race_id, class_id)) + } + if (race_id && class_id && !item_b->IsEquipable(race_id, class_id)) { + fail_state = swapRaceClass; return false; - if (deity_id && item_b->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_b->Deity)) + } + if (deity_id && item_b->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_b->Deity)) { + fail_state = swapDeity; return false; - if (level && item_b->ReqLevel && level < item_b->ReqLevel) + } + if (level && item_b->ReqLevel && level < item_b->ReqLevel) { + fail_state = swapLevel; return false; + } } } - _PutItem(slot_a, inst_b); // Copy b->a - _PutItem(slot_b, inst_a); // Copy a->b + _PutItem(slot_a, inst_b); // Assign b->a + _PutItem(slot_b, inst_a); // Assign a->b + + fail_state = swapPass; return true; } diff --git a/common/inventory_profile.h b/common/inventory_profile.h index d6d166337..702c92e83 100644 --- a/common/inventory_profile.h +++ b/common/inventory_profile.h @@ -127,7 +127,8 @@ namespace EQEmu ItemInstance* GetCursorItem(); // Swap items in inventory - bool SwapItem(int16 slot_a, int16 slot_b, uint16 race_id = 0, uint8 class_id = 0, uint16 deity_id = 0, uint8 level = 0); + enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel }; + bool SwapItem(int16 slot_a, int16 slot_b, SwapItemFailState& fail_state, uint16 race_id = 0, uint8 class_id = 0, uint16 deity_id = 0, uint8 level = 0); // Remove item from inventory bool DeleteItem(int16 slot_id, uint8 quantity = 0); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index ceaeb282b..42520058c 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1793,7 +1793,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { // Nothing in destination slot: split stack into two if ((int16)move_in->number_in_stack >= src_inst->GetCharges()) { // Move entire stack - if(!m_inv.SwapItem(src_slot_id, dst_slot_id)) { return false; } + EQEmu::InventoryProfile::SwapItemFailState fail_state = EQEmu::InventoryProfile::swapInvalid; + if (!m_inv.SwapItem(src_slot_id, dst_slot_id, fail_state)) { return false; } Log(Logs::Detail, Logs::Inventory, "Move entire stack from %d to %d with stack size %d. Dest empty.", src_slot_id, dst_slot_id, move_in->number_in_stack); } else { @@ -1823,7 +1824,21 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } SetMaterial(dst_slot_id,src_inst->GetItem()->ID); } - if(!m_inv.SwapItem(src_slot_id, dst_slot_id, GetRace(), GetClass(), GetDeity(), GetLevel())) { return false; } + + EQEmu::InventoryProfile::SwapItemFailState fail_state = EQEmu::InventoryProfile::swapInvalid; + if (!m_inv.SwapItem(src_slot_id, dst_slot_id, fail_state, GetRace(), GetClass(), GetDeity(), GetLevel())) { + const char* fail_message = "The selected slot was invalid."; + if (fail_state == EQEmu::InventoryProfile::swapRaceClass || fail_state == EQEmu::InventoryProfile::swapDeity) + fail_message = "Your class, deity and/or race may not equip that item."; + else if (fail_state == EQEmu::InventoryProfile::swapLevel) + fail_message = "You are not sufficient level to use this item."; + + if (fail_message) + Message(CC_Red, "%s", fail_message); + + return false; + } + Log(Logs::Detail, Logs::Inventory, "Moving entire item from slot %d to slot %d", src_slot_id, dst_slot_id); if (src_slot_id <= EQEmu::legacy::EQUIPMENT_END || src_slot_id == EQEmu::inventory::slotPowerSource) { diff --git a/zone/lua_inventory.cpp b/zone/lua_inventory.cpp index 0866eebc5..d29bb435b 100644 --- a/zone/lua_inventory.cpp +++ b/zone/lua_inventory.cpp @@ -40,7 +40,8 @@ int Lua_Inventory::PushCursor(Lua_ItemInst item) { bool Lua_Inventory::SwapItem(int slot_a, int slot_b) { Lua_Safe_Call_Bool(); - return self->SwapItem(slot_a, slot_b); + EQEmu::InventoryProfile::SwapItemFailState fail_state = EQEmu::InventoryProfile::swapInvalid; + return self->SwapItem(slot_a, slot_b, fail_state); } bool Lua_Inventory::DeleteItem(int slot_id) { diff --git a/zone/lua_inventory.h b/zone/lua_inventory.h index baaa5d10f..1e391b4da 100644 --- a/zone/lua_inventory.h +++ b/zone/lua_inventory.h @@ -18,6 +18,11 @@ namespace luabind { luabind::scope lua_register_inventory(); +// This class should be deprecated due to the nature of inventory actions. +// Direct manipulation of the inventory system bypasses the client management +// of database calls and can lead to lost items, duplicated items and/or +// desync'd inventories, if not handled correctly. + class Lua_Inventory : public Lua_Ptr { typedef EQEmu::InventoryProfile NativeType; From 23115ca1778962b82e93ce3090f86f90c7dd0a82 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 2 Apr 2017 15:35:13 -0400 Subject: [PATCH 04/20] Disabled deity checks in item swaps until issue is 100% resolved --- common/deity.h | 5 +++-- common/inventory_profile.cpp | 8 ++++---- zone/inventory.cpp | 4 +++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/common/deity.h b/common/deity.h index fa56a9d8f..f754352a0 100644 --- a/common/deity.h +++ b/common/deity.h @@ -49,7 +49,7 @@ namespace EQEmu }; enum DeityTypeBit : uint32 { - bit_DeityAll = 0x00000000, + bit_DeityNone = 0x00000000, bit_DeityAgnostic = 0x00000001, bit_DeityBertoxxulous = 0x00000002, bit_DeityBrellSirilis = 0x00000004, @@ -66,7 +66,8 @@ namespace EQEmu bit_DeitySolusekRo = 0x00002000, bit_DeityTheTribunal = 0x00004000, bit_DeityTunare = 0x00008000, - bit_DeityVeeshan = 0x00010000 + bit_DeityVeeshan = 0x00010000, + bit_DeityAll = 0xFFFFFFFF }; extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type); diff --git a/common/inventory_profile.cpp b/common/inventory_profile.cpp index 4f64c7a58..7ec73d3f2 100644 --- a/common/inventory_profile.cpp +++ b/common/inventory_profile.cpp @@ -264,10 +264,10 @@ bool EQEmu::InventoryProfile::SwapItem(int16 slot_a, int16 slot_b, SwapItemFailS fail_state = swapRaceClass; return false; } - if (deity_id && item_a->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_a->Deity)) { + /*if (deity_id && item_a->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_a->Deity)) { fail_state = swapDeity; return false; - } + }*/ if (level && item_a->ReqLevel && level < item_a->ReqLevel) { fail_state = swapLevel; return false; @@ -290,10 +290,10 @@ bool EQEmu::InventoryProfile::SwapItem(int16 slot_a, int16 slot_b, SwapItemFailS fail_state = swapRaceClass; return false; } - if (deity_id && item_b->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_b->Deity)) { + /*if (deity_id && item_b->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_b->Deity)) { fail_state = swapDeity; return false; - } + }*/ if (level && item_b->ReqLevel && level < item_b->ReqLevel) { fail_state = swapLevel; return false; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 42520058c..916818166 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1833,8 +1833,10 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { else if (fail_state == EQEmu::InventoryProfile::swapLevel) fail_message = "You are not sufficient level to use this item."; - if (fail_message) + if (fail_message) { Message(CC_Red, "%s", fail_message); + //Log(Logs::General, Logs::Error, "[%s] %s (r:%u, c:%u, d:%u, l:%u)", GetCleanName(), fail_message, GetRace(), GetClass(), GetDeity(), GetLevel()); + } return false; } From 5d9a89dcd1409becbc83dd0d5adf1fee26552f2c Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 2 Apr 2017 16:21:13 -0400 Subject: [PATCH 05/20] Damn base values... --- common/inventory_profile.cpp | 8 ++++---- zone/inventory.cpp | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/common/inventory_profile.cpp b/common/inventory_profile.cpp index 7ec73d3f2..4f64c7a58 100644 --- a/common/inventory_profile.cpp +++ b/common/inventory_profile.cpp @@ -264,10 +264,10 @@ bool EQEmu::InventoryProfile::SwapItem(int16 slot_a, int16 slot_b, SwapItemFailS fail_state = swapRaceClass; return false; } - /*if (deity_id && item_a->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_a->Deity)) { + if (deity_id && item_a->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_a->Deity)) { fail_state = swapDeity; return false; - }*/ + } if (level && item_a->ReqLevel && level < item_a->ReqLevel) { fail_state = swapLevel; return false; @@ -290,10 +290,10 @@ bool EQEmu::InventoryProfile::SwapItem(int16 slot_a, int16 slot_b, SwapItemFailS fail_state = swapRaceClass; return false; } - /*if (deity_id && item_b->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_b->Deity)) { + if (deity_id && item_b->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & item_b->Deity)) { fail_state = swapDeity; return false; - }*/ + } if (level && item_b->ReqLevel && level < item_b->ReqLevel) { fail_state = swapLevel; return false; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 916818166..29c2b4cb3 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1826,17 +1826,15 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } EQEmu::InventoryProfile::SwapItemFailState fail_state = EQEmu::InventoryProfile::swapInvalid; - if (!m_inv.SwapItem(src_slot_id, dst_slot_id, fail_state, GetRace(), GetClass(), GetDeity(), GetLevel())) { + if (!m_inv.SwapItem(src_slot_id, dst_slot_id, fail_state, GetBaseRace(), GetBaseClass(), GetDeity(), GetLevel())) { const char* fail_message = "The selected slot was invalid."; if (fail_state == EQEmu::InventoryProfile::swapRaceClass || fail_state == EQEmu::InventoryProfile::swapDeity) fail_message = "Your class, deity and/or race may not equip that item."; else if (fail_state == EQEmu::InventoryProfile::swapLevel) fail_message = "You are not sufficient level to use this item."; - if (fail_message) { + if (fail_message) Message(CC_Red, "%s", fail_message); - //Log(Logs::General, Logs::Error, "[%s] %s (r:%u, c:%u, d:%u, l:%u)", GetCleanName(), fail_message, GetRace(), GetClass(), GetDeity(), GetLevel()); - } return false; } From c3ce0a5df54a95f0cbeeb9ec516ca47e95b6b7d4 Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 3 Apr 2017 21:19:55 -0400 Subject: [PATCH 06/20] Added mob version lookup pointer to class InventoryProfile --- common/inventory_profile.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/common/inventory_profile.h b/common/inventory_profile.h index 702c92e83..5be7ed8d3 100644 --- a/common/inventory_profile.h +++ b/common/inventory_profile.h @@ -85,15 +85,22 @@ namespace EQEmu // Public Methods /////////////////////////////// - InventoryProfile() { m_mob_version = versions::MobVersion::Unknown; m_mob_version_set = false; } + InventoryProfile() { + m_mob_version = versions::MobVersion::Unknown; + m_mob_version_set = false; + m_lookup = inventory::Lookup(versions::MobVersion::Unknown); + } ~InventoryProfile(); bool SetInventoryVersion(versions::MobVersion inventory_version) { if (!m_mob_version_set) { m_mob_version = versions::ValidateMobVersion(inventory_version); - return (m_mob_version_set = true); + m_lookup = inventory::Lookup(m_mob_version); + m_mob_version_set = true; + return true; } else { + m_lookup = inventory::Lookup(versions::MobVersion::Unknown); return false; } } @@ -225,6 +232,7 @@ namespace EQEmu // Active mob version versions::MobVersion m_mob_version; bool m_mob_version_set; + const inventory::LookupEntry* m_lookup; }; } From 75950b0f2bc91ddfa834b5bc4f44ece873511e5b Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 4 Apr 2017 15:00:23 -0400 Subject: [PATCH 07/20] Spell Reflect messages go out to everyone close --- zone/spells.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index f204cde87..4544246a3 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -3781,11 +3781,13 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r default: break; } - if(reflect_chance) { - Message_StringID(MT_Spells, SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName()); + if (reflect_chance) { + entity_list.MessageClose_StringID(this, false, RuleI(Range, SpellMessages), MT_Spells, + SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName()); CheckNumHitsRemaining(NumHit::ReflectSpell); // caster actually appears to change - // ex. During OMM fight you click your reflect mask and you get the recourse from the reflected spell + // ex. During OMM fight you click your reflect mask and you get the recourse from the reflected + // spell spelltar->SpellOnTarget(spell_id, this, true, use_resist_adjust, resist_adjust); safe_delete(action_packet); return false; From 9161921bf0caed53b7dfb9f03be467f91d1a3db8 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 4 Apr 2017 22:07:25 -0500 Subject: [PATCH 08/20] Fix for Loginserver log messages --- common/eqemu_logsys.cpp | 9 +++++++++ loginserver/main.cpp | 1 + zone/mob_ai.cpp | 2 ++ 3 files changed, 12 insertions(+) diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index 78a26c5dc..f3bbe2527 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -104,6 +104,15 @@ void EQEmuLogSys::LoadLogSettingsDefaults() log_settings[Logs::MySQLError].log_to_console = Logs::General; log_settings[Logs::Login_Server].log_to_console = Logs::General; + /* Set Category enabled status on defaults */ + log_settings[Logs::World_Server].is_category_enabled = 1; + log_settings[Logs::Zone_Server].is_category_enabled = 1; + log_settings[Logs::QS_Server].is_category_enabled = 1; + log_settings[Logs::UCS_Server].is_category_enabled = 1; + log_settings[Logs::Crash].is_category_enabled = 1; + log_settings[Logs::MySQLError].is_category_enabled = 1; + log_settings[Logs::Login_Server].is_category_enabled = 1; + /* Declare process file names for log writing If there is no process_file_name declared, no log file will be written, simply */ diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 486e47146..d25afde9b 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -45,6 +45,7 @@ int main() LogSys.LoadLogSettingsDefaults(); LogSys.log_settings[Logs::Error].log_to_console = Logs::General; + LogSys.log_settings[Logs::Error].is_category_enabled = 1; Log(Logs::General, Logs::Login_Server, "Logging System Init."); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 3f58a0854..798b5f2bd 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1432,6 +1432,7 @@ void Mob::AI_Process() { } } } + /* Entity has been assigned another entity to follow */ else if (GetFollowID()) { Mob* follow = entity_list.GetMob(GetFollowID()); @@ -1475,6 +1476,7 @@ void Mob::AI_Process() { minLastFightingDelayMoving = 0; maxLastFightingDelayMoving = 0; } + /* All normal NPC pathing */ CastToNPC()->AI_DoMovement(); } } From 4600844336c994dca9eb96abfcbc5891d13d57a9 Mon Sep 17 00:00:00 2001 From: regneq Date: Fri, 7 Apr 2017 19:45:26 -0700 Subject: [PATCH 09/20] Added ignore_despawn column to npc_types to have NPCs ignore the despawn column in spawngroup. --- utils/sql/db_update_manifest.txt | 1 + .../required/2017_04_07_ignore_despawn.sql | 1 + zone/npc.cpp | 1 + zone/npc.h | 3 +++ zone/spawn2.cpp | 26 ++++++++++++++++--- zone/zonedb.cpp | 4 ++- zone/zonedump.h | 1 + 7 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 utils/sql/git/required/2017_04_07_ignore_despawn.sql diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 428fd52c8..ea176f1e0 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -361,6 +361,7 @@ 9105|2017_02_15_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty| 9106|2017_02_26_npc_spells_update_for_bots.sql|SELECT * FROM `npc_spells` WHERE `id` = '701' AND `name` = 'Cleric Bot'|not_empty| 9107|2017_03_09_inventory_version.sql|SHOW TABLES LIKE 'inventory_version'|empty| +9107|2017_04_07_ignore_despawn|SHOW COLUMNS FROM `npc_types` LIKE 'ignore_despawn'|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/2017_04_07_ignore_despawn.sql b/utils/sql/git/required/2017_04_07_ignore_despawn.sql new file mode 100644 index 000000000..0cf264d34 --- /dev/null +++ b/utils/sql/git/required/2017_04_07_ignore_despawn.sql @@ -0,0 +1 @@ +alter table npc_types add column `ignore_despawn` tinyint(2) not null default 0; \ No newline at end of file diff --git a/zone/npc.cpp b/zone/npc.cpp index e47ba402b..324bfe2e9 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -374,6 +374,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if InitializeBuffSlots(); CalcBonuses(); raid_target = d->raid_target; + ignore_despawn = d->ignore_despawn; } NPC::~NPC() diff --git a/zone/npc.h b/zone/npc.h index 015128340..30e54da55 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -417,6 +417,8 @@ public: bool IsRaidTarget() const { return raid_target; }; void ResetHPUpdateTimer() { sendhpupdate_timer.Start(); } + bool IgnoreDespawn() { return ignore_despawn; } + protected: const NPCType* NPCTypedata; @@ -532,6 +534,7 @@ protected: bool raid_target; uint8 probability; + bool ignore_despawn; //NPCs with this set to 1 will ignore the despawn value in spawngroup private: uint32 loottable_id; diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 291ee9bb7..654c5e836 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -208,11 +208,26 @@ bool Spawn2::Process() { } } - if(sg->despawn != 0 && condition_id == 0) - zone->Despawn(spawn2_id); - - if(IsDespawned) + bool ignore_despawn = false; + if (npcthis) + { + ignore_despawn = npcthis->IgnoreDespawn(); + } + + if (ignore_despawn) + { return true; + } + + if (sg->despawn != 0 && condition_id == 0 && !ignore_despawn) + { + zone->Despawn(spawn2_id); + } + + if (IsDespawned) + { + return true; + } currentnpcid = npcid; NPC* npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), FlyMode3); @@ -295,6 +310,9 @@ void Spawn2::ForceDespawn() if(npcthis != nullptr) { + if (npcthis->IgnoreDespawn()) + return; + if(!npcthis->IsEngaged()) { if(sg->despawn == 3 || sg->despawn == 4) diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index dae62340d..aa4cbc846 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1966,7 +1966,8 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load "npc_types.bracertexture, " "npc_types.handtexture, " "npc_types.legtexture, " - "npc_types.feettexture " + "npc_types.feettexture, " + "npc_types.ignore_despawn " "FROM npc_types %s", where_condition.c_str() ); @@ -2141,6 +2142,7 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load temp_npctype_data->handtexture = atoi(row[94]); temp_npctype_data->legtexture = atoi(row[95]); temp_npctype_data->feettexture = atoi(row[96]); + temp_npctype_data->ignore_despawn = atoi(row[97]) == 1 ? true : false; // If NPC with duplicate NPC id already in table, // free item we attempted to add. diff --git a/zone/zonedump.h b/zone/zonedump.h index ef8da2243..359c09ba8 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -132,6 +132,7 @@ struct NPCType uint8 handtexture; uint8 legtexture; uint8 feettexture; + bool ignore_despawn; }; namespace player_lootitem { From 5ff271d5833e3703462095a6bfe46b14d5048f46 Mon Sep 17 00:00:00 2001 From: regneq Date: Fri, 7 Apr 2017 19:49:18 -0700 Subject: [PATCH 10/20] fixed a copy and paste error from previous commit. --- utils/sql/db_update_manifest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index ea176f1e0..e1817acf9 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -361,7 +361,7 @@ 9105|2017_02_15_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty| 9106|2017_02_26_npc_spells_update_for_bots.sql|SELECT * FROM `npc_spells` WHERE `id` = '701' AND `name` = 'Cleric Bot'|not_empty| 9107|2017_03_09_inventory_version.sql|SHOW TABLES LIKE 'inventory_version'|empty| -9107|2017_04_07_ignore_despawn|SHOW COLUMNS FROM `npc_types` LIKE 'ignore_despawn'|empty| +9108|2017_04_07_ignore_despawn|SHOW COLUMNS FROM `npc_types` LIKE 'ignore_despawn'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not From 09f51742997f30da519d396b6e81c345ed688916 Mon Sep 17 00:00:00 2001 From: regneq Date: Fri, 7 Apr 2017 19:54:13 -0700 Subject: [PATCH 11/20] added a missing version number in version.h --- common/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/version.h b/common/version.h index c0c246166..d0a2838a7 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 9107 +#define CURRENT_BINARY_DATABASE_VERSION 9108 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017 #else From 20302781160d5a426fe38e0cd0f4e03a1d2acda9 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 7 Apr 2017 22:09:20 -0500 Subject: [PATCH 12/20] Fix manifest for Robregen [skip ci] --- utils/sql/db_update_manifest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index e1817acf9..6c2d5672c 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -361,7 +361,7 @@ 9105|2017_02_15_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty| 9106|2017_02_26_npc_spells_update_for_bots.sql|SELECT * FROM `npc_spells` WHERE `id` = '701' AND `name` = 'Cleric Bot'|not_empty| 9107|2017_03_09_inventory_version.sql|SHOW TABLES LIKE 'inventory_version'|empty| -9108|2017_04_07_ignore_despawn|SHOW COLUMNS FROM `npc_types` LIKE 'ignore_despawn'|empty| +9108|2017_04_07_ignore_despawn.sql|SHOW COLUMNS FROM `npc_types` LIKE 'ignore_despawn'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not From b4bab425f5b505b2a50cacc3b1a33622e6e26c7f Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 8 Apr 2017 02:06:49 -0400 Subject: [PATCH 13/20] Refactor OP_BeginCast into it's own function --- zone/attack.cpp | 9 +-------- zone/mob.h | 1 + zone/spells.cpp | 42 +++++++++++++++++++++++++----------------- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index c292a0e91..47e082747 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3901,14 +3901,7 @@ void Mob::TrySpellProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData *w Log(Logs::Detail, Logs::Combat, "Spell proc %d procing spell %d (%.2f percent chance)", i, SpellProcs[i].spellID, chance); - auto outapp = new EQApplicationPacket(OP_BeginCast,sizeof(BeginCast_Struct)); - BeginCast_Struct* begincast = (BeginCast_Struct*)outapp->pBuffer; - begincast->caster_id = GetID(); - begincast->spell_id = SpellProcs[i].spellID; - begincast->cast_time = 0; - outapp->priority = 3; - entity_list.QueueCloseClients(this, outapp, false, RuleI(Range, SpellMessages), 0, true); - safe_delete(outapp); + SendBeginCast(SpellProcs[i].spellID, 0); ExecWeaponProc(nullptr, SpellProcs[i].spellID, on, SpellProcs[i].level_override); CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0, SpellProcs[i].base_spellID); diff --git a/zone/mob.h b/zone/mob.h index 81ef7d14a..7e3535a73 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -279,6 +279,7 @@ public: uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0); bool SpellFinished(uint16 spell_id, Mob *target, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, uint16 mana_used = 0, uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1); + void SendBeginCast(uint16 spell_id, uint32 casttime); virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect = false, bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1); virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1); diff --git a/zone/spells.cpp b/zone/spells.cpp index 4544246a3..f7258e1dd 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -477,23 +477,8 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, // now tell the people in the area -- we ALWAYS want to send this, even instant cast spells. // The only time this is skipped is for NPC innate procs and weapon procs. Procs from buffs // oddly still send this. Since those cases don't reach here, we don't need to check them - if (slot != CastingSlot::Discipline) { - auto outapp = new EQApplicationPacket(OP_BeginCast,sizeof(BeginCast_Struct)); - BeginCast_Struct* begincast = (BeginCast_Struct*)outapp->pBuffer; - begincast->caster_id = GetID(); - begincast->spell_id = spell_id; - begincast->cast_time = orgcasttime; // client calculates reduced time by itself - outapp->priority = 3; - entity_list.QueueCloseClients( - this, /* Sender */ - outapp, /* Packet */ - false, /* Ignore Sender */ - RuleI(Range, BeginCast), - 0, /* Skip this Mob */ - true /* Packet ACK */ - ); //IsClient() ? FILTER_PCSPELLS : FILTER_NPCSPELLS); - safe_delete(outapp); - } + if (slot != CastingSlot::Discipline) + SendBeginCast(spell_id, orgcasttime); // cast time is 0, just finish it right now and be done with it if(cast_time == 0) { @@ -536,6 +521,29 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, return(true); } +void Mob::SendBeginCast(uint16 spell_id, uint32 casttime) +{ + auto outapp = new EQApplicationPacket(OP_BeginCast, sizeof(BeginCast_Struct)); + auto begincast = (BeginCast_Struct *)outapp->pBuffer; + + begincast->caster_id = GetID(); + begincast->spell_id = spell_id; + begincast->cast_time = casttime; // client calculates reduced time by itself + + outapp->priority = 3; + + entity_list.QueueCloseClients( + this, /* Sender */ + outapp, /* Packet */ + false, /* Ignore Sender */ + RuleI(Range, BeginCast), + 0, /* Skip this Mob */ + true /* Packet ACK */ + ); //IsClient() ? FILTER_PCSPELLS : FILTER_NPCSPELLS); + + safe_delete(outapp); +} + /* * Some failures should be caught before the spell finishes casting * This is especially helpful to clients when they cast really long things From d36f1159fb8be334933c2fa504c2bda82af6ae76 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 8 Apr 2017 02:07:08 -0400 Subject: [PATCH 14/20] Add SendBeginCast to Lua API --- zone/lua_mob.cpp | 6 ++++++ zone/lua_mob.h | 1 + 2 files changed, 7 insertions(+) diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index e59357ebf..190db1f18 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -823,6 +823,11 @@ bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_use return self->SpellFinished(spell_id, target, static_cast(slot), mana_used, inventory_slot, resist_adjust, proc); } +void Lua_Mob::SendBeginCast(int spell_id, int cast_time) { + Lua_Safe_Call_Void(); + self->SendBeginCast(spell_id, cast_time); +} + void Lua_Mob::SpellEffect(Lua_Mob caster, int spell_id, double partial) { Lua_Safe_Call_Void(); self->SpellEffect(caster, spell_id, static_cast(partial)); @@ -2128,6 +2133,7 @@ luabind::scope lua_register_mob() { .def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int,int,uint32))&Lua_Mob::SpellFinished) .def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int,int,uint32,int))&Lua_Mob::SpellFinished) .def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int,int,uint32,int,bool))&Lua_Mob::SpellFinished) + .def("SendBeginCast", &Lua_Mob::SendBeginCast) .def("SpellEffect", &Lua_Mob::SpellEffect) .def("GetPet", &Lua_Mob::GetPet) .def("GetOwner", &Lua_Mob::GetOwner) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 37bde994a..08502b1a9 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -181,6 +181,7 @@ public: bool SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot); bool SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot, int resist_adjust); bool SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot, int resist_adjust, bool proc); + void SendBeginCast(int spell_id, int cast_time); void SpellEffect(Lua_Mob caster, int spell_id, double partial); Lua_Mob GetPet(); Lua_Mob GetOwner(); From 58e1d9501d5b193e2c49e5bb4abdf2a93ff7aad8 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sat, 8 Apr 2017 21:08:15 -0400 Subject: [PATCH 15/20] Added 'disable_timer' to door objects (used for click once doors) --- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../required/2017_04_08_doors_disable_timer.sql | 1 + zone/CMakeLists.txt | 1 + zone/doors.cpp | 15 +++++++++++---- zone/doors.h | 5 +++++ zone/lua_door.cpp | 10 ++++++++++ zone/lua_door.h | 2 ++ zone/zonedb.cpp | 8 ++++---- zone/zonedb.h | 2 +- zone/zonedump.h | 1 + 11 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 utils/sql/git/required/2017_04_08_doors_disable_timer.sql diff --git a/common/version.h b/common/version.h index d0a2838a7..60ba600e0 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 9108 +#define CURRENT_BINARY_DATABASE_VERSION 9109 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017 #else diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 6c2d5672c..c8894f756 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -362,6 +362,7 @@ 9106|2017_02_26_npc_spells_update_for_bots.sql|SELECT * FROM `npc_spells` WHERE `id` = '701' AND `name` = 'Cleric Bot'|not_empty| 9107|2017_03_09_inventory_version.sql|SHOW TABLES LIKE 'inventory_version'|empty| 9108|2017_04_07_ignore_despawn.sql|SHOW COLUMNS FROM `npc_types` LIKE 'ignore_despawn'|empty| +9109|2017_04_08_doors_disable_timer.sql|SHOW COLUMNS FROM `doors` LIKE 'disable_timer'|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/2017_04_08_doors_disable_timer.sql b/utils/sql/git/required/2017_04_08_doors_disable_timer.sql new file mode 100644 index 000000000..d28e13fd6 --- /dev/null +++ b/utils/sql/git/required/2017_04_08_doors_disable_timer.sql @@ -0,0 +1 @@ +ALTER TABLE `doors` ADD COLUMN `disable_timer` TINYINT(2) NOT NULL DEFAULT '0' AFTER `triggertype`; \ No newline at end of file diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index deadd079e..bec3f0306 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -162,6 +162,7 @@ SET(zone_headers lua_bit.h lua_client.h lua_corpse.h + lua_door.h lua_encounter.h lua_entity.h lua_entity_list.h diff --git a/zone/doors.cpp b/zone/doors.cpp index b2cfede41..489c65c37 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -135,7 +135,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) //door debugging info dump Log(Logs::Detail, Logs::Doors, "%s clicked door %s (dbid %d, eqid %d) at %s", sender->GetName(), door_name, db_id, door_id, to_string(m_Position).c_str()); Log(Logs::Detail, Logs::Doors, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param); - Log(Logs::Detail, Logs::Doors, " size %d, invert %d, dest: %s %s", size, invert_state, dest_zone, to_string(m_Destination).c_str()); + Log(Logs::Detail, Logs::Doors, " disable_timer '%s',size %d, invert %d, dest: %s %s", (disable_timer?"true":"false"), size, invert_state, dest_zone, to_string(m_Destination).c_str()); auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; @@ -354,13 +354,15 @@ void Doors::HandleClick(Client* sender, uint8 trigger) entity_list.QueueClients(sender, outapp, false); if(!IsDoorOpen() || (opentype == 58)) { - close_timer.Start(); + if (!disable_timer) + close_timer.Start(); SetOpenState(true); } else { close_timer.Disable(); - SetOpenState(false); + if (!disable_timer) + SetOpenState(false); } //everything past this point assumes we opened the door @@ -636,7 +638,7 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name std::string query = StringFormat("SELECT id, doorid, zone, name, pos_x, pos_y, pos_z, heading, " "opentype, guild, lockpick, keyitem, nokeyring, triggerdoor, triggertype, " "dest_zone, dest_instance, dest_x, dest_y, dest_z, dest_heading, " - "door_param, invert_state, incline, size, is_ldon_door, client_version_mask " + "door_param, invert_state, incline, size, is_ldon_door, client_version_mask, disable_timer " "FROM doors WHERE zone = '%s' AND (version = %u OR version = -1) " "ORDER BY doorid asc", zone_name, version); auto results = QueryDatabase(query); @@ -686,6 +688,7 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name into[rowIndex].size=atoi(row[24]); into[rowIndex].is_ldon_door=atoi(row[25]); into[rowIndex].client_version_mask = (uint32)strtoul(row[26], nullptr, 10); + into[rowIndex].disable_timer = (atoi(row[27]) ? true : false); } return true; @@ -730,6 +733,10 @@ void Doors::SetSize(uint16 in) { entity_list.RespawnAllDoors(); } +void Doors::SetDisableTimer(bool flag) { + disable_timer = flag; +} + void Doors::CreateDatabaseEntry() { if(database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()) - 1 >= 255) diff --git a/zone/doors.h b/zone/doors.h index 96764534d..093c57e7f 100644 --- a/zone/doors.h +++ b/zone/doors.h @@ -67,6 +67,10 @@ public: void SetDoorName(const char* name); void SetOpenType(uint8 in); void SetSize(uint16 size); + + void SetDisableTimer(bool flag); + bool GetDisableTimer() { return disable_timer; } + void CreateDatabaseEntry(); private: @@ -88,6 +92,7 @@ private: uint16 size; int invert_state; uint32 entity_id; + bool disable_timer; bool isopen; Timer close_timer; //Timer trigger_timer; diff --git a/zone/lua_door.cpp b/zone/lua_door.cpp index 1a16fe364..909294b92 100644 --- a/zone/lua_door.cpp +++ b/zone/lua_door.cpp @@ -111,6 +111,16 @@ uint32 Lua_Door::GetOpenType() { return self->GetOpenType(); } +void Lua_Door::SetDisableTimer(bool flag) { + Lua_Safe_Call_Void(); + self->SetDisableTimer(flag); +} + +bool Lua_Door::GetDisableTimer() { + Lua_Safe_Call_Bool(); + return self->GetDisableTimer(); +} + void Lua_Door::SetLockPick(uint32 pick) { Lua_Safe_Call_Void(); self->SetLockpick(pick); diff --git a/zone/lua_door.h b/zone/lua_door.h index 309dc7f21..f445e48ea 100644 --- a/zone/lua_door.h +++ b/zone/lua_door.h @@ -49,6 +49,8 @@ public: uint32 GetIncline(); void SetOpenType(uint32 type); uint32 GetOpenType(); + void SetDisableTimer(bool flag); + bool GetDisableTimer(); void SetLockPick(uint32 pick); uint32 GetLockPick(); void SetKeyItem(uint32 key); diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index aa4cbc846..d647dcbf7 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -2989,16 +2989,16 @@ void ZoneDatabase::QGlobalPurge() database.QueryDatabase(query); } -void ZoneDatabase::InsertDoor(uint32 ddoordbid, uint16 ddoorid, const char* ddoor_name, const glm::vec4& position, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize){ +void ZoneDatabase::InsertDoor(uint32 ddoordbid, uint16 ddoorid, const char* ddoor_name, const glm::vec4& position, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize, bool ddisabletimer){ std::string query = StringFormat("REPLACE INTO doors (id, doorid, zone, version, name, " "pos_x, pos_y, pos_z, heading, opentype, guild, lockpick, " - "keyitem, door_param, invert_state, incline, size) " + "keyitem, disable_timer, door_param, invert_state, incline, size) " "VALUES('%i', '%i', '%s', '%i', '%s', '%f', '%f', " - "'%f', '%f', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i')", + "'%f', '%f', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i')", ddoordbid, ddoorid, zone->GetShortName(), zone->GetInstanceVersion(), ddoor_name, position.x, position.y, position.z, position.w, - dopentype, dguildid, dlockpick, dkeyitem, ddoor_param, dinvert, dincline, dsize); + dopentype, dguildid, dlockpick, dkeyitem, (ddisabletimer ? 1 : 0), ddoor_param, dinvert, dincline, dsize); QueryDatabase(query); } diff --git a/zone/zonedb.h b/zone/zonedb.h index 46ce825e4..b592be480 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -454,7 +454,7 @@ public: int32 GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version); int32 GetDoorsCountPlusOne(const char *zone_name, int16 version); int32 GetDoorsDBCountPlusOne(const char *zone_name, int16 version); - void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, const glm::vec4& position, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize); + void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, const glm::vec4& position, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize, bool ddisabletimer = false); /* Blocked Spells */ int32 GetBlockedSpellsCount(uint32 zoneid); diff --git a/zone/zonedump.h b/zone/zonedump.h index 359c09ba8..e273d7379 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -202,6 +202,7 @@ struct Door { uint8 nokeyring; uint8 trigger_door; uint8 trigger_type; + bool disable_timer; uint32 door_param; int invert_state; uint16 size; From 6ae2ff2b7596b225ef7ce9cdd373113da2a4840b Mon Sep 17 00:00:00 2001 From: Uleat Date: Sat, 8 Apr 2017 22:35:37 -0400 Subject: [PATCH 16/20] Added `disable_timer` checks to doors override functions --- zone/doors.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/zone/doors.cpp b/zone/doors.cpp index 489c65c37..b2dd3379b 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -459,16 +459,19 @@ void Doors::NPCOpen(NPC* sender, bool alt_mode) if(!alt_mode) { // original function if(!isopen) { - close_timer.Start(); + if (!disable_timer) + close_timer.Start(); isopen=true; } else { close_timer.Disable(); - isopen=false; + if (!disable_timer) + isopen=false; } } else { // alternative function - close_timer.Start(); + if (!disable_timer) + close_timer.Start(); isopen=true; } } @@ -485,16 +488,19 @@ void Doors::ForceOpen(Mob *sender, bool alt_mode) if(!alt_mode) { // original function if(!isopen) { - close_timer.Start(); + if (!disable_timer) + close_timer.Start(); isopen=true; } else { close_timer.Disable(); - isopen=false; + if (!disable_timer) + isopen=false; } } else { // alternative function - close_timer.Start(); + if (!disable_timer) + close_timer.Start(); isopen=true; } } @@ -510,7 +516,8 @@ void Doors::ForceClose(Mob *sender, bool alt_mode) if(!alt_mode) { // original function if(!isopen) { - close_timer.Start(); + if (!disable_timer) + close_timer.Start(); isopen=true; } else { From 11e56e72d0800957368bdb4f5bfbb6999d2c4f36 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sun, 9 Apr 2017 02:16:23 -0400 Subject: [PATCH 17/20] Fix lua killed_merit issue --- zone/lua_general.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index b1a2b9cfe..bc6205c85 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1680,7 +1680,7 @@ luabind::scope lua_register_events() { luabind::value("loot", static_cast(EVENT_LOOT)), luabind::value("zone", static_cast(EVENT_ZONE)), luabind::value("level_up", static_cast(EVENT_LEVEL_UP)), - luabind::value("killed_merit ", static_cast(EVENT_KILLED_MERIT )), + luabind::value("killed_merit", static_cast(EVENT_KILLED_MERIT)), luabind::value("cast_on", static_cast(EVENT_CAST_ON)), luabind::value("task_accepted", static_cast(EVENT_TASK_ACCEPTED)), luabind::value("task_stage_complete", static_cast(EVENT_TASK_STAGE_COMPLETE)), From 421b3bb27777fb3aeade3acf3dedf5a096de982c Mon Sep 17 00:00:00 2001 From: Athrogate Date: Mon, 10 Apr 2017 11:03:36 -0700 Subject: [PATCH 18/20] Graveyards!!! --- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + utils/sql/git/required/2017_04_10_graveyard.sql | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 utils/sql/git/required/2017_04_10_graveyard.sql diff --git a/common/version.h b/common/version.h index 60ba600e0..411493356 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 9109 +#define CURRENT_BINARY_DATABASE_VERSION 9110 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017 #else diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index c8894f756..b4dce6c86 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -363,6 +363,7 @@ 9107|2017_03_09_inventory_version.sql|SHOW TABLES LIKE 'inventory_version'|empty| 9108|2017_04_07_ignore_despawn.sql|SHOW COLUMNS FROM `npc_types` LIKE 'ignore_despawn'|empty| 9109|2017_04_08_doors_disable_timer.sql|SHOW COLUMNS FROM `doors` LIKE 'disable_timer'|empty| +9110|2017_04_10_graveyard.sql|show index from graveyard WHERE key_name = 'zone_id_nonunique'|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/2017_04_10_graveyard.sql b/utils/sql/git/required/2017_04_10_graveyard.sql new file mode 100644 index 000000000..704797b3b --- /dev/null +++ b/utils/sql/git/required/2017_04_10_graveyard.sql @@ -0,0 +1,2 @@ +alter table graveyard drop index zone_id; +create index zone_id_nonunique on graveyard(zone_id); From 08111ac1766ed4a660fb08b772df5dfebff8d69e Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Mon, 10 Apr 2017 14:52:44 -0400 Subject: [PATCH 19/20] Fix door functions --- common/ptimer.h | 3 ++- zone/lua_door.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/common/ptimer.h b/common/ptimer.h index d7398bea3..2232b55b5 100644 --- a/common/ptimer.h +++ b/common/ptimer.h @@ -22,7 +22,8 @@ #include #include -enum { //values for pTimerType +enum : int { //values for pTimerType + pTimerNegativeItemReuse = -1, // these grow down basically, we will have item ID * -1 for the timer ID pTimerStartAdventureTimer = 1, pTimerSurnameChange = 2, pTimerFeignDeath = 3, diff --git a/zone/lua_door.cpp b/zone/lua_door.cpp index 909294b92..1b39d3e54 100644 --- a/zone/lua_door.cpp +++ b/zone/lua_door.cpp @@ -200,6 +200,8 @@ luabind::scope lua_register_door() { .def("GetIncline", (uint32(Lua_Door::*)(void))&Lua_Door::GetIncline) .def("SetOpenType", (void(Lua_Door::*)(uint32))&Lua_Door::SetOpenType) .def("GetOpenType", (uint32(Lua_Door::*)(void))&Lua_Door::GetOpenType) + .def("SetDisableTimer", (void(Lua_Door::*)(bool))&Lua_Door::SetDisableTimer) + .def("GetDisableTimer", (bool(Lua_Door::*)(void))&Lua_Door::GetDisableTimer) .def("SetLockPick", (void(Lua_Door::*)(uint32))&Lua_Door::SetLockPick) .def("GetLockPick", (uint32(Lua_Door::*)(void))&Lua_Door::GetLockPick) .def("SetKeyItem", (void(Lua_Door::*)(uint32))&Lua_Door::SetKeyItem) From b5b6145786c51358847d4cd797272ebcb5cec2b5 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 10 Apr 2017 19:55:17 -0500 Subject: [PATCH 20/20] Fix initialization issues with loading 'disable_timer' from the database for doors --- zone/doors.cpp | 122 ++++++++++++++++++++++++++---------------------- zone/doors.h | 6 +-- zone/entity.cpp | 54 ++++++++++++--------- zone/zonedump.h | 2 +- 4 files changed, 102 insertions(+), 82 deletions(-) diff --git a/zone/doors.cpp b/zone/doors.cpp index b2dd3379b..97aaa1088 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -70,6 +70,8 @@ m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading) is_ldon_door = door->is_ldon_door; client_version_mask = door->client_version_mask; + + disable_timer = (door->disable_timer == 1 ? true : false); } Doors::Doors(const char *dmodel, const glm::vec4& position, uint8 dopentype, uint16 dsize) : @@ -102,6 +104,8 @@ m_Destination(glm::vec4()) is_ldon_door = 0; client_version_mask = 4294967295u; + + disable_timer = 0; } @@ -445,34 +449,34 @@ void Doors::HandleClick(Client* sender, uint8 trigger) void Doors::NPCOpen(NPC* sender, bool alt_mode) { - if(sender) { - if(GetTriggerType() == 255 || GetTriggerDoorID() > 0 || GetLockpick() != 0 || GetKeyItem() != 0 || opentype == 59 || opentype == 58 || !sender->IsNPC()) { // this object isnt triggered or door is locked - NPCs should not open locked doors! + if (sender) { + if (GetTriggerType() == 255 || GetTriggerDoorID() > 0 || GetLockpick() != 0 || GetKeyItem() != 0 || opentype == 59 || opentype == 58 || !sender->IsNPC()) { // this object isnt triggered or door is locked - NPCs should not open locked doors! return; } auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); - MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer; + MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; md->doorid = door_id; md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; - entity_list.QueueCloseClients(sender,outapp,false,200); + entity_list.QueueCloseClients(sender, outapp, false, 200); safe_delete(outapp); - if(!alt_mode) { // original function - if(!isopen) { + if (!alt_mode) { // original function + if (!is_open) { if (!disable_timer) close_timer.Start(); - isopen=true; + is_open = true; } else { close_timer.Disable(); if (!disable_timer) - isopen=false; + is_open = false; } } else { // alternative function if (!disable_timer) close_timer.Start(); - isopen=true; + is_open = true; } } } @@ -480,53 +484,53 @@ void Doors::NPCOpen(NPC* sender, bool alt_mode) void Doors::ForceOpen(Mob *sender, bool alt_mode) { auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); - MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer; + MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; md->doorid = door_id; md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; - entity_list.QueueClients(sender,outapp,false); + entity_list.QueueClients(sender, outapp, false); safe_delete(outapp); - if(!alt_mode) { // original function - if(!isopen) { + if (!alt_mode) { // original function + if (!is_open) { if (!disable_timer) close_timer.Start(); - isopen=true; + is_open = true; } else { close_timer.Disable(); if (!disable_timer) - isopen=false; + is_open = false; } } else { // alternative function if (!disable_timer) close_timer.Start(); - isopen=true; + is_open = true; } } void Doors::ForceClose(Mob *sender, bool alt_mode) { auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); - MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer; + MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; md->doorid = door_id; md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; // change from original (open to close) - entity_list.QueueClients(sender,outapp,false); + entity_list.QueueClients(sender, outapp, false); safe_delete(outapp); - if(!alt_mode) { // original function - if(!isopen) { + if (!alt_mode) { // original function + if (!is_open) { if (!disable_timer) close_timer.Start(); - isopen=true; + is_open = true; } else { close_timer.Disable(); - isopen=false; + is_open = false; } } else { // alternative function - if(isopen) + if (is_open) close_timer.Trigger(); } } @@ -541,14 +545,14 @@ void Doors::ToggleState(Mob *sender) MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer; md->doorid = door_id; - if(!isopen) { + if(!is_open) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; - isopen=true; + is_open=true; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; - isopen=false; + is_open=false; } entity_list.QueueClients(sender,outapp,false); @@ -561,7 +565,7 @@ void Doors::DumpDoor(){ db_id, door_id, zone_name, door_name, to_string(m_Position).c_str()); Log(Logs::General, Logs::None, "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"); + opentype, guild_id, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param, (is_open) ? "open":"closed"); Log(Logs::General, Logs::None, "dest_zone:%s destination:%s ", dest_zone, to_string(m_Destination).c_str()); @@ -641,34 +645,32 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name Log(Logs::General, Logs::Status, "Loading Doors from database..."); -// Door tmpDoor; - std::string query = StringFormat("SELECT id, doorid, zone, name, pos_x, pos_y, pos_z, heading, " - "opentype, guild, lockpick, keyitem, nokeyring, triggerdoor, triggertype, " - "dest_zone, dest_instance, dest_x, dest_y, dest_z, dest_heading, " - "door_param, invert_state, incline, size, is_ldon_door, client_version_mask, disable_timer " - "FROM doors WHERE zone = '%s' AND (version = %u OR version = -1) " - "ORDER BY doorid asc", zone_name, version); + // Door tmpDoor; + std::string query = StringFormat("SELECT id, doorid, zone, name, pos_x, pos_y, pos_z, heading, " + "opentype, guild, lockpick, keyitem, nokeyring, triggerdoor, triggertype, " + "dest_zone, dest_instance, dest_x, dest_y, dest_z, dest_heading, " + "door_param, invert_state, incline, size, is_ldon_door, client_version_mask, disable_timer " + "FROM doors WHERE zone = '%s' AND (version = %u OR version = -1) " + "ORDER BY doorid asc", zone_name, version); auto results = QueryDatabase(query); - if (!results.Success()){ + if (!results.Success()) { return false; } - int32 rowIndex = 0; - for(auto row = results.begin(); row != results.end(); ++row, ++rowIndex) { - if(rowIndex >= iDoorCount) { - std::cerr << "Error, Door Count of " << iDoorCount << " exceeded." << std::endl; - break; - } + int32 rowIndex = 0; + for (auto row = results.begin(); row != results.end(); ++row, ++rowIndex) { + if (rowIndex >= iDoorCount) { + std::cerr << "Error, Door Count of " << iDoorCount << " exceeded." << std::endl; + break; + } - memset(&into[rowIndex], 0, sizeof(Door)); + memset(&into[rowIndex], 0, sizeof(Door)); into[rowIndex].db_id = atoi(row[0]); into[rowIndex].door_id = atoi(row[1]); - Log(Logs::Detail, Logs::Doors, "Door Load: db id: %u, door_id %u", into[rowIndex].db_id, into[rowIndex].door_id); - - strn0cpy(into[rowIndex].zone_name,row[2],32); - strn0cpy(into[rowIndex].door_name,row[3],32); + strn0cpy(into[rowIndex].zone_name, row[2], 32); + strn0cpy(into[rowIndex].door_name, row[3], 32); into[rowIndex].pos_x = (float)atof(row[4]); into[rowIndex].pos_y = (float)atof(row[5]); @@ -685,18 +687,24 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name strn0cpy(into[rowIndex].dest_zone, row[15], 32); into[rowIndex].dest_instance_id = atoi(row[16]); - into[rowIndex].dest_x = (float) atof(row[17]); - into[rowIndex].dest_y = (float) atof(row[18]); - into[rowIndex].dest_z = (float) atof(row[19]); - into[rowIndex].dest_heading = (float) atof(row[20]); - into[rowIndex].door_param=atoi(row[21]); - into[rowIndex].invert_state=atoi(row[22]); - into[rowIndex].incline=atoi(row[23]); - into[rowIndex].size=atoi(row[24]); - into[rowIndex].is_ldon_door=atoi(row[25]); + into[rowIndex].dest_x = (float)atof(row[17]); + into[rowIndex].dest_y = (float)atof(row[18]); + into[rowIndex].dest_z = (float)atof(row[19]); + into[rowIndex].dest_heading = (float)atof(row[20]); + into[rowIndex].door_param = atoi(row[21]); + into[rowIndex].invert_state = atoi(row[22]); + into[rowIndex].incline = atoi(row[23]); + into[rowIndex].size = atoi(row[24]); + into[rowIndex].is_ldon_door = atoi(row[25]); into[rowIndex].client_version_mask = (uint32)strtoul(row[26], nullptr, 10); - into[rowIndex].disable_timer = (atoi(row[27]) ? true : false); - } + into[rowIndex].disable_timer = atoi(row[27]); + + Log(Logs::Detail, Logs::Doors, "Door Load: db id: %u, door_id %u disable_timer: %i", + into[rowIndex].db_id, + into[rowIndex].door_id, + into[rowIndex].disable_timer + ); + } return true; } diff --git a/zone/doors.h b/zone/doors.h index 093c57e7f..80af306b8 100644 --- a/zone/doors.h +++ b/zone/doors.h @@ -32,8 +32,8 @@ public: const glm::vec4& GetPosition() const{ return m_Position; } int GetIncline() { return incline; } bool triggered; - void SetOpenState(bool st) { isopen = st; } - bool IsDoorOpen() { return isopen; } + void SetOpenState(bool st) { is_open = st; } + bool IsDoorOpen() { return is_open; } uint8 GetTriggerDoorID() { return trigger_door; } uint8 GetTriggerType() { return trigger_type; } @@ -93,7 +93,7 @@ private: int invert_state; uint32 entity_id; bool disable_timer; - bool isopen; + bool is_open; Timer close_timer; //Timer trigger_timer; diff --git a/zone/entity.cpp b/zone/entity.cpp index 2189228c3..37af35fdb 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -877,12 +877,12 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client) auto it = door_list.begin(); while (it != door_list.end()) { if ((it->second->GetClientVersionMask() & mask_test) && - strlen(it->second->GetDoorName()) > 3) + strlen(it->second->GetDoorName()) > 3) count++; ++it; } - if(count == 0 || count > 500) + if (count == 0 || count > 500) return false; uint32 length = count * sizeof(Door_Struct); @@ -890,31 +890,43 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client) memset(packet_buffer, 0, length); uchar *ptr = packet_buffer; Doors *door; - Door_Struct nd; + Door_Struct new_door; it = door_list.begin(); while (it != door_list.end()) { door = it->second; if (door && (door->GetClientVersionMask() & mask_test) && - strlen(door->GetDoorName()) > 3) { - memset(&nd, 0, sizeof(nd)); - memcpy(nd.name, door->GetDoorName(), 32); + strlen(door->GetDoorName()) > 3) { + memset(&new_door, 0, sizeof(new_door)); + memcpy(new_door.name, door->GetDoorName(), 32); + auto position = door->GetPosition(); - nd.xPos = position.x; - nd.yPos = position.y; - nd.zPos = position.z; - nd.heading = position.w; - nd.incline = door->GetIncline(); - nd.size = door->GetSize(); - nd.doorId = door->GetDoorID(); - nd.opentype = door->GetOpenType(); - nd.state_at_spawn = door->GetInvertState() ? !door->IsDoorOpen() : door->IsDoorOpen(); - nd.invert_state = door->GetInvertState(); - nd.door_param = door->GetDoorParam(); - memcpy(ptr, &nd, sizeof(nd)); - ptr+=sizeof(nd); - *(ptr-1)=0x01; - *(ptr-3)=0x01; + + new_door.xPos = position.x; + new_door.yPos = position.y; + new_door.zPos = position.z; + new_door.heading = position.w; + + new_door.incline = door->GetIncline(); + new_door.size = door->GetSize(); + new_door.doorId = door->GetDoorID(); + new_door.opentype = door->GetOpenType(); + + Log(Logs::General, Logs::Doors, "Door timer_disable: %s door_id: %u is_open: %s invert_state: %i", + (door->GetDisableTimer() ? "true" : "false"), + door->GetDoorID(), + (door->IsDoorOpen() ? "true" : "false"), + door->GetInvertState() + ); + + new_door.state_at_spawn = (door->GetInvertState() ? !door->IsDoorOpen() : door->IsDoorOpen()); + new_door.invert_state = door->GetInvertState(); + + new_door.door_param = door->GetDoorParam(); + memcpy(ptr, &new_door, sizeof(new_door)); + ptr += sizeof(new_door); + *(ptr - 1) = 0x01; + *(ptr - 3) = 0x01; } ++it; } diff --git a/zone/zonedump.h b/zone/zonedump.h index e273d7379..713bfca7e 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -202,7 +202,7 @@ struct Door { uint8 nokeyring; uint8 trigger_door; uint8 trigger_type; - bool disable_timer; + uint8 disable_timer; uint32 door_param; int invert_state; uint16 size;