TrinityCore
Loading...
Searching...
No Matches
Corpse.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "CharacterCache.h"
19#include "Common.h"
20#include "Corpse.h"
21#include "DatabaseEnv.h"
22#include "DB2Stores.h"
23#include "GameTime.h"
24#include "Log.h"
25#include "Loot.h"
26#include "Map.h"
27#include "PhasingHandler.h"
28#include "Player.h"
29#include "StringConvert.h"
30#include "UpdateData.h"
31#include "WorldPacket.h"
32#include <sstream>
33
46
48
50{
52 if (!IsInWorld())
54
56}
57
66
68{
69 _Create(ObjectGuid::Create<HighGuid::Corpse>(map->GetId(), 0, guidlow));
70 return true;
71}
72
74{
75 ASSERT(owner);
76
77 Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
78
79 if (!IsPositionValid())
80 {
81 TC_LOG_ERROR("entities.player", "Corpse (guidlow {}, owner {}) not created. Suggested coordinates isn't valid (X: {} Y: {})",
82 guidlow, owner->GetName(), owner->GetPositionX(), owner->GetPositionY());
83 return false;
84 }
85
86 _Create(ObjectGuid::Create<HighGuid::Corpse>(owner->GetMapId(), 0, guidlow));
87
88 SetObjectScale(1.0f);
89 SetOwnerGUID(owner->GetGUID());
90
92
94
95 return true;
96}
97
99{
101
102 if (m_loot)
103 m_loot->Update();
104}
105
107{
108 // prevent DB data inconsistence problems and duplicates
109 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
110 DeleteFromDB(trans);
111
112 std::ostringstream items;
113 for (size_t index = 0; index < m_corpseData->Items.size(); ++index)
114 items << m_corpseData->Items[index] << ' ';
115
116 uint16 index = 0;
118 stmt->setUInt64(index++, GetOwnerGUID().GetCounter()); // guid
119 stmt->setFloat (index++, GetPositionX()); // posX
120 stmt->setFloat (index++, GetPositionY()); // posY
121 stmt->setFloat (index++, GetPositionZ()); // posZ
122 stmt->setFloat (index++, GetOrientation()); // orientation
123 stmt->setUInt16(index++, GetMapId()); // mapId
124 stmt->setUInt32(index++, m_corpseData->DisplayID); // displayId
125 stmt->setString(index++, items.str()); // itemCache
126 stmt->setUInt8 (index++, m_corpseData->RaceID); // race
127 stmt->setUInt8 (index++, m_corpseData->Class); // class
128 stmt->setUInt8 (index++, m_corpseData->Sex); // gender
129 stmt->setUInt8 (index++, m_corpseData->Flags); // flags
130 stmt->setUInt8 (index++, m_corpseData->DynamicFlags); // dynFlags
131 stmt->setUInt32(index++, uint32(m_time)); // time
132 stmt->setUInt8 (index++, GetType()); // corpseType
133 stmt->setUInt32(index++, GetInstanceId()); // instanceId
134 trans->Append(stmt);
135
136 for (PhaseShift::PhaseRef const& phase : GetPhaseShift().GetPhases())
137 {
138 index = 0;
139 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE_PHASES);
140 stmt->setUInt64(index++, GetOwnerGUID().GetCounter()); // OwnerGuid
141 stmt->setUInt32(index++, phase.Id); // PhaseId
142 trans->Append(stmt);
143 }
144
145 for (UF::ChrCustomizationChoice customization : m_corpseData->Customizations)
146 {
147 index = 0;
148 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE_CUSTOMIZATIONS);
149 stmt->setUInt64(index++, GetOwnerGUID().GetCounter()); // OwnerGuid
150 stmt->setUInt32(index++, customization.ChrCustomizationOptionID);
151 stmt->setUInt32(index++, customization.ChrCustomizationChoiceID);
152 trans->Append(stmt);
153 }
154
155 CharacterDatabase.CommitTransaction(trans);
156}
157
162
164{
166 stmt->setUInt64(0, ownerGuid.GetCounter());
167 CharacterDatabase.ExecuteOrAppend(trans, stmt);
168
169 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_PHASES);
170 stmt->setUInt64(0, ownerGuid.GetCounter());
171 CharacterDatabase.ExecuteOrAppend(trans, stmt);
172
173 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_CUSTOMIZATIONS);
174 stmt->setUInt64(0, ownerGuid.GetCounter());
175 CharacterDatabase.ExecuteOrAppend(trans, stmt);
176}
177
182
184{
185 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
186 // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, race, class, gender, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?
187
188 float posX = fields[0].GetFloat();
189 float posY = fields[1].GetFloat();
190 float posZ = fields[2].GetFloat();
191 float o = fields[3].GetFloat();
192 uint32 mapId = fields[4].GetUInt16();
193
194 _Create(ObjectGuid::Create<HighGuid::Corpse>(mapId, 0, guid));
195
196 SetObjectScale(1.0f);
197 SetDisplayId(fields[5].GetUInt32());
198 std::vector<std::string_view> items = Trinity::Tokenize(fields[6].GetStringView(), ' ', false);
199 if (items.size() == m_corpseData->Items.size())
200 for (size_t index = 0; index < m_corpseData->Items.size(); ++index)
201 SetItem(index, Trinity::StringTo<uint32>(items[index]).value_or(0));
202
203 SetRace(fields[7].GetUInt8());
204 SetClass(fields[8].GetUInt8());
205 SetSex(fields[9].GetUInt8());
206 ReplaceAllFlags(fields[10].GetUInt8());
207 ReplaceAllCorpseDynamicFlags(CorpseDynFlags(fields[11].GetUInt8()));
208 SetOwnerGUID(ObjectGuid::Create<HighGuid::Player>(fields[15].GetUInt64()));
209 SetFactionTemplate(sChrRacesStore.AssertEntry(m_corpseData->RaceID)->FactionID);
210
211 m_time = time_t(fields[12].GetUInt32());
212
213 uint32 instanceId = fields[14].GetUInt32();
214
215 // place
216 SetLocationInstanceId(instanceId);
217 SetLocationMapId(mapId);
218 Relocate(posX, posY, posZ, o);
219
220 if (!IsPositionValid())
221 {
222 TC_LOG_ERROR("entities.player", "Corpse ({}, owner: {}) is not created, given coordinates are not valid (X: {}, Y: {}, Z: {})",
223 GetGUID().ToString(), GetOwnerGUID().ToString(), posX, posY, posZ);
224 return false;
225 }
226
228 return true;
229}
230
231bool Corpse::IsExpired(time_t t) const
232{
233 // Deleted character
234 if (!sCharacterCache->HasCharacterCacheEntry(GetOwnerGUID()))
235 return true;
236
237 if (m_type == CORPSE_BONES)
238 return m_time < t - 60 * MINUTE;
239 else
240 return m_time < t - 3 * DAY;
241}
242
244{
245 m_objectData->WriteCreate(flags, data, target, this);
246 m_corpseData->WriteCreate(flags, data, target, this);
247}
248
250{
252
254 m_objectData->WriteUpdate(flags, data, target, this);
255
257 m_corpseData->WriteUpdate(flags, data, target, this);
258}
259
261 UF::CorpseData::Mask const& requestedCorpseMask, Player const* target, bool ignoreNestedChangesMask) const
262{
265 if (requestedObjectMask.IsAnySet())
266 valuesMask.Set(TYPEID_OBJECT);
267
268 if (requestedCorpseMask.IsAnySet())
269 valuesMask.Set(TYPEID_CORPSE);
270
272 std::size_t sizePos = buffer.wpos();
273 buffer << uint32(0);
275 buffer << uint32(valuesMask.GetBlock(0));
276
277 if (valuesMask[TYPEID_OBJECT])
278 m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, ignoreNestedChangesMask);
279
280 if (valuesMask[TYPEID_CORPSE])
281 m_corpseData->WriteUpdate(requestedCorpseMask, buffer, target, this, ignoreNestedChangesMask);
282
283 buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
284
285 data->AddUpdateBlock();
286}
287
298
#define sCharacterCache
@ CHAR_DEL_CORPSE_CUSTOMIZATIONS
@ CHAR_INS_CORPSE_PHASES
@ CHAR_INS_CORPSE_CUSTOMIZATIONS
@ CHAR_DEL_CORPSE
@ CHAR_DEL_CORPSE_PHASES
@ CHAR_INS_CORPSE
@ MINUTE
Definition Common.h:32
@ DAY
Definition Common.h:34
CorpseType
Definition Corpse.h:30
@ CORPSE_BONES
Definition Corpse.h:31
DB2Storage< ChrRacesEntry > sChrRacesStore("ChrRaces.db2", &ChrRacesLoadInfo::Instance)
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
uint16 flags
#define ASSERT
Definition Errors.h:80
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
@ TYPEID_OBJECT
Definition ObjectGuid.h:38
@ TYPEID_CORPSE
Definition ObjectGuid.h:48
CorpseDynFlags
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
WowCS::EntityFragmentsHolder m_entityFragments
Definition BaseEntity.h:353
UF::UpdateFieldHolder m_values
Definition BaseEntity.h:205
bool IsInWorld() const
Definition BaseEntity.h:158
void _Create(ObjectGuid const &guid)
Definition BaseEntity.h:218
CreateObjectBits m_updateFlag
Definition BaseEntity.h:352
ByteBuffer & PrepareValuesUpdateBuffer(UpdateData *data) const
TypeID m_objectTypeId
Definition BaseEntity.h:351
virtual UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const *target) const
size_t wpos() const
Definition ByteBuffer.h:461
void put(std::size_t pos, T value)
Definition ByteBuffer.h:260
CellCoord _cellCoord
Definition Corpse.h:144
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer &data, Player const *target) const override
Definition Corpse.cpp:249
bool IsExpired(time_t t) const
Definition Corpse.cpp:231
void ReplaceAllFlags(uint32 flags)
Definition Corpse.h:107
void SaveToDB()
Definition Corpse.cpp:106
void SetRace(uint8 race)
Definition Corpse.h:104
void SetClass(uint8 playerClass)
Definition Corpse.h:105
void ResetGhostTime()
Definition Corpse.cpp:178
Corpse(CorpseType type=CORPSE_BONES)
Definition Corpse.cpp:34
void SetSex(uint8 sex)
Definition Corpse.h:106
void SetDisplayId(uint32 displayId)
Definition Corpse.h:103
Player * lootRecipient
Definition Corpse.h:135
CorpseType m_type
Definition Corpse.h:142
void ClearValuesChangesMask() override
Definition Corpse.cpp:299
void SetFactionTemplate(int32 factionTemplate)
Definition Corpse.h:108
void RemoveFromWorld() override
Definition Corpse.cpp:58
void SetOwnerGUID(ObjectGuid owner)
Definition Corpse.h:100
UF::UpdateField< UF::CorpseData, int32(WowCS::EntityFragment::CGObject), TYPEID_CORPSE > m_corpseData
Definition Corpse.h:139
void Update(uint32 diff) override
Definition Corpse.cpp:98
std::unique_ptr< Loot > m_loot
Definition Corpse.h:132
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer &data, Player const *target) const override
Definition Corpse.cpp:243
void AddToWorld() override
Definition Corpse.cpp:49
time_t m_time
Definition Corpse.h:143
~Corpse()
Definition Corpse.cpp:47
void ReplaceAllCorpseDynamicFlags(CorpseDynFlags dynamicFlags)
Definition Corpse.h:96
ObjectGuid GetOwnerGUID() const override
Definition Corpse.h:99
bool LoadCorpseFromDB(ObjectGuid::LowType guid, Field *fields)
Definition Corpse.cpp:183
void BuildValuesUpdateForPlayerWithMask(UpdateData *data, UF::ObjectData::Mask const &requestedObjectMask, UF::CorpseData::Mask const &requestedCorpseMask, Player const *target, bool ignoreNestedChangesMask) const
Definition Corpse.cpp:260
bool Create(ObjectGuid::LowType guidlow, Map *map)
Definition Corpse.cpp:67
CorpseType GetType() const
Definition Corpse.h:127
void DeleteFromDB(CharacterDatabaseTransaction trans)
Definition Corpse.cpp:158
void SetItem(uint32 slot, uint32 item)
Definition Corpse.h:111
Class used to access individual fields of database query result.
Definition Field.h:94
float GetFloat() const noexcept
Definition Field.cpp:85
uint32 GetUInt32() const noexcept
Definition Field.cpp:57
uint16 GetUInt16() const noexcept
Definition Field.cpp:43
Definition Map.h:225
MapStoredObjectTypesContainer & GetObjectsStore()
Definition Map.h:458
uint32 GetId() const
Definition Map.cpp:3257
LowType GetCounter() const
Definition ObjectGuid.h:336
uint64 LowType
Definition ObjectGuid.h:321
void AddToWorld() override
Definition Object.cpp:83
void BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer &data, EnumFlag< UF::UpdateFieldFlag > flags) const
Definition Object.cpp:113
virtual void ClearValuesChangesMask()
Definition Object.cpp:130
virtual void SetObjectScale(float scale)
Definition Object.h:93
UF::UpdateField< UF::ObjectData, int32(WowCS::EntityFragment::CGObject), TYPEID_OBJECT > m_objectData
Definition Object.h:161
PhaseContainer const & GetPhases() const
Definition PhaseShift.h:101
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6283
void setUInt16(uint8 index, uint16 value)
void setString(uint8 index, std::string &&value)
void setUInt32(uint8 index, uint32 value)
void setFloat(uint8 index, float value)
void setUInt64(uint8 index, uint64 value)
void setUInt8(uint8 index, uint8 value)
Mask const & GetChangesMask() const
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
bool HasChanged(uint32 index) const
Definition BaseEntity.h:83
uint32 GetChangedObjectTypeMask() const
Definition BaseEntity.h:81
bool BuildPacket(WorldPacket *packet)
void AddUpdateBlock()
Definition UpdateData.h:46
constexpr uint32 GetBlock(uint32 index) const
Definition UpdateMask.h:59
constexpr void Set(uint32 index)
Definition UpdateMask.h:91
constexpr uint32 GetMapId() const
Definition Position.h:216
Map * GetMap() const
Definition Object.h:411
void RemoveFromWorld() override
Definition Object.cpp:371
void SetLocationInstanceId(uint32 _instanceId)
Definition Object.h:601
PhaseShift & GetPhaseShift()
Definition Object.h:310
void SetLocationMapId(uint32 _mapId)
Definition Object.h:600
uint32 GetInstanceId() const
Definition Object.h:308
std::string const & GetName() const
Definition Object.h:342
virtual void Update(uint32 diff)
Definition Object.cpp:245
time_t GetGameTime()
Definition GameTime.cpp:52
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Util.cpp:57
CellCoord ComputeCellCoord(float x, float y)
UpdateFieldFlag
Definition UpdateField.h:37
void operator()(Player const *player) const
Definition Corpse.cpp:288
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
std::string ToString() const
Definition Position.cpp:202
bool IsPositionValid() const
Definition Position.cpp:42
constexpr void Relocate(float x, float y)
Definition Position.h:74
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
bool Insert(ValueType< ObjectType > object)
bool Remove(ValueType< ObjectType > object)
void Add(EntityFragment fragment, bool update, void const *data=nullptr)