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
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 (uint32 itemSlot = 0; itemSlot < m_corpseData->Items.size(); ++itemSlot)
112 items << GetItem(itemSlot) << ' ';
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++, GetDisplayId()); // displayId
123 stmt->setString(index++, std::move(items).str()); // itemCache
124 stmt->setUInt8 (index++, GetRace()); // race
125 stmt->setUInt8 (index++, GetClass()); // class
126 stmt->setUInt8 (index++, GetSex()); // gender
127 stmt->setUInt8 (index++, GetCorpseFlags()); // flags
128 stmt->setUInt8 (index++, GetCorpseDynamicFlags()); // 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
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
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 _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 ReplaceAllCorpseFlags(CorpseFlags(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
225 return true;
226}
227
228bool Corpse::IsExpired(time_t t) const
229{
230 // Deleted character
231 if (!sCharacterCache->HasCharacterCacheEntry(GetOwnerGUID()))
232 return true;
233
234 if (m_type == CORPSE_BONES)
235 return m_time < t - 60 * MINUTE;
236 else
237 return m_time < t - 3 * DAY;
238}
239
241{
242 m_objectData->WriteCreate(flags, data, target, this);
243 m_corpseData->WriteCreate(flags, data, target, this);
244}
245
247{
249
251 m_objectData->WriteUpdate(flags, data, target, this);
252
254 m_corpseData->WriteUpdate(flags, data, target, this);
255}
256
258 UF::CorpseData::Mask const& requestedCorpseMask, Player const* target, bool ignoreNestedChangesMask) const
259{
262 if (requestedObjectMask.IsAnySet())
263 valuesMask.Set(TYPEID_OBJECT);
264
265 if (requestedCorpseMask.IsAnySet())
266 valuesMask.Set(TYPEID_CORPSE);
267
269 std::size_t sizePos = buffer.wpos();
270 buffer << uint32(0);
272 buffer << uint32(valuesMask.GetBlock(0));
273
274 if (valuesMask[TYPEID_OBJECT])
275 m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, ignoreNestedChangesMask);
276
277 if (valuesMask[TYPEID_CORPSE])
278 m_corpseData->WriteUpdate(requestedCorpseMask, buffer, target, this, ignoreNestedChangesMask);
279
280 buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
281
282 data->AddUpdateBlock();
283}
284
295
#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
CorpseFlags
Definition Corpse.h:41
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:72
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:182
@ 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:462
void put(std::size_t pos, T value)
Definition ByteBuffer.h:261
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer &data, Player const *target) const override
Definition Corpse.cpp:246
bool IsExpired(time_t t) const
Definition Corpse.cpp:228
uint32 GetDisplayId() const
Definition Corpse.h:114
void SaveToDB()
Definition Corpse.cpp:104
void SetRace(uint8 race)
Definition Corpse.h:117
void SetClass(uint8 playerClass)
Definition Corpse.h:119
uint8 GetRace() const
Definition Corpse.h:116
void ResetGhostTime()
Definition Corpse.cpp:176
Corpse(CorpseType type=CORPSE_BONES)
Definition Corpse.cpp:34
uint8 GetClass() const
Definition Corpse.h:118
void SetSex(uint8 sex)
Definition Corpse.h:121
void SetDisplayId(uint32 displayId)
Definition Corpse.h:115
Player * lootRecipient
Definition Corpse.h:144
CorpseType m_type
Definition Corpse.h:151
CorpseDynFlags GetCorpseDynamicFlags() const
Definition Corpse.h:101
void ClearValuesChangesMask() override
Definition Corpse.cpp:296
void ReplaceAllCorpseFlags(CorpseFlags flags)
Definition Corpse.h:99
void SetFactionTemplate(int32 factionTemplate)
Definition Corpse.h:123
void RemoveFromWorld() override
Definition Corpse.cpp:58
void SetOwnerGUID(ObjectGuid owner)
Definition Corpse.h:109
UF::UpdateField< UF::CorpseData, int32(WowCS::EntityFragment::CGObject), TYPEID_CORPSE > m_corpseData
Definition Corpse.h:148
void Update(uint32 diff) override
Definition Corpse.cpp:96
std::unique_ptr< Loot > m_loot
Definition Corpse.h:141
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer &data, Player const *target) const override
Definition Corpse.cpp:240
void AddToWorld() override
Definition Corpse.cpp:49
time_t m_time
Definition Corpse.h:152
~Corpse()
Definition Corpse.cpp:47
void ReplaceAllCorpseDynamicFlags(CorpseDynFlags dynamicFlags)
Definition Corpse.h:105
uint32 GetItem(uint32 slot) const
Definition Corpse.h:126
CorpseFlags GetCorpseFlags() const
Definition Corpse.h:95
ObjectGuid GetOwnerGUID() const override
Definition Corpse.h:108
bool LoadCorpseFromDB(ObjectGuid::LowType guid, Field *fields)
Definition Corpse.cpp:181
void BuildValuesUpdateForPlayerWithMask(UpdateData *data, UF::ObjectData::Mask const &requestedObjectMask, UF::CorpseData::Mask const &requestedCorpseMask, Player const *target, bool ignoreNestedChangesMask) const
Definition Corpse.cpp:257
uint8 GetSex() const
Definition Corpse.h:120
bool Create(ObjectGuid::LowType guidlow, Map *map)
Definition Corpse.cpp:67
CorpseType GetType() const
Definition Corpse.h:139
void DeleteFromDB(CharacterDatabaseTransaction trans)
Definition Corpse.cpp:156
void SetItem(uint32 slot, uint32 item)
Definition Corpse.h:127
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:227
MapStoredObjectTypesContainer & GetObjectsStore()
Definition Map.h:463
uint32 GetId() const
Definition Map.cpp:3288
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:6193
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:369
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:243
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
UpdateFieldFlag
Definition UpdateField.h:37
void operator()(Player const *player) const
Definition Corpse.cpp:285
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)