diff --git a/common/database/database_update_manifest.cpp b/common/database/database_update_manifest.cpp index 63f3ba35b32..6b9d0997352 100644 --- a/common/database/database_update_manifest.cpp +++ b/common/database/database_update_manifest.cpp @@ -5758,6 +5758,17 @@ ALTER TABLE `inventory_snapshots` ALTER TABLE `character_exp_modifiers` MODIFY COLUMN `aa_modifier` float NOT NULL DEFAULT 1.0 AFTER `instance_version`, MODIFY COLUMN `exp_modifier` float NOT NULL DEFAULT 1.0 AFTER `aa_modifier`; +)" + }, + ManifestEntry{ + .version = 9285, + .description = "2024_10_15_npc_types_multiquest_enabled.sql", + .check = "SHOW COLUMNS FROM `npc_types` LIKE 'multiquest_enabled'", + .condition = "empty", + .match = "", + .sql = R"( +ALTER TABLE `npc_types` +ADD COLUMN `multiquest_enabled` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `is_parcel_merchant`; )" } // -- template; copy/paste this when you need to create a new entry diff --git a/common/repositories/base/base_npc_types_repository.h b/common/repositories/base/base_npc_types_repository.h index 1eb12660bf4..02632be4813 100644 --- a/common/repositories/base/base_npc_types_repository.h +++ b/common/repositories/base/base_npc_types_repository.h @@ -148,6 +148,7 @@ class BaseNpcTypesRepository { int32_t faction_amount; uint8_t keeps_sold_items; uint8_t is_parcel_merchant; + uint8_t multiquest_enabled; }; static std::string PrimaryKey() @@ -287,6 +288,7 @@ class BaseNpcTypesRepository { "faction_amount", "keeps_sold_items", "is_parcel_merchant", + "multiquest_enabled", }; } @@ -422,6 +424,7 @@ class BaseNpcTypesRepository { "faction_amount", "keeps_sold_items", "is_parcel_merchant", + "multiquest_enabled", }; } @@ -591,6 +594,7 @@ class BaseNpcTypesRepository { e.faction_amount = 0; e.keeps_sold_items = 1; e.is_parcel_merchant = 0; + e.multiquest_enabled = 0; return e; } @@ -756,6 +760,7 @@ class BaseNpcTypesRepository { e.faction_amount = row[126] ? static_cast(atoi(row[126])) : 0; e.keeps_sold_items = row[127] ? static_cast(strtoul(row[127], nullptr, 10)) : 1; e.is_parcel_merchant = row[128] ? static_cast(strtoul(row[128], nullptr, 10)) : 0; + e.multiquest_enabled = row[129] ? static_cast(strtoul(row[129], nullptr, 10)) : 0; return e; } @@ -917,6 +922,7 @@ class BaseNpcTypesRepository { v.push_back(columns[126] + " = " + std::to_string(e.faction_amount)); v.push_back(columns[127] + " = " + std::to_string(e.keeps_sold_items)); v.push_back(columns[128] + " = " + std::to_string(e.is_parcel_merchant)); + v.push_back(columns[129] + " = " + std::to_string(e.multiquest_enabled)); auto results = db.QueryDatabase( fmt::format( @@ -1067,6 +1073,7 @@ class BaseNpcTypesRepository { v.push_back(std::to_string(e.faction_amount)); v.push_back(std::to_string(e.keeps_sold_items)); v.push_back(std::to_string(e.is_parcel_merchant)); + v.push_back(std::to_string(e.multiquest_enabled)); auto results = db.QueryDatabase( fmt::format( @@ -1225,6 +1232,7 @@ class BaseNpcTypesRepository { v.push_back(std::to_string(e.faction_amount)); v.push_back(std::to_string(e.keeps_sold_items)); v.push_back(std::to_string(e.is_parcel_merchant)); + v.push_back(std::to_string(e.multiquest_enabled)); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); } @@ -1387,6 +1395,7 @@ class BaseNpcTypesRepository { e.faction_amount = row[126] ? static_cast(atoi(row[126])) : 0; e.keeps_sold_items = row[127] ? static_cast(strtoul(row[127], nullptr, 10)) : 1; e.is_parcel_merchant = row[128] ? static_cast(strtoul(row[128], nullptr, 10)) : 0; + e.multiquest_enabled = row[129] ? static_cast(strtoul(row[129], nullptr, 10)) : 0; all_entries.push_back(e); } @@ -1540,6 +1549,7 @@ class BaseNpcTypesRepository { e.faction_amount = row[126] ? static_cast(atoi(row[126])) : 0; e.keeps_sold_items = row[127] ? static_cast(strtoul(row[127], nullptr, 10)) : 1; e.is_parcel_merchant = row[128] ? static_cast(strtoul(row[128], nullptr, 10)) : 0; + e.multiquest_enabled = row[129] ? static_cast(strtoul(row[129], nullptr, 10)) : 0; all_entries.push_back(e); } @@ -1743,6 +1753,7 @@ class BaseNpcTypesRepository { v.push_back(std::to_string(e.faction_amount)); v.push_back(std::to_string(e.keeps_sold_items)); v.push_back(std::to_string(e.is_parcel_merchant)); + v.push_back(std::to_string(e.multiquest_enabled)); auto results = db.QueryDatabase( fmt::format( @@ -1894,6 +1905,7 @@ class BaseNpcTypesRepository { v.push_back(std::to_string(e.faction_amount)); v.push_back(std::to_string(e.keeps_sold_items)); v.push_back(std::to_string(e.is_parcel_merchant)); + v.push_back(std::to_string(e.multiquest_enabled)); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); } diff --git a/common/version.h b/common/version.h index 91d4c7494eb..44345799740 100644 --- a/common/version.h +++ b/common/version.h @@ -42,7 +42,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9284 +#define CURRENT_BINARY_DATABASE_VERSION 9285 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9045 #endif diff --git a/zone/npc.cpp b/zone/npc.cpp index eac775f5c80..df323751040 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -226,6 +226,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi ATK = npc_type_data->ATK; heroic_strikethrough = npc_type_data->heroic_strikethrough; keeps_sold_items = npc_type_data->keeps_sold_items; + multiquest_enabled = npc_type_data->multiquest_enabled; // used for when switch back to charm default_ac = npc_type_data->AC; diff --git a/zone/npc.h b/zone/npc.h index 893aeaa3c0a..33510772fa8 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -561,8 +561,8 @@ class NPC : public Mob bool CanPetTakeItem(const EQ::ItemInstance *inst); - bool IsMultiQuest() { return m_is_multiquest_npc; } - void SetMultiQuest(bool b) { m_is_multiquest_npc = b; } + bool IsMultiQuest() { return multiquest_enabled; } + void SetMultiQuest(bool b) { multiquest_enabled = b; } protected: @@ -705,7 +705,7 @@ class NPC : public Mob bool raid_target; bool ignore_despawn; //NPCs with this set to 1 will ignore the despawn value in spawngroup - bool m_is_multiquest_npc; + bool multiquest_enabled; private: uint32 m_loottable_id; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index bcfaa935d02..a0f95d01115 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1905,6 +1905,7 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load t->heroic_strikethrough = n.heroic_strikethrough; t->faction_amount = n.faction_amount; t->keeps_sold_items = n.keeps_sold_items; + t->multiquest_enabled = n.multiquest_enabled != 0; // 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 52dbb5b3ed6..cefa2574d35 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -155,7 +155,8 @@ struct NPCType int heroic_strikethrough; bool keeps_sold_items; bool is_parcel_merchant; - uint8 greed; + uint8 greed; + bool multiquest_enabled; }; #pragma pack()