[9290] Some cleanups in realmd, no functional changes
[getmangos.git] / src / game / Corpse.cpp
blobbe3d9ae9f88a32d75c1284c38356a64499274c3d
1 /*
2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Corpse.h"
21 #include "Player.h"
22 #include "UpdateMask.h"
23 #include "ObjectAccessor.h"
24 #include "ObjectDefines.h"
25 #include "Database/DatabaseEnv.h"
26 #include "Opcodes.h"
27 #include "GossipDef.h"
28 #include "World.h"
30 Corpse::Corpse(CorpseType type) : WorldObject()
32 m_objectType |= TYPEMASK_CORPSE;
33 m_objectTypeId = TYPEID_CORPSE;
35 m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
37 m_valuesCount = CORPSE_END;
39 m_type = type;
41 m_time = time(NULL);
43 lootForBody = false;
46 Corpse::~Corpse()
50 void Corpse::AddToWorld()
52 ///- Register the corpse for guid lookup
53 if(!IsInWorld())
54 sObjectAccessor.AddObject(this);
56 Object::AddToWorld();
59 void Corpse::RemoveFromWorld()
61 ///- Remove the corpse from the accessor
62 if(IsInWorld())
63 sObjectAccessor.RemoveObject(this);
65 Object::RemoveFromWorld();
68 bool Corpse::Create( uint32 guidlow )
70 Object::_Create(guidlow, 0, HIGHGUID_CORPSE);
71 return true;
74 bool Corpse::Create( uint32 guidlow, Player *owner)
76 ASSERT(owner);
78 WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
79 Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
81 //we need to assign owner's map for corpse
82 //in other way we will get a crash in Corpse::SaveToDB()
83 SetMap(owner->GetMap());
85 if(!IsPositionValid())
87 sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
88 guidlow, owner->GetName(), owner->GetPositionX(), owner->GetPositionY());
89 return false;
92 SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
93 SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() );
95 m_grid = MaNGOS::ComputeGridPair(GetPositionX(), GetPositionY());
97 return true;
100 void Corpse::SaveToDB()
102 // prevent DB data inconsistence problems and duplicates
103 CharacterDatabase.BeginTransaction();
104 DeleteFromDB();
106 std::ostringstream ss;
107 ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
108 << GetGUIDLow() << ", "
109 << GUID_LOPART(GetOwnerGUID()) << ", "
110 << GetPositionX() << ", "
111 << GetPositionY() << ", "
112 << GetPositionZ() << ", "
113 << GetOrientation() << ", "
114 << GetZoneId() << ", "
115 << GetMapId() << ", '";
116 for(uint16 i = 0; i < m_valuesCount; ++i )
117 ss << GetUInt32Value(i) << " ";
118 ss << "',"
119 << uint64(m_time) <<", "
120 << uint32(GetType()) << ", "
121 << int(GetInstanceId()) << ", "
122 << uint16(GetPhaseMask()) << ")"; // prevent out of range error
123 CharacterDatabase.Execute( ss.str().c_str() );
124 CharacterDatabase.CommitTransaction();
127 void Corpse::DeleteBonesFromWorld()
129 assert(GetType() == CORPSE_BONES);
130 Corpse* corpse = GetMap()->GetCorpse(GetGUID());
132 if (!corpse)
134 sLog.outError("Bones %u not found in world.", GetGUIDLow());
135 return;
138 AddObjectToRemoveList();
141 void Corpse::DeleteFromDB()
143 if(GetType() == CORPSE_BONES)
144 // only specific bones
145 CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow());
146 else
147 // all corpses (not bones)
148 CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
151 bool Corpse::LoadFromDB(uint32 guid, QueryResult *result)
153 bool external = (result != NULL);
154 if (!external)
155 // 0 1 2 3 4 5 6 7 8 9
156 result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
158 if( !result )
160 sLog.outError("Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid);
161 return false;
164 Field *fields = result->Fetch();
166 if(!LoadFromDB(guid, fields))
168 if (!external)
169 delete result;
171 return false;
174 if (!external)
175 delete result;
177 return true;
180 bool Corpse::LoadFromDB(uint32 guid, Field *fields)
182 // 0 1 2 3 4 5 6 7 8 9
183 //result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
184 float positionX = fields[0].GetFloat();
185 float positionY = fields[1].GetFloat();
186 float positionZ = fields[2].GetFloat();
187 float ort = fields[3].GetFloat();
188 uint32 mapid = fields[4].GetUInt32();
190 Object::_Create(guid, 0, HIGHGUID_CORPSE);
192 if(!LoadValues( fields[5].GetString() ))
194 sLog.outError("Corpse #%d have broken data in `data` field. Can't be loaded.",guid);
195 return false;
198 m_time = time_t(fields[6].GetUInt64());
199 m_type = CorpseType(fields[7].GetUInt32());
201 if(m_type >= MAX_CORPSE_TYPE)
203 sLog.outError("Corpse (guidlow %d, owner %d) have wrong corpse type, not load.",GetGUIDLow(),GUID_LOPART(GetOwnerGUID()));
204 return false;
207 uint32 instanceid = fields[8].GetUInt32();
208 uint32 phaseMask = fields[9].GetUInt32();
210 // overwrite possible wrong/corrupted guid
211 SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
213 // place
214 SetLocationInstanceId(instanceid);
215 SetLocationMapId(mapid);
216 SetPhaseMask(phaseMask, false);
217 Relocate(positionX, positionY, positionZ, ort);
219 if(!IsPositionValid())
221 sLog.outError("Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
222 GetGUIDLow(), GUID_LOPART(GetOwnerGUID()), GetPositionX(), GetPositionY());
223 return false;
226 m_grid = MaNGOS::ComputeGridPair(GetPositionX(), GetPositionY());
228 return true;
231 bool Corpse::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const
233 return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(viewPoint, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);