diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 7b13e0c2c2..d85a68307f 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -614,13 +614,10 @@ void CharacterDatabaseConnection::DoPrepareStatements() //PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, "DELETE FROM character_pet_declinedname WHERE Guid = ?", CONNECTION_ASYNC); //PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE PetNumber = ?", CONNECTION_ASYNC); //PrepareStatement(CHAR_INS_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (PetNumber, Guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PET_AURA, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges, critChance, applyResilience FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE Guid = ? AND PetNumber = ?", CONNECTION_SYNCH); + PrepareStatement(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE Guid = ? AND PetNumber = ?", CONNECTION_ASYNC); + + PrepareStatement(CHAR_SEL_PET_AURAS, "SELECT guid, casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges, critChance, applyResilience FROM pet_aura WHERE guid IN (SELECT PetNumber FROM character_pet WHERE Guid = ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_PET_AURAS, "DELETE FROM pet_aura WHERE guid = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_DEL_PET_SPELLS, "DELETE FROM pet_spell WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PET_SPELL_BY_SPELL, "DELETE FROM pet_spell WHERE guid = ? and spell = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)", CONNECTION_BOTH); PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, " "base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges, critChance, applyResilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH); @@ -629,6 +626,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHAR_PET, "SELECT PetNumber, CreatureId, TamedCreatureId, DisplayId, SavedHealth, SavedPower, CreatedBySpellId, LastSaveTime, ReactState, Slot, HasBeenRenamed, IsActive, `Name`, ActionBar, Talents FROM character_pet WHERE Guid = ? ORDER BY Slot", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_PET, "UPDATE character_pet SET SavedHealth = ?, SavedPower = ?, LastSaveTime = ?, ReactState = ?, Slot = ?, HasBeenRenamed = ?, IsActive = ?, `Name` = ?, ActionBar = ?, Talents = ? WHERE PetNumber = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_PET, "INSERT INTO character_pet (Guid, PetNumber, CreatureId, TamedCreatureId, DisplayId, SavedHealth, SavedPower, CreatedBySpellId, LastSaveTime, ReactState, Slot, HasBeenRenamed, IsActive, `Name`, ActionBar, Talents) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH); + PrepareStatement(CHAR_SEL_PET_SPELL_COOLDOWNS, "SELECT guid, spell, time, categoryId, categoryEnd FROM pet_spell_cooldown WHERE guid IN (SELECT PetNumber FROM character_pet WHERE Guid = ?) AND time > UNIX_TIMESTAMP()", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_PET_SPELL_COOLDOWNS, "DELETE FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_BOTH); PrepareStatement(CHAR_INS_PET_SPELL_COOLDOWN, "INSERT INTO pet_spell_cooldown (guid, spell, time, categoryId, categoryEnd) VALUES (?, ?, ?, ?, ?)", CONNECTION_BOTH); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 01b0d26a20..59c0adfd5e 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -519,17 +519,15 @@ enum CharacterDatabaseStatements : uint32 CHAR_REP_CALENDAR_INVITE, CHAR_DEL_CALENDAR_INVITE, - CHAR_SEL_PET_AURA, - CHAR_SEL_PET_SPELL, - CHAR_SEL_PET_SPELL_COOLDOWNS, - CHAR_SEL_PET_DECLINED_NAME, + CHAR_SEL_PET_AURAS, CHAR_DEL_PET_AURAS, + CHAR_INS_PET_AURA, + + CHAR_SEL_PET_SPELL_COOLDOWNS, CHAR_DEL_PET_SPELL_COOLDOWNS, CHAR_INS_PET_SPELL_COOLDOWN, - CHAR_DEL_PET_SPELL_BY_SPELL, - CHAR_INS_PET_SPELL, - CHAR_INS_PET_AURA, - CHAR_DEL_PET_SPELLS, + + CHAR_SEL_PET_DECLINED_NAME, CHAR_INS_CHAR_PET, CHAR_DEL_CHAR_PET, diff --git a/src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp b/src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp index ef08eee26f..69b6996def 100644 --- a/src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp @@ -6,6 +6,8 @@ #include "ObjectMgr.h" #include "PetPackets.h" #include "Player.h" +#include "SpellAuras.h" +#include "SpellAuraEffects.h" #include "SpellMgr.h" #include "SpellHistory.h" #include "SpellInfo.h" @@ -77,6 +79,8 @@ bool NewPet::HandlePreSummonActions(Unit const* summoner, uint8 creatureLevel, u for (auto const& itr : playerPetData->Cooldowns) GetSpellHistory()->AddCooldown(itr.SpellId, 0, itr.CooldownEnd, itr.CategoryId, itr.CategoryEnd); + ApplySavedAuras(playerPetData); + if (IsClassPet()) SetName(playerPetData->Name); @@ -303,6 +307,7 @@ void NewPet::UpdatePlayerPetData(PlayerPetData* petData) petData->Talents = GenenerateTalentsDataString(); GetSpellHistory()->StoreSpellHistoryEntries(petData->Cooldowns); + StoreAppliedAuras(petData); if (petData->Status != PlayerPetDataStatus::New) petData->Status = PlayerPetDataStatus::Changed; @@ -435,6 +440,91 @@ void NewPet::LearnAvailableSpellsForCurrentLevel() } +void NewPet::ApplySavedAuras(PlayerPetData* petData) +{ + uint32 timediff = uint32(GameTime::GetGameTime() - petData->LastSaveTime); + + for (PlayerPetDataAura& petAura : petData->Auras) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(petAura.SpellId); + if (!spellInfo) // skip non-existing/outdated auras. They will be pruned from DB at the next save cycle + continue; + + int32 remainingDuration = petAura.RemainingDuration; + // negative effects should continue counting down after logout + if (remainingDuration != -1 && (!spellInfo->IsPositive() || spellInfo->HasAttribute(SPELL_ATTR4_AURA_EXPIRES_OFFLINE))) + { + if (remainingDuration / IN_MILLISECONDS <= int32(timediff)) + continue; + + remainingDuration -= timediff * IN_MILLISECONDS; + } + + uint8 remainingCharges = petAura.RemainingCharges; + // prevent wrong values of remaincharges + if (spellInfo->ProcCharges) + { + if (remainingCharges <= 0 || remainingCharges > spellInfo->ProcCharges) + remainingCharges = spellInfo->ProcCharges; + } + else + remainingCharges = 0; + + AuraCreateInfo createInfo(spellInfo, petAura.EffectMask, this); + createInfo + .SetCasterGUID(petAura.CasterGuid) + .SetBaseAmount(petAura.BaseAmount.data()); + + if (Aura* aura = Aura::TryCreate(createInfo)) + { + if (!aura->CanBeSaved()) + { + aura->Remove(); + continue; + } + + aura->SetLoadedState(petAura.MaxDuration, remainingDuration, remainingCharges, petAura.StackAmount, petAura.RecalculateMask, petAura.CritChance, petAura.ApplyResilience, petAura.Amount.data()); + aura->ApplyForTargets(); + } + } +} + +void NewPet::StoreAppliedAuras(PlayerPetData* petData) +{ + petData->Auras.clear(); + + for (auto const& pair : m_ownedAuras) + { + Aura* aura = pair.second; + if (!aura->CanBeSaved()) + continue; + + PlayerPetDataAura& petAura = petData->Auras.emplace_back(); + + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (aura->GetEffect(i)) + { + petAura.BaseAmount[i] = aura->GetEffect(i)->GetBaseAmount(); + petAura.Amount[i] = aura->GetEffect(i)->GetAmount(); + petAura.EffectMask |= (1 << i); + if (aura->GetEffect(i)->CanBeRecalculated()) + petAura.RecalculateMask |= (1 << i); + } + } + + // Store auras that have been casted by ourselves as empty because when we are summoned the next time, we will have a different ObjectGuid + petAura.CasterGuid = aura->GetCasterGUID() == GetGUID() ? ObjectGuid::Empty : aura->GetCasterGUID(); + petAura.SpellId = aura->GetId(); + petAura.StackAmount = aura->GetStackAmount(); + petAura.RemainingCharges = aura->GetCharges(); + petAura.MaxDuration = aura->GetMaxDuration(); + petAura.RemainingDuration = aura->GetDuration(); + petAura.CritChance = aura->GetCritChance(); + petAura.ApplyResilience = aura->CanApplyResilience(); + } +} + bool NewPet::LearnSpell(uint32 spellId) { if (!AddSpell(spellId)) diff --git a/src/server/game/Entities/Creature/TemporarySummon/NewPet.h b/src/server/game/Entities/Creature/TemporarySummon/NewPet.h index 35870e9eb9..4f2c15a03c 100644 --- a/src/server/game/Entities/Creature/TemporarySummon/NewPet.h +++ b/src/server/game/Entities/Creature/TemporarySummon/NewPet.h @@ -71,14 +71,14 @@ class TC_GAME_API NewPet final : public NewGuardian // Synchronizes the pet's level with its summoner, updates the stats for the new level and learns new spells if available void SynchronizeLevelWithSummoner(); // Returns true when the pet knows the given spell - bool HasSpell(uint32 spellID) const override; + bool HasSpell(uint32 spellId) const override; // Enables or disables auto casting for the given spell void ToggleAutocast(SpellInfo const* spellInfo, bool apply); // Returns a map of a pet's known spells PetSpellMap const& GetSpells() const { return _spells; } // Sets the PlayerPetData map key for accessing the summoner's player pet data at any given time void SetPlayerPetDataKey(uint8 slot, uint32 creatureId); - // Updates the PlayerPetData values of this pet for the specified summoner + // Updates the provided pet data object with the pet's current data, such as action bars, talents and cooldowns. This method should be used whenever you have to store the data (like unsummoning and saving pets) void UpdatePlayerPetData(PlayerPetData* petData); // Learns the specified talent for the given rank and learns the according spell/passive aura void LearnTalent(uint32 talentId, uint32 rank); @@ -91,6 +91,8 @@ class TC_GAME_API NewPet final : public NewGuardian void SendSpellLearnedToSummoner(uint32 spellId); void SendSpellUnlearnedToSummoner(uint32 spellId); void LearnAvailableSpellsForCurrentLevel(); + void ApplySavedAuras(PlayerPetData* petData); + void StoreAppliedAuras(PlayerPetData* petData); bool LearnSpell(uint32 spellId); bool UnlearnSpell(uint32 spellId, bool learnPreviousRank, bool clearActionbar = true); bool AddSpell(uint32 spellId, ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 25217e67fa..0d42db5fc4 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -931,6 +931,7 @@ void Pet::_LoadSpellCooldowns() void Pet::_LoadSpells() { + /* CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL); stmt->setUInt32(0, m_charmInfo->GetPetNumber()); PreparedQueryResult result = CharacterDatabase.Query(stmt); @@ -945,10 +946,12 @@ void Pet::_LoadSpells() } while (result->NextRow()); } + */ } void Pet::_SaveSpells(CharacterDatabaseTransaction& trans) { + /* for (PetSpellMapOld::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next) { ++next; @@ -994,10 +997,12 @@ void Pet::_SaveSpells(CharacterDatabaseTransaction& trans) } itr->second.state = PETSPELL_UNCHANGED; } + */ } void Pet::_LoadAuras(uint32 timediff) { + /* TC_LOG_DEBUG("entities.pet", "Loading auras for pet %u", GetGUID().GetCounter()); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_AURA); @@ -1075,6 +1080,7 @@ void Pet::_LoadAuras(uint32 timediff) } while (result->NextRow()); } + */ } void Pet::_SaveAuras(CharacterDatabaseTransaction& trans) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b8db301f8b..ca6a916c31 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -16924,6 +16924,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol _LoadPets(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ALL_PETS)); _LoadPetCooldowns(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ALL_PET_COOLDOWNS)); + _LoadPetAuras(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ALL_PET_AURAS)); // after spell load, learn rewarded spell if need also _LoadQuestStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS)); @@ -17812,6 +17813,39 @@ void Player::_LoadPetCooldowns(PreparedQueryResult result) } while (result->NextRow()); } +void Player::_LoadPetAuras(PreparedQueryResult result) +{ + // "SELECT guid, casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges, + // critChance, applyResilience FROM pet_aura WHERE guid IN (SELECT PetNumber FROM character_pet WHERE Guid = ?)" + if (!result) + return; + + do + { + Field* fields = result->Fetch(); + + uint32 petNumber = fields[0].GetUInt32(); + PlayerPetData* petData = GetPlayerPetDataByPetNumber(petNumber); + if (!petData) + continue; + + PlayerPetDataAura& aura = petData->Auras.emplace_back(); + aura.CasterGuid = ObjectGuid(fields[1].GetUInt64()); + aura.SpellId = fields[2].GetUInt32(); + aura.EffectMask = fields[3].GetUInt8(); + aura.RecalculateMask = fields[4].GetUInt8(); + aura.StackAmount = fields[5].GetUInt8(); + aura.Amount = { fields[6].GetInt32(), fields[7].GetInt32(), fields[8].GetInt32() }; + aura.BaseAmount = { fields[9].GetInt32(), fields[10].GetInt32(), fields[11].GetInt32() }; + aura.MaxDuration = fields[12].GetInt32(); + aura.RemainingDuration = fields[13].GetInt32(); + aura.RemainingCharges = fields[14].GetUInt8(); + aura.CritChance = fields[15].GetFloat(); + aura.ApplyResilience = fields[16].GetBool(); + + } while (result->NextRow()); +} + void Player::SendPetSpellsMessage(NewPet* pet, bool remove /*= false*/) { CharmInfo* charmInfo = pet->GetCharmInfo(); @@ -20022,6 +20056,7 @@ void Player::_SavePets(CharacterDatabaseTransaction& trans) trans->Append(stmt); + // Pet cooldowns stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_COOLDOWNS); stmt->setUInt32(0, petData->PetNumber); trans->Append(stmt); @@ -20040,6 +20075,34 @@ void Player::_SavePets(CharacterDatabaseTransaction& trans) stmt->setUInt32(4, uint32(SpellHistory::Clock::to_time_t(itr.CooldownEnd))); trans->Append(stmt); } + + // Pet auras + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS); + stmt->setUInt32(0, petData->PetNumber); + trans->Append(stmt); + + for (auto const& itr : petData->Auras) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_AURA); + stmt->setUInt32(0, petData->PetNumber); + stmt->setUInt64(1, itr.CasterGuid.GetRawValue()); + stmt->setUInt32(2, itr.SpellId); + stmt->setUInt8(3, itr.EffectMask); + stmt->setUInt8(4, itr.RecalculateMask); + stmt->setUInt8(5, itr.StackAmount); + stmt->setInt32(6, itr.Amount[EFFECT_0]); + stmt->setInt32(7, itr.Amount[EFFECT_1]); + stmt->setInt32(8, itr.Amount[EFFECT_2]); + stmt->setInt32(9, itr.BaseAmount[EFFECT_0]); + stmt->setInt32(10, itr.BaseAmount[EFFECT_1]); + stmt->setInt32(11, itr.BaseAmount[EFFECT_2]); + stmt->setInt32(12, itr.MaxDuration); + stmt->setInt32(13, itr.RemainingDuration); + stmt->setUInt8(14, itr.RemainingCharges); + stmt->setFloat(15, itr.CritChance); + stmt->setBool(16, itr.ApplyResilience); + trans->Append(stmt); + } } for (uint32 deletedPetNumber : _deletedPlayerPetDataSet) @@ -20051,6 +20114,10 @@ void Player::_SavePets(CharacterDatabaseTransaction& trans) stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_COOLDOWNS); stmt->setUInt32(0, deletedPetNumber); trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS); + stmt->setUInt32(0, deletedPetNumber); + trans->Append(stmt); } _deletedPlayerPetDataSet.clear(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 400a3d5431..3753355694 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -802,7 +802,8 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 36, PLAYER_LOGIN_QUERY_LOAD_ALL_PETS = 37, PLAYER_LOGIN_QUERY_LOAD_ALL_PET_COOLDOWNS = 38, - PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS = 39, + PLAYER_LOGIN_QUERY_LOAD_ALL_PET_AURAS = 39, + PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS = 40, MAX_PLAYER_LOGIN_QUERY }; @@ -2465,6 +2466,7 @@ class TC_GAME_API Player : public Unit, public GridObject void _LoadLFGRewardStatus(PreparedQueryResult result); void _LoadPets(PreparedQueryResult result); void _LoadPetCooldowns(PreparedQueryResult result); + void _LoadPetAuras(PreparedQueryResult result); /*********************************************************/ /*** SAVE SYSTEM ***/ diff --git a/src/server/game/Entities/Player/PlayerPetData.h b/src/server/game/Entities/Player/PlayerPetData.h index 751504e25e..1fba30d3c4 100644 --- a/src/server/game/Entities/Player/PlayerPetData.h +++ b/src/server/game/Entities/Player/PlayerPetData.h @@ -22,6 +22,22 @@ #include "PetDefines.h" #include "UnitDefines.h" +struct PlayerPetDataAura +{ + std::array Amount = { }; + std::array BaseAmount = { }; + ObjectGuid CasterGuid; + uint32 SpellId = 0; + uint8 EffectMask = 0; + uint8 RecalculateMask = 0; + uint8 StackAmount = 0; + int32 MaxDuration = 0; + int32 RemainingDuration = 0; + uint8 RemainingCharges = 0; + float CritChance = 0.f; + bool ApplyResilience = false; +}; + struct PlayerPetData { PlayerPetData() { } @@ -42,6 +58,7 @@ struct PlayerPetData std::string ActionBar; std::string Talents; std::vector Cooldowns; + std::vector Auras; PlayerPetDataStatus Status = PlayerPetDataStatus::New; }; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index a250aeb6d5..e5525dc938 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -237,6 +237,10 @@ bool LoginQueryHolder::Initialize() stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ALL_PET_COOLDOWNS, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_AURAS); + stmt->setUInt32(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ALL_PET_AURAS, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_REWARDSTATUS_LFG); stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS, stmt);