TrinityCore
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 <sstream>
32
33Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES), m_type(type)
34{
37
39
41
42 lootRecipient = nullptr;
43}
44
46
48{
50 if (!IsInWorld())
52
54}
55
57{
59 if (IsInWorld())
61
63}
64
66{
67 Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(map->GetId(), 0, guidlow));
68 return true;
69}
70
72{
73 ASSERT(owner);
74
75 Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
76
77 if (!IsPositionValid())
78 {
79 TC_LOG_ERROR("entities.player", "Corpse (guidlow {}, owner {}) not created. Suggested coordinates isn't valid (X: {} Y: {})",
80 guidlow, owner->GetName(), owner->GetPositionX(), owner->GetPositionY());
81 return false;
82 }
83
84 Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(owner->GetMapId(), 0, guidlow));
85
86 SetObjectScale(1.0f);
87 SetOwnerGUID(owner->GetGUID());
88
90
92
93 return true;
94}
95
97{
99
100 if (m_loot)
101 m_loot->Update();
102}
103
105{
106 // prevent DB data inconsistence problems and duplicates
107 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
108 DeleteFromDB(trans);
109
110 std::ostringstream items;
111 for (size_t index = 0; index < m_corpseData->Items.size(); ++index)
112 items << m_corpseData->Items[index] << ' ';
113
114 uint16 index = 0;
116 stmt->setUInt64(index++, GetOwnerGUID().GetCounter()); // guid
117 stmt->setFloat (index++, GetPositionX()); // posX
118 stmt->setFloat (index++, GetPositionY()); // posY
119 stmt->setFloat (index++, GetPositionZ()); // posZ
120 stmt->setFloat (index++, GetOrientation()); // orientation
121 stmt->setUInt16(index++, GetMapId()); // mapId
122 stmt->setUInt32(index++, m_corpseData->DisplayID); // displayId
123 stmt->setString(index++, items.str()); // itemCache
124 stmt->setUInt8 (index++, m_corpseData->RaceID); // race
125 stmt->setUInt8 (index++, m_corpseData->Class); // class
126 stmt->setUInt8 (index++, m_corpseData->Sex); // gender
127 stmt->setUInt8 (index++, m_corpseData->Flags); // flags
128 stmt->setUInt8 (index++, m_corpseData->DynamicFlags); // dynFlags
129 stmt->setUInt32(index++, uint32(m_time)); // time
130 stmt->setUInt8 (index++, GetType()); // corpseType
131 stmt->setUInt32(index++, GetInstanceId()); // instanceId
132 trans->Append(stmt);
133
134 for (PhaseShift::PhaseRef const& phase : GetPhaseShift().GetPhases())
135 {
136 index = 0;
137 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE_PHASES);
138 stmt->setUInt64(index++, GetOwnerGUID().GetCounter()); // OwnerGuid
139 stmt->setUInt32(index++, phase.Id); // PhaseId
140 trans->Append(stmt);
141 }
142
143 for (UF::ChrCustomizationChoice customization : m_corpseData->Customizations)
144 {
145 index = 0;
146 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE_CUSTOMIZATIONS);
147 stmt->setUInt64(index++, GetOwnerGUID().GetCounter()); // OwnerGuid
148 stmt->setUInt32(index++, customization.ChrCustomizationOptionID);
149 stmt->setUInt32(index++, customization.ChrCustomizationChoiceID);
150 trans->Append(stmt);
151 }
152
153 CharacterDatabase.CommitTransaction(trans);
154}
155
157{
158 DeleteFromDB(GetOwnerGUID(), trans);
159}
160
162{
164 stmt->setUInt64(0, ownerGuid.GetCounter());
165 CharacterDatabase.ExecuteOrAppend(trans, stmt);
166
167 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_PHASES);
168 stmt->setUInt64(0, ownerGuid.GetCounter());
169 CharacterDatabase.ExecuteOrAppend(trans, stmt);
170
171 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_CUSTOMIZATIONS);
172 stmt->setUInt64(0, ownerGuid.GetCounter());
173 CharacterDatabase.ExecuteOrAppend(trans, stmt);
174}
175
177{
179}
180
182{
183 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
184 // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, race, class, gender, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?
185
186 float posX = fields[0].GetFloat();
187 float posY = fields[1].GetFloat();
188 float posZ = fields[2].GetFloat();
189 float o = fields[3].GetFloat();
190 uint32 mapId = fields[4].GetUInt16();
191
192 Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(mapId, 0, guid));
193
194 SetObjectScale(1.0f);
195 SetDisplayId(fields[5].GetUInt32());
196 std::vector<std::string_view> items = Trinity::Tokenize(fields[6].GetStringView(), ' ', false);
197 if (items.size() == m_corpseData->Items.size())
198 for (size_t index = 0; index < m_corpseData->Items.size(); ++index)
199 SetItem(index, Trinity::StringTo<uint32>(items[index]).value_or(0));
200
201 SetRace(fields[7].GetUInt8());
202 SetClass(fields[8].GetUInt8());
203 SetSex(fields[9].GetUInt8());
204 ReplaceAllFlags(fields[10].GetUInt8());
205 ReplaceAllCorpseDynamicFlags(CorpseDynFlags(fields[11].GetUInt8()));
206 SetOwnerGUID(ObjectGuid::Create<HighGuid::Player>(fields[15].GetUInt64()));
207 SetFactionTemplate(sChrRacesStore.AssertEntry(m_corpseData->RaceID)->FactionID);
208
209 m_time = time_t(fields[12].GetUInt32());
210
211 uint32 instanceId = fields[14].GetUInt32();
212
213 // place
214 SetLocationInstanceId(instanceId);
215 SetLocationMapId(mapId);
216 Relocate(posX, posY, posZ, o);
217
218 if (!IsPositionValid())
219 {
220 TC_LOG_ERROR("entities.player", "Corpse ({}, owner: {}) is not created, given coordinates are not valid (X: {}, Y: {}, Z: {})",
221 GetGUID().ToString(), GetOwnerGUID().ToString(), posX, posY, posZ);
222 return false;
223 }
224
226 return true;
227}
228
229bool Corpse::IsExpired(time_t t) const
230{
231 // Deleted character
232 if (!sCharacterCache->HasCharacterCacheEntry(GetOwnerGUID()))
233 return true;
234
235 if (m_type == CORPSE_BONES)
236 return m_time < t - 60 * MINUTE;
237 else
238 return m_time < t - 3 * DAY;
239}
240
241void Corpse::BuildValuesCreate(ByteBuffer* data, Player const* target) const
242{
244 std::size_t sizePos = data->wpos();
245 *data << uint32(0);
246 *data << uint8(flags);
247 m_objectData->WriteCreate(*data, flags, this, target);
248 m_corpseData->WriteCreate(*data, flags, this, target);
249 data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
250}
251
252void Corpse::BuildValuesUpdate(ByteBuffer* data, Player const* target) const
253{
255 std::size_t sizePos = data->wpos();
256 *data << uint32(0);
258
260 m_objectData->WriteUpdate(*data, flags, this, target);
261
263 m_corpseData->WriteUpdate(*data, flags, this, target);
264
265 data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
266}
267
269 UF::CorpseData::Mask const& requestedCorpseMask, Player const* target) const
270{
272 if (requestedObjectMask.IsAnySet())
273 valuesMask.Set(TYPEID_OBJECT);
274
275 if (requestedCorpseMask.IsAnySet())
276 valuesMask.Set(TYPEID_CORPSE);
277
279 std::size_t sizePos = buffer.wpos();
280 buffer << uint32(0);
281 buffer << uint32(valuesMask.GetBlock(0));
282
283 if (valuesMask[TYPEID_OBJECT])
284 m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
285
286 if (valuesMask[TYPEID_CORPSE])
287 m_corpseData->WriteUpdate(buffer, requestedCorpseMask, true, this, target);
288
289 buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
290
291 data->AddUpdateBlock();
292}
293
295{
296 UpdateData udata(Owner->GetMapId());
297 WorldPacket packet;
298
300
301 udata.BuildPacket(&packet);
302 player->SendDirectMessage(&packet);
303}
304
305void Corpse::ClearUpdateMask(bool remove)
306{
309}
#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:29
@ DAY
Definition: Common.h:31
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.
Definition: DatabaseEnv.cpp:21
uint8_t uint8
Definition: Define.h:144
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
uint16 flags
Definition: DisableMgr.cpp:49
#define ASSERT
Definition: Errors.h:68
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
@ TYPEID_OBJECT
Definition: ObjectGuid.h:35
@ TYPEID_CORPSE
Definition: ObjectGuid.h:45
@ TYPEMASK_CORPSE
Definition: ObjectGuid.h:65
CorpseDynFlags
size_t wpos() const
Definition: ByteBuffer.h:412
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:220
Definition: Corpse.h:53
CellCoord _cellCoord
Definition: Corpse.h:143
bool IsExpired(time_t t) const
Definition: Corpse.cpp:229
void ReplaceAllFlags(uint32 flags)
Definition: Corpse.h:106
void SaveToDB()
Definition: Corpse.cpp:104
void SetRace(uint8 race)
Definition: Corpse.h:103
void SetClass(uint8 playerClass)
Definition: Corpse.h:104
void ResetGhostTime()
Definition: Corpse.cpp:176
Corpse(CorpseType type=CORPSE_BONES)
Definition: Corpse.cpp:33
void ClearUpdateMask(bool remove) override
Definition: Corpse.cpp:305
void SetSex(uint8 sex)
Definition: Corpse.h:105
void SetDisplayId(uint32 displayId)
Definition: Corpse.h:102
Player * lootRecipient
Definition: Corpse.h:134
CorpseType m_type
Definition: Corpse.h:141
void SetFactionTemplate(int32 factionTemplate)
Definition: Corpse.h:107
void RemoveFromWorld() override
Definition: Corpse.cpp:56
void SetOwnerGUID(ObjectGuid owner)
Definition: Corpse.h:99
void BuildValuesCreate(ByteBuffer *data, Player const *target) const override
Definition: Corpse.cpp:241
UF::UpdateField< UF::CorpseData, 0, TYPEID_CORPSE > m_corpseData
Definition: Corpse.h:138
void Update(uint32 diff) override
Definition: Corpse.cpp:96
std::unique_ptr< Loot > m_loot
Definition: Corpse.h:131
void AddToWorld() override
Definition: Corpse.cpp:47
time_t m_time
Definition: Corpse.h:142
~Corpse()
Definition: Corpse.cpp:45
void ReplaceAllCorpseDynamicFlags(CorpseDynFlags dynamicFlags)
Definition: Corpse.h:95
ObjectGuid GetOwnerGUID() const override
Definition: Corpse.h:98
bool LoadCorpseFromDB(ObjectGuid::LowType guid, Field *fields)
Definition: Corpse.cpp:181
bool Create(ObjectGuid::LowType guidlow, Map *map)
Definition: Corpse.cpp:65
void BuildValuesUpdate(ByteBuffer *data, Player const *target) const override
Definition: Corpse.cpp:252
CorpseType GetType() const
Definition: Corpse.h:126
void DeleteFromDB(CharacterDatabaseTransaction trans)
Definition: Corpse.cpp:156
void SetItem(uint32 slot, uint32 item)
Definition: Corpse.h:110
void BuildValuesUpdateForPlayerWithMask(UpdateData *data, UF::ObjectData::Mask const &requestedObjectMask, UF::CorpseData::Mask const &requestedCorpseMask, Player const *target) const
Definition: Corpse.cpp:268
Class used to access individual fields of database query result.
Definition: Field.h:90
uint16 GetUInt16() const
Definition: Field.cpp:46
float GetFloat() const
Definition: Field.cpp:94
uint32 GetUInt32() const
Definition: Field.cpp:62
Definition: Map.h:189
MapStoredObjectTypesContainer & GetObjectsStore()
Definition: Map.h:422
uint32 GetId() const
Definition: Map.cpp:3228
LowType GetCounter() const
Definition: ObjectGuid.h:293
uint64 LowType
Definition: ObjectGuid.h:278
uint16 m_objectType
Definition: Object.h:401
ObjectGuid const & GetGUID() const
Definition: Object.h:160
bool IsInWorld() const
Definition: Object.h:154
UF::UpdateField< UF::ObjectData, 0, TYPEID_OBJECT > m_objectData
Definition: Object.h:267
CreateObjectBits m_updateFlag
Definition: Object.h:404
virtual void ClearUpdateMask(bool remove)
Definition: Object.cpp:790
UF::UpdateFieldHolder m_values
Definition: Object.h:266
void _Create(ObjectGuid const &guid)
Definition: Object.cpp:101
ByteBuffer & PrepareValuesUpdateBuffer(UpdateData *data) const
Definition: Object.cpp:225
virtual void AddToWorld()
Definition: Object.cpp:107
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
virtual void SetObjectScale(float scale)
Definition: Object.h:165
virtual UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const *target) const
Definition: Object.cpp:770
TypeID m_objectTypeId
Definition: Object.h:403
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:6324
void setUInt64(const uint8 index, const uint64 value)
bool Remove(KEY_TYPE const &handle)
bool Insert(KEY_TYPE const &handle, SPECIFIC_TYPE *obj)
Mask const & GetChangesMask() const
Definition: UpdateField.h:605
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:690
bool HasChanged(uint32 index) const
Definition: UpdateField.h:701
uint32 GetChangedObjectTypeMask() const
Definition: UpdateField.h:696
bool BuildPacket(WorldPacket *packet)
Definition: UpdateData.cpp:40
void AddUpdateBlock()
Definition: UpdateData.h:49
uint32 GetBlock(uint32 index) const
Definition: UpdateMask.h:53
void Set(uint32 index)
Definition: UpdateMask.h:84
constexpr uint32 GetMapId() const
Definition: Position.h:201
Map * GetMap() const
Definition: Object.h:624
void RemoveFromWorld() override
Definition: Object.cpp:1017
void SetLocationInstanceId(uint32 _instanceId)
Definition: Object.h:817
PhaseShift & GetPhaseShift()
Definition: Object.h:523
void SetLocationMapId(uint32 _mapId)
Definition: Object.h:816
uint32 GetInstanceId() const
Definition: Object.h:521
std::string const & GetName() const
Definition: Object.h:555
virtual void Update(uint32 diff)
Definition: Object.cpp:898
time_t GetGameTime()
Definition: GameTime.cpp:44
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Util.cpp:56
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:206
UpdateFieldFlag
Definition: UpdateField.h:34
void operator()(Player const *player) const
Definition: Corpse.cpp:294
bool Stationary
Definition: Object.h:88
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
std::string ToString() const
Definition: Position.cpp:128
bool IsPositionValid() const
Definition: Position.cpp:42
constexpr void Relocate(float x, float y)
Definition: Position.h:63
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78