2008-10-02 16:23:55 -05:00
/*
2009-02-04 12:42:26 +01:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
2009-02-04 12:04:12 +01:00
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
2008-10-02 16:23:55 -05:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2008-10-14 11:57:03 -05:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-02 16:23:55 -05:00
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
2008-10-14 11:57:03 -05:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-02 16:23:55 -05:00
*/
#include "Common.h"
#include "Corpse.h"
#include "Player.h"
#include "UpdateMask.h"
#include "ObjectAccessor.h"
#include "Database/DatabaseEnv.h"
#include "Opcodes.h"
#include "GossipDef.h"
#include "World.h"
Corpse :: Corpse ( CorpseType type ) : WorldObject ()
2009-08-11 16:14:45 -05:00
, m_type ( type )
2008-10-02 16:23:55 -05:00
{
m_objectType |= TYPEMASK_CORPSE ;
m_objectTypeId = TYPEID_CORPSE ;
2009-06-11 00:45:59 -05:00
m_updateFlag = ( UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION );
2008-10-02 16:23:55 -05:00
m_valuesCount = CORPSE_END ;
2009-08-01 19:50:42 +02:00
m_mapId = 0 ;
2008-10-02 16:23:55 -05:00
m_time = time ( NULL );
lootForBody = false ;
2009-08-11 16:14:45 -05:00
if ( type != CORPSE_BONES )
m_isWorldObject = true ;
2008-10-02 16:23:55 -05:00
}
Corpse ::~ Corpse ()
{
}
void Corpse :: AddToWorld ()
{
///- Register the corpse for guid lookup
2009-06-06 20:22:14 -05:00
if ( ! IsInWorld ())
ObjectAccessor :: Instance (). AddObject ( this );
2008-10-02 16:23:55 -05:00
Object :: AddToWorld ();
}
void Corpse :: RemoveFromWorld ()
{
///- Remove the corpse from the accessor
2009-06-06 20:22:14 -05:00
if ( IsInWorld ())
ObjectAccessor :: Instance (). RemoveObject ( this );
2008-10-02 16:23:55 -05:00
Object :: RemoveFromWorld ();
}
bool Corpse :: Create ( uint32 guidlow )
{
Object :: _Create ( guidlow , 0 , HIGHGUID_CORPSE );
return true ;
}
2009-01-31 16:38:50 -06:00
bool Corpse :: Create ( uint32 guidlow , Player * owner )
2008-10-02 16:23:55 -05:00
{
2009-07-16 11:49:00 +08:00
ASSERT ( owner );
2008-10-02 16:23:55 -05:00
2009-07-16 11:49:00 +08:00
//we need to assign owner's map for corpse
//in other way we will get a crash in Corpse::SaveToDB()
SetMap ( owner -> GetMap ());
2009-08-01 00:20:32 +02:00
Relocate ( owner -> GetPositionX (), owner -> GetPositionY (), owner -> GetPositionZ (), owner -> GetOrientation ());
2008-10-02 16:23:55 -05:00
if ( ! IsPositionValid ())
{
2009-03-21 14:28:02 -06:00
sLog . outError ( "Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)" ,
2009-06-06 20:22:14 -05:00
guidlow , owner -> GetName (), owner -> GetPositionX (), owner -> GetPositionY ());
2008-10-02 16:23:55 -05:00
return false ;
}
2009-08-01 00:20:32 +02:00
WorldObject :: _Create ( guidlow , HIGHGUID_CORPSE , owner -> GetPhaseMask ());
2008-10-02 16:23:55 -05:00
SetFloatValue ( OBJECT_FIELD_SCALE_X , 1 );
SetUInt64Value ( CORPSE_FIELD_OWNER , owner -> GetGUID () );
2008-10-14 11:57:03 -05:00
m_grid = Trinity :: ComputeGridPair ( GetPositionX (), GetPositionY ());
2008-10-02 16:23:55 -05:00
return true ;
}
void Corpse :: SaveToDB ()
{
2009-01-31 16:38:50 -06:00
// prevent DB data inconsistence problems and duplicates
2008-10-02 16:23:55 -05:00
CharacterDatabase . BeginTransaction ();
DeleteFromDB ();
std :: ostringstream ss ;
2009-01-31 16:38:50 -06:00
ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
2009-02-27 12:26:40 -06:00
<< GetGUIDLow () << ", "
<< GUID_LOPART ( GetOwnerGUID ()) << ", "
<< GetPositionX () << ", "
<< GetPositionY () << ", "
<< GetPositionZ () << ", "
<< GetOrientation () << ", "
<< GetZoneId () << ", "
<< GetMapId () << ", '" ;
2009-04-29 00:26:07 -05:00
for ( uint16 i = 0 ; i < m_valuesCount ; ++ i )
2008-10-02 16:23:55 -05:00
ss << GetUInt32Value ( i ) << " " ;
2009-02-27 12:26:40 -06:00
ss << "',"
<< uint64 ( m_time ) << ", "
<< uint32 ( GetType ()) << ", "
<< int ( GetInstanceId ()) << ", "
<< uint16 ( GetPhaseMask ()) << ")" ; // prevent out of range error
2008-10-02 16:23:55 -05:00
CharacterDatabase . Execute ( ss . str (). c_str () );
CharacterDatabase . CommitTransaction ();
}
void Corpse :: DeleteBonesFromWorld ()
{
2009-06-06 20:22:14 -05:00
assert ( GetType () == CORPSE_BONES );
2008-10-02 16:23:55 -05:00
Corpse * corpse = ObjectAccessor :: GetCorpse ( * this , GetGUID ());
if ( ! corpse )
{
sLog . outError ( "Bones %u not found in world." , GetGUIDLow ());
return ;
}
AddObjectToRemoveList ();
}
void Corpse :: DeleteFromDB ()
{
if ( GetType () == CORPSE_BONES )
// only specific bones
CharacterDatabase . PExecute ( "DELETE FROM corpse WHERE guid = '%d'" , GetGUIDLow ());
else
// all corpses (not bones)
CharacterDatabase . PExecute ( "DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'" , GUID_LOPART ( GetOwnerGUID ()));
}
2009-08-01 00:20:32 +02:00
/*
2008-10-02 16:23:55 -05:00
bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
{
bool external = (result != NULL);
if (!external)
2009-01-31 16:38:50 -06:00
// 0 1 2 3 4 5 6 7 8 9
result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
2008-10-02 16:23:55 -05:00
2009-06-06 20:22:14 -05:00
if( !result )
2008-10-02 16:23:55 -05:00
{
2009-03-21 14:28:02 -06:00
sLog.outError("Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid);
2008-10-02 16:23:55 -05:00
return false;
}
Field *fields = result->Fetch();
2009-06-06 20:22:14 -05:00
if(!LoadFromDB(guid, fields))
2008-10-02 16:23:55 -05:00
{
2009-06-06 20:22:14 -05:00
if (!external)
delete result;
2008-10-02 16:23:55 -05:00
return false;
}
2009-06-06 20:22:14 -05:00
if (!external)
delete result;
2008-10-02 16:23:55 -05:00
return true;
2009-08-01 00:20:32 +02:00
}*/
2008-10-02 16:23:55 -05:00
2009-08-03 12:52:31 +02:00
bool Corpse :: LoadFromDB ( uint32 guid , Field * fields )
2008-10-02 16:23:55 -05:00
{
2009-01-31 16:38:50 -06:00
// 0 1 2 3 4 5 6 7 8 9
//result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
2008-10-02 16:23:55 -05:00
float positionX = fields [ 0 ]. GetFloat ();
float positionY = fields [ 1 ]. GetFloat ();
float positionZ = fields [ 2 ]. GetFloat ();
float ort = fields [ 3 ]. GetFloat ();
2009-06-05 17:15:54 -05:00
Object :: _Create ( guid , 0 , HIGHGUID_CORPSE );
2008-10-02 16:23:55 -05:00
if ( ! LoadValues ( fields [ 5 ]. GetString () ))
{
2009-03-21 14:28:02 -06:00
sLog . outError ( "Corpse #%d have broken data in `data` field. Can't be loaded." , guid );
2008-10-02 16:23:55 -05:00
return false ;
}
2009-08-03 12:52:31 +02:00
SetMapId ( fields [ 4 ]. GetUInt32 ());
SetInstanceId ( fields [ 8 ]. GetUInt32 ());
2009-08-01 00:20:32 +02:00
2009-06-06 20:22:14 -05:00
m_time = time_t ( fields [ 6 ]. GetUInt64 ());
2009-08-11 17:29:56 -05:00
m_type = CorpseType ( fields [ 7 ]. GetUInt32 ());
2009-06-06 20:22:14 -05:00
2008-10-02 16:23:55 -05:00
if ( m_type >= MAX_CORPSE_TYPE )
{
2009-03-21 14:28:02 -06:00
sLog . outError ( "Corpse (guidlow %d, owner %d) have wrong corpse type, not load." , GetGUIDLow (), GUID_LOPART ( GetOwnerGUID ()));
2008-10-02 16:23:55 -05:00
return false ;
}
2009-06-06 20:22:14 -05:00
2009-08-11 16:14:45 -05:00
if ( m_type != CORPSE_BONES )
m_isWorldObject = true ;
2009-01-31 16:38:50 -06:00
uint32 phaseMask = fields [ 9 ]. GetUInt32 ();
2008-10-02 16:23:55 -05:00
// overwrite possible wrong/corrupted guid
SetUInt64Value ( OBJECT_FIELD_GUID , MAKE_NEW_GUID ( guid , 0 , HIGHGUID_CORPSE ));
2009-06-06 20:22:14 -05:00
SetPhaseMask ( phaseMask , false );
Relocate ( positionX , positionY , positionZ , ort );
2008-10-02 16:23:55 -05:00
if ( ! IsPositionValid ())
{
2009-03-21 14:28:02 -06:00
sLog . outError ( "Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)" ,
2009-06-06 20:22:14 -05:00
GetGUIDLow (), GUID_LOPART ( GetOwnerGUID ()), GetPositionX (), GetPositionY ());
2008-10-02 16:23:55 -05:00
return false ;
}
2008-10-14 11:57:03 -05:00
m_grid = Trinity :: ComputeGridPair ( GetPositionX (), GetPositionY ());
2008-10-02 16:23:55 -05:00
return true ;
}
bool Corpse :: isVisibleForInState ( Player const * u , bool inVisibleList ) const
{
2009-06-06 20:22:14 -05:00
return IsInWorld () && u -> IsInWorld () && IsWithinDistInMap ( u -> m_seer , World :: GetMaxVisibleDistanceForObject () + ( inVisibleList ? World :: GetVisibleObjectGreyDistance () : 0.0f ), false );
2008-10-02 16:23:55 -05:00
}
2009-02-17 20:07:49 -06:00