diff options
17 files changed, 195 insertions, 22 deletions
diff --git a/sql/updates/hotfixes/master/2021_10_26_00_hotfixes.sql b/sql/updates/hotfixes/master/2021_10_26_00_hotfixes.sql new file mode 100644 index 00000000000..54c1a8b9390 --- /dev/null +++ b/sql/updates/hotfixes/master/2021_10_26_00_hotfixes.sql @@ -0,0 +1,15 @@ +-- +-- Table structure for table `broadcast_text_duration` +-- +DROP TABLE IF EXISTS `broadcast_text_duration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `broadcast_text_duration` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `BroadcastTextID` int(11) NOT NULL DEFAULT '0', + `Locale` int(11) NOT NULL DEFAULT '0', + `Duration` int(11) NOT NULL DEFAULT '0', + `VerifiedBuild` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`,`VerifiedBuild`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; diff --git a/sql/updates/world/master/2021_10_26_00_world.sql b/sql/updates/world/master/2021_10_26_00_world.sql new file mode 100644 index 00000000000..e1f10ae3f5c --- /dev/null +++ b/sql/updates/world/master/2021_10_26_00_world.sql @@ -0,0 +1,3 @@ +-- +ALTER TABLE `conversation_line_template` DROP `StartTime`; +ALTER TABLE `conversation_template` DROP `LastLineEndTime`; diff --git a/src/common/Common.cpp b/src/common/Common.cpp index a176941e6f9..1d1beddddc6 100644 --- a/src/common/Common.cpp +++ b/src/common/Common.cpp @@ -41,3 +41,19 @@ LocaleConstant GetLocaleByName(std::string const& name) return TOTAL_LOCALES; } + +CascLocaleBit WowLocaleToCascLocaleBit[TOTAL_LOCALES] = +{ + CascLocaleBit::enUS, + CascLocaleBit::koKR, + CascLocaleBit::frFR, + CascLocaleBit::deDE, + CascLocaleBit::zhCN, + CascLocaleBit::zhTW, + CascLocaleBit::esES, + CascLocaleBit::esMX, + CascLocaleBit::ruRU, + CascLocaleBit::None, + CascLocaleBit::ptBR, + CascLocaleBit::itIT +}; diff --git a/src/common/Common.h b/src/common/Common.h index 7c0f2b37142..902b8cf6567 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -98,10 +98,33 @@ enum LocaleConstant : uint8 const uint8 OLD_TOTAL_LOCALES = 9; /// @todo convert in simple system #define DEFAULT_LOCALE LOCALE_enUS +enum class CascLocaleBit : uint8 +{ + None = 0, + enUS = 1, + koKR = 2, + Reserved = 3, + frFR = 4, + deDE = 5, + zhCN = 6, + esES = 7, + zhTW = 8, + enGB = 9, + enCN = 10, + enTW = 11, + esMX = 12, + ruRU = 13, + ptBR = 14, + itIT = 15, + ptPT = 16 +}; + TC_COMMON_API extern char const* localeNames[TOTAL_LOCALES]; TC_COMMON_API LocaleConstant GetLocaleByName(std::string const& name); +TC_COMMON_API extern CascLocaleBit WowLocaleToCascLocaleBit[TOTAL_LOCALES]; + constexpr inline bool IsValidLocale(LocaleConstant locale) { return locale < TOTAL_LOCALES && locale != LOCALE_none; diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp index e79c7c1024f..b470ba8cdd9 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp @@ -276,6 +276,11 @@ void HotfixDatabaseConnection::DoPrepareStatements() PREPARE_LOCALE_STMT(HOTFIX_SEL_BROADCAST_TEXT, "SELECT ID, Text_lang, Text1_lang FROM broadcast_text_locale WHERE (`VerifiedBuild` > 0) = ?" " AND locale = ?", CONNECTION_SYNCH); + // BroadcastTextDuration.db2 + PrepareStatement(HOTFIX_SEL_BROADCAST_TEXT_DURATION, "SELECT ID, BroadcastTextID, Locale, Duration FROM broadcast_text_duration" + " WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); + PREPARE_MAX_ID_STMT(HOTFIX_SEL_BROADCAST_TEXT_DURATION, "SELECT MAX(ID) + 1 FROM broadcast_text_duration", CONNECTION_SYNCH); + // CfgRegions.db2 PrepareStatement(HOTFIX_SEL_CFG_REGIONS, "SELECT ID, Tag, RegionID, Raidorigin, RegionGroupMask, ChallengeOrigin FROM cfg_regions" " WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h index e11c93a7fb7..7237547cfe2 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -175,6 +175,9 @@ enum HotfixDatabaseStatements : uint32 HOTFIX_SEL_BROADCAST_TEXT_MAX_ID, HOTFIX_SEL_BROADCAST_TEXT_LOCALE, + HOTFIX_SEL_BROADCAST_TEXT_DURATION, + HOTFIX_SEL_BROADCAST_TEXT_DURATION_MAX_ID, + HOTFIX_SEL_CFG_REGIONS, HOTFIX_SEL_CFG_REGIONS_MAX_ID, diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h index 93a0b7075ae..6fae3356658 100644 --- a/src/server/game/DataStores/DB2LoadInfo.h +++ b/src/server/game/DataStores/DB2LoadInfo.h @@ -890,6 +890,22 @@ struct BroadcastTextLoadInfo } }; +struct BroadcastTextDurationLoadInfo +{ + static DB2LoadInfo const* Instance() + { + static DB2FieldMeta const fields[] = + { + { false, FT_INT, "ID" }, + { true, FT_INT, "BroadcastTextID" }, + { true, FT_INT, "Locale" }, + { true, FT_INT, "Duration" }, + }; + static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, BroadcastTextDurationMeta::Instance(), HOTFIX_SEL_BROADCAST_TEXT_DURATION); + return &loadInfo; + } +}; + struct CfgRegionsLoadInfo { static DB2LoadInfo const* Instance() diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 7254de7c37e..c40820bba9f 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -84,6 +84,7 @@ DB2Storage<BattlePetSpeciesEntry> sBattlePetSpeciesStore("BattlePe DB2Storage<BattlePetSpeciesStateEntry> sBattlePetSpeciesStateStore("BattlePetSpeciesState.db2", BattlePetSpeciesStateLoadInfo::Instance()); DB2Storage<BattlemasterListEntry> sBattlemasterListStore("BattlemasterList.db2", BattlemasterListLoadInfo::Instance()); DB2Storage<BroadcastTextEntry> sBroadcastTextStore("BroadcastText.db2", BroadcastTextLoadInfo::Instance()); +DB2Storage<BroadcastTextDurationEntry> sBroadcastTextDurationStore("BroadcastTextDuration.db2", BroadcastTextDurationLoadInfo::Instance()); DB2Storage<Cfg_RegionsEntry> sCfgRegionsStore("Cfg_Regions.db2", CfgRegionsLoadInfo::Instance()); DB2Storage<CharTitlesEntry> sCharTitlesStore("CharTitles.db2", CharTitlesLoadInfo::Instance()); DB2Storage<CharacterLoadoutEntry> sCharacterLoadoutStore("CharacterLoadout.db2", CharacterLoadoutLoadInfo::Instance()); @@ -407,6 +408,7 @@ namespace std::unordered_map<uint32 /*azeritePowerSetId*/, std::vector<AzeritePowerSetMemberEntry const*>> _azeritePowers; std::unordered_map<std::pair<uint32 /*azeriteUnlockSetId*/, ItemContext>, std::array<uint8, MAX_AZERITE_EMPOWERED_TIER>> _azeriteTierUnlockLevels; std::unordered_map<std::pair<uint32 /*itemId*/, ItemContext>, AzeriteUnlockMappingEntry const*> _azeriteUnlockMappings; + std::unordered_map<std::pair<int32 /*broadcastTextId*/, CascLocaleBit /*cascLocaleBit*/>, int32> _broadcastTextDurations; std::array<ChrClassUIDisplayEntry const*, MAX_CLASSES> _uiDisplayByClass; std::array<std::array<uint32, MAX_POWERS>, MAX_CLASSES> _powersByClass; std::unordered_map<uint32 /*chrCustomizationOptionId*/, std::vector<ChrCustomizationChoiceEntry const*>> _chrCustomizationChoicesByOption; @@ -635,6 +637,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul LOAD_DB2(sBattlePetSpeciesStateStore); LOAD_DB2(sBattlemasterListStore); LOAD_DB2(sBroadcastTextStore); + LOAD_DB2(sBroadcastTextDurationStore); LOAD_DB2(sCfgRegionsStore); LOAD_DB2(sCharTitlesStore); LOAD_DB2(sCharacterLoadoutStore); @@ -967,6 +970,9 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul ASSERT(BATTLE_PET_SPECIES_MAX_ID >= sBattlePetSpeciesStore.GetNumRows(), "BATTLE_PET_SPECIES_MAX_ID (%d) must be equal to or greater than %u", BATTLE_PET_SPECIES_MAX_ID, sBattlePetSpeciesStore.GetNumRows()); + for (BroadcastTextDurationEntry const* broadcastTextDuration : sBroadcastTextDurationStore) + _broadcastTextDurations[{ broadcastTextDuration->BroadcastTextID, CascLocaleBit(broadcastTextDuration->Locale) }] = broadcastTextDuration->Duration; + for (ChrClassUIDisplayEntry const* uiDisplay : sChrClassUIDisplayStore) { ASSERT(uiDisplay->ChrClassesID < MAX_CLASSES); @@ -1844,6 +1850,11 @@ char const* DB2Manager::GetBroadcastTextValue(BroadcastTextEntry const* broadcas return broadcastText->Text[DEFAULT_LOCALE]; } +int32 const* DB2Manager::GetBroadcastTextDuration(int32 broadcastTextId, LocaleConstant locale /*= DEFAULT_LOCALE*/) const +{ + return Trinity::Containers::MapGetValuePtr(_broadcastTextDurations, { broadcastTextId, WowLocaleToCascLocaleBit[locale] }); +} + ChrClassUIDisplayEntry const* DB2Manager::GetUiDisplayForClass(Classes unitClass) const { ASSERT(unitClass < MAX_CLASSES); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 278fab3fa12..e6dfe80745d 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -353,6 +353,7 @@ public: std::vector<AzeritePowerSetMemberEntry const*> const* GetAzeritePowers(uint32 itemId) const; uint32 GetRequiredAzeriteLevelForAzeritePowerTier(uint32 azeriteUnlockSetId, ItemContext context, uint32 tier) const; static char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false); + int32 const* GetBroadcastTextDuration(int32 broadcastTextId, LocaleConstant locale = DEFAULT_LOCALE) const; ChrClassUIDisplayEntry const* GetUiDisplayForClass(Classes unitClass) const; static char const* GetClassName(uint8 class_, LocaleConstant locale = DEFAULT_LOCALE); uint32 GetPowerIndexByClass(Powers power, uint32 classId) const; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index fd573e4e615..4f09a919e21 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -532,6 +532,14 @@ struct BroadcastTextEntry uint16 EmoteDelay[MAX_BROADCAST_TEXT_EMOTES]; }; +struct BroadcastTextDurationEntry +{ + uint32 ID; + int32 BroadcastTextID; + int32 Locale; + int32 Duration; +}; + struct Cfg_RegionsEntry { uint32 ID; diff --git a/src/server/game/Entities/Conversation/Conversation.cpp b/src/server/game/Entities/Conversation/Conversation.cpp index 75d7d2b8ab2..bd1a6155b13 100644 --- a/src/server/game/Entities/Conversation/Conversation.cpp +++ b/src/server/game/Entities/Conversation/Conversation.cpp @@ -17,8 +17,10 @@ #include "Conversation.h" #include "ConditionMgr.h" +#include "Containers.h" #include "ConversationDataStore.h" #include "Creature.h" +#include "DB2Stores.h" #include "IteratorPair.h" #include "Log.h" #include "Map.h" @@ -34,6 +36,8 @@ Conversation::Conversation() : WorldObject(false), _duration(0), _textureKitId(0 m_updateFlag.Stationary = true; m_updateFlag.Conversation = true; + + _lastLineEndTimes.fill(Milliseconds::zero()); } Conversation::~Conversation() = default; @@ -60,9 +64,9 @@ void Conversation::RemoveFromWorld() void Conversation::Update(uint32 diff) { - if (GetDuration() > int32(diff)) + if (GetDuration() > Milliseconds(diff)) { - _duration -= diff; + _duration -= Milliseconds(diff); DoWithSuppressingObjectUpdates([&]() { // Only sent in CreateObject @@ -123,8 +127,6 @@ bool Conversation::Create(ObjectGuid::LowType lowGuid, uint32 conversationEntry, SetEntry(conversationEntry); SetObjectScale(1.0f); - SetUpdateFieldValue(m_values.ModifyValue(&Conversation::m_conversationData).ModifyValue(&UF::ConversationData::LastLineEndTime), conversationTemplate->LastLineEndTime); - _duration = conversationTemplate->LastLineEndTime + 10 * IN_MILLISECONDS; _textureKitId = conversationTemplate->TextureKitId; for (ConversationActor const& actor : conversationTemplate->Actors) @@ -158,16 +160,38 @@ bool Conversation::Create(ObjectGuid::LowType lowGuid, uint32 conversationEntry, actorIndices.insert(line->ActorIdx); lines.emplace_back(); + UF::ConversationLine& lineField = lines.back(); lineField.ConversationLineID = line->Id; - lineField.StartTime = line->StartTime; lineField.UiCameraID = line->UiCameraID; lineField.ActorIndex = line->ActorIdx; lineField.Flags = line->Flags; + + ConversationLineEntry const* convoLine = sConversationLineStore.LookupEntry(line->Id); // never null for conversationTemplate->Lines + + for (LocaleConstant locale = LOCALE_enUS; locale < TOTAL_LOCALES; locale = LocaleConstant(locale + 1)) + { + if (locale == LOCALE_none) + continue; + + _lineStartTimes[{ locale, line->Id }] = _lastLineEndTimes[locale]; + if (locale == DEFAULT_LOCALE) + lineField.StartTime = _lastLineEndTimes[locale].count(); + + if (int32 const* broadcastTextDuration = sDB2Manager.GetBroadcastTextDuration(convoLine->BroadcastTextID, locale)) + _lastLineEndTimes[locale] += Milliseconds(*broadcastTextDuration); + + _lastLineEndTimes[locale] += Milliseconds(convoLine->AdditionalDuration); + } } + _duration = Milliseconds(*std::max_element(_lastLineEndTimes.begin(), _lastLineEndTimes.end())); + SetUpdateFieldValue(m_values.ModifyValue(&Conversation::m_conversationData).ModifyValue(&UF::ConversationData::LastLineEndTime), _duration.count()); SetUpdateFieldValue(m_values.ModifyValue(&Conversation::m_conversationData).ModifyValue(&UF::ConversationData::Lines), std::move(lines)); + // conversations are despawned 5-20s after LastLineEndTime + _duration += 10s; + sScriptMgr->OnConversationCreate(this, creator); // All actors need to be set @@ -194,6 +218,16 @@ void Conversation::AddActor(ObjectGuid const& actorGuid, uint16 actorIdx) SetUpdateFieldValue(actorField.ModifyValue(&UF::ConversationActor::Type), AsUnderlyingType(ActorType::WorldObjectActor)); } +Milliseconds const* Conversation::GetLineStartTime(LocaleConstant locale, int32 lineId) const +{ + return Trinity::Containers::MapGetValuePtr(_lineStartTimes, { locale, lineId }); +} + +Milliseconds Conversation::GetLastLineEndTime(LocaleConstant locale) const +{ + return _lastLineEndTimes[locale]; +} + uint32 Conversation::GetScriptId() const { return sConversationDataStore->GetConversationTemplate(GetEntry())->ScriptId; diff --git a/src/server/game/Entities/Conversation/Conversation.h b/src/server/game/Entities/Conversation/Conversation.h index a2356cd8a40..157a89f77cd 100644 --- a/src/server/game/Entities/Conversation/Conversation.h +++ b/src/server/game/Entities/Conversation/Conversation.h @@ -19,6 +19,7 @@ #define TRINITYCORE_CONVERSATION_H #include "Object.h" +#include "Hash.h" class Unit; class SpellInfo; @@ -43,7 +44,7 @@ class TC_GAME_API Conversation : public WorldObject, public GridObject<Conversat void Update(uint32 diff) override; void Remove(); - int32 GetDuration() const { return _duration; } + Milliseconds GetDuration() const { return _duration; } uint32 GetTextureKitId() const { return _textureKitId; } static Conversation* CreateConversation(uint32 conversationEntry, Unit* creator, Position const& pos, ObjectGuid privateObjectOwner, SpellInfo const* spellInfo = nullptr); @@ -60,6 +61,9 @@ class TC_GAME_API Conversation : public WorldObject, public GridObject<Conversat float GetStationaryO() const override { return _stationaryPosition.GetOrientation(); } void RelocateStationaryPosition(Position const& pos) { _stationaryPosition.Relocate(pos); } + Milliseconds const* GetLineStartTime(LocaleConstant locale, int32 lineId) const; + Milliseconds GetLastLineEndTime(LocaleConstant locale) const; + uint32 GetScriptId() const; UF::UpdateField<UF::ConversationData, 0, TYPEID_CONVERSATION> m_conversationData; @@ -73,8 +77,11 @@ class TC_GAME_API Conversation : public WorldObject, public GridObject<Conversat private: Position _stationaryPosition; ObjectGuid _creatorGuid; - uint32 _duration; + Milliseconds _duration; uint32 _textureKitId; + + std::unordered_map<std::pair<LocaleConstant /*locale*/, int32 /*lineId*/>, Milliseconds /*startTime*/> _lineStartTimes; + std::array<Milliseconds /*endTime*/, TOTAL_LOCALES> _lastLineEndTimes; }; #endif // TRINITYCORE_CONVERSATION_H diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index 9e9e0c4355e..0fa4e8c1c8b 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -4836,7 +4836,7 @@ void SceneObjectData::ClearChangesMask() void ConversationLine::WriteCreate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const { data << int32(ConversationLineID); - data << uint32(StartTime); + data << uint32(ViewerDependentValue<StartTimeTag>::GetValue(this, owner, receiver)); data << int32(UiCameraID); data << uint8(ActorIndex); data << uint8(Flags); @@ -4846,7 +4846,7 @@ void ConversationLine::WriteCreate(ByteBuffer& data, Conversation const* owner, void ConversationLine::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Conversation const* owner, Player const* receiver) const { data << int32(ConversationLineID); - data << uint32(StartTime); + data << uint32(ViewerDependentValue<StartTimeTag>::GetValue(this, owner, receiver)); data << int32(UiCameraID); data << uint8(ActorIndex); data << uint8(Flags); @@ -4898,7 +4898,7 @@ bool ConversationActor::operator==(ConversationActor const& right) const void ConversationData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Conversation const* owner, Player const* receiver) const { data << uint32(Lines->size()); - data << int32(LastLineEndTime); + data << int32(ViewerDependentValue<LastLineEndTimeTag>::GetValue(this, owner, receiver)); data << uint32(Progress); for (std::size_t i = 0; i < Lines->size(); ++i) { @@ -4963,7 +4963,7 @@ void ConversationData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } if (changesMask[4]) { - data << int32(LastLineEndTime); + data << int32(ViewerDependentValue<LastLineEndTimeTag>::GetValue(this, owner, receiver)); } if (changesMask[5]) { diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index ab78d91b374..813838755aa 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -906,6 +906,7 @@ struct ConversationLine : public IsUpdateFieldStructureTag { int32 ConversationLineID; uint32 StartTime; + struct StartTimeTag : ViewerDependentValueTag<uint32> {}; int32 UiCameraID; uint8 ActorIndex; uint8 Flags; @@ -938,6 +939,7 @@ struct ConversationData : public IsUpdateFieldStructureTag, public HasChangesMas UpdateField<std::vector<UF::ConversationLine>, 0, 2> Lines; DynamicUpdateField<UF::ConversationActor, 0, 3> Actors; UpdateField<int32, 0, 4> LastLineEndTime; + struct LastLineEndTimeTag : ViewerDependentValueTag<int32> {}; UpdateField<uint32, 0, 5> Progress; void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Conversation const* owner, Player const* receiver) const; diff --git a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h index a2b20b2d216..e27ee27619f 100644 --- a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h +++ b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h @@ -18,6 +18,7 @@ #ifndef ViewerDependentValues_h__ #define ViewerDependentValues_h__ +#include "Conversation.h" #include "Creature.h" #include "GameObject.h" #include "Map.h" @@ -26,6 +27,7 @@ #include "SpellInfo.h" #include "SpellMgr.h" #include "World.h" +#include "WorldSession.h" namespace UF { @@ -279,6 +281,37 @@ public: return state; } }; + +template<> +class ViewerDependentValue<UF::ConversationData::LastLineEndTimeTag> +{ +public: + using value_type = UF::ConversationData::LastLineEndTimeTag::value_type; + + static value_type GetValue(UF::ConversationData const* /*conversationData*/, Conversation const* conversation, Player const* receiver) + { + LocaleConstant locale = receiver->GetSession()->GetSessionDbLocaleIndex(); + return conversation->GetLastLineEndTime(locale).count(); + } +}; + +template<> +class ViewerDependentValue<UF::ConversationLine::StartTimeTag> +{ +public: + using value_type = UF::ConversationLine::StartTimeTag::value_type; + + static value_type GetValue(UF::ConversationLine const* conversationLineData, Conversation const* conversation, Player const* receiver) + { + value_type startTime = conversationLineData->StartTime; + LocaleConstant locale = receiver->GetSession()->GetSessionDbLocaleIndex(); + + if (Milliseconds const* localizedStartTime = conversation->GetLineStartTime(locale, conversationLineData->ConversationLineID)) + startTime = localizedStartTime->count(); + + return startTime; + } +}; } #endif // ViewerDependentValues_h__ diff --git a/src/server/game/Globals/ConversationDataStore.cpp b/src/server/game/Globals/ConversationDataStore.cpp index 60b709fe23b..73098184ffb 100644 --- a/src/server/game/Globals/ConversationDataStore.cpp +++ b/src/server/game/Globals/ConversationDataStore.cpp @@ -37,7 +37,7 @@ void ConversationDataStore::LoadConversationTemplates() std::unordered_map<uint32, std::vector<ConversationActor>> actorsByConversation; std::unordered_map<uint32, std::vector<ObjectGuid::LowType>> actorGuidsByConversation; - if (QueryResult lineTemplates = WorldDatabase.Query("SELECT Id, StartTime, UiCameraID, ActorIdx, Flags FROM conversation_line_template")) + if (QueryResult lineTemplates = WorldDatabase.Query("SELECT Id, UiCameraID, ActorIdx, Flags FROM conversation_line_template")) { uint32 oldMSTime = getMSTime(); @@ -55,10 +55,9 @@ void ConversationDataStore::LoadConversationTemplates() ConversationLineTemplate& conversationLine = _conversationLineTemplateStore[id]; conversationLine.Id = id; - conversationLine.StartTime = fields[1].GetUInt32(); - conversationLine.UiCameraID = fields[2].GetUInt32(); - conversationLine.ActorIdx = fields[3].GetUInt8(); - conversationLine.Flags = fields[4].GetUInt8(); + conversationLine.UiCameraID = fields[1].GetUInt32(); + conversationLine.ActorIdx = fields[2].GetUInt8(); + conversationLine.Flags = fields[3].GetUInt8(); } while (lineTemplates->NextRow()); @@ -132,7 +131,7 @@ void ConversationDataStore::LoadConversationTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 Conversation actors. DB table `conversation_actors` is empty."); } - if (QueryResult templates = WorldDatabase.Query("SELECT Id, FirstLineId, LastLineEndTime, TextureKitId, ScriptName FROM conversation_template")) + if (QueryResult templates = WorldDatabase.Query("SELECT Id, FirstLineId, TextureKitId, ScriptName FROM conversation_template")) { uint32 oldMSTime = getMSTime(); @@ -143,9 +142,8 @@ void ConversationDataStore::LoadConversationTemplates() ConversationTemplate conversationTemplate; conversationTemplate.Id = fields[0].GetUInt32(); conversationTemplate.FirstLineId = fields[1].GetUInt32(); - conversationTemplate.LastLineEndTime = fields[2].GetUInt32(); - conversationTemplate.TextureKitId = fields[3].GetUInt32(); - conversationTemplate.ScriptId = sObjectMgr->GetScriptId(fields[4].GetString()); + conversationTemplate.TextureKitId = fields[2].GetUInt32(); + conversationTemplate.ScriptId = sObjectMgr->GetScriptId(fields[3].GetString()); conversationTemplate.Actors = std::move(actorsByConversation[conversationTemplate.Id]); conversationTemplate.ActorGuids = std::move(actorGuidsByConversation[conversationTemplate.Id]); diff --git a/src/server/game/Globals/ConversationDataStore.h b/src/server/game/Globals/ConversationDataStore.h index 41931758dae..f3208153fb5 100644 --- a/src/server/game/Globals/ConversationDataStore.h +++ b/src/server/game/Globals/ConversationDataStore.h @@ -39,7 +39,6 @@ struct ConversationActor struct ConversationLineTemplate { uint32 Id; // Link to ConversationLine.db2 - uint32 StartTime; // Time in ms after conversation creation the line is displayed uint32 UiCameraID; // Link to UiCamera.db2 uint8 ActorIdx; // Index from conversation_actors uint8 Flags; @@ -51,7 +50,6 @@ struct ConversationTemplate { uint32 Id; uint32 FirstLineId; // Link to ConversationLine.db2 - uint32 LastLineEndTime; // Time in ms after conversation creation the last line fades out uint32 TextureKitId; // Background texture std::vector<ConversationActor> Actors; |