All pastes #1269326 Raw Edit

GameObject.cpp

public cpp v1 · immutable
#1269326 ·published 2008-11-28 12:32 UTC
rendered paste body
/* *  Ascent Serveur MMORPG * Copyright (C) 2005-2008 Ascent Team <http://www.ascentemu.com/> * Copyright (C) 2007-2008 AscentFR Team <http://www.ascentfr.fr/> * * Ce programme est un logiciel libre: vous pouvez le redistribuer ou le modifier. *Selon les termes de la GNU General Public License Affero tel que publi par * la Software Foundation, soit la version 3 de la licence, ou * toute version ultrieure. * * Ce programme est distribu dans l'espoir qu'il sera utile, * Mais SANS AUCUNE GARANTIE; sans mme la garantie implicite de * Marchande ou d'adquation   un usage particulier. Voir le * Affero GNU General Public License pour plus de dtails. * * Vous devez avoir reu une copie de la GNU General Public License Affero * Avec ce programme. Si non, voir <http://www.gnu.org/licenses/>. * */#include "StdAfx.h"GameObject::GameObject(uint64 guid){	m_objectTypeId = TYPEID_GAMEOBJECT;	m_valuesCount = GAMEOBJECT_END;	m_uint32Values = _fields;	memset(m_uint32Values, 0,(GAMEOBJECT_END)*sizeof(uint32));	m_updateMask.SetCount(GAMEOBJECT_END);	SetUInt32Value( OBJECT_FIELD_TYPE,TYPE_GAMEOBJECT|TYPE_OBJECT);	SetUInt64Value( OBJECT_FIELD_GUID,guid);	SetByte(GAMEOBJECT_BYTES_1, 3, 100);	m_wowGuid.Init(GetGUID()); 	SetFloatValue( OBJECT_FIELD_SCALE_X, 1);//info->Size  );	SetByte(GAMEOBJECT_BYTES_1, 3, 100);	counter=0;//not needed at all but to prevent errors that var was not inited, can be removed in release	bannerslot = bannerauraslot = -1;	m_summonedGo = false;	invisible = false;	invisibilityFlag = INVIS_FLAG_NORMAL;	spell = 0;	m_summoner = NULL;	charges = -1;	m_ritualcaster = 0;	m_ritualtarget = 0;	m_ritualmembers = NULL;	m_ritualspell = 0;	m_quests = NULL;	pInfo = NULL;	myScript = NULL;	m_spawn = 0;	loot.gold = 0;	m_deleted = false;	usage_remaining = 1;	m_respawnCell=NULL;	m_battleground = NULL;}GameObject::~GameObject(){	sEventMgr.RemoveEvents(this);	if(m_ritualmembers) {		delete[] m_ritualmembers;		m_ritualmembers = NULL;	}	uint32 guid = GetUInt32Value(OBJECT_FIELD_CREATED_BY);	if(guid)	{		Player *plr = objmgr.GetPlayer(guid);		if(plr && plr->GetSummonedObject() == this)			plr->SetSummonedObject(NULL);		if(plr == m_summoner)			m_summoner = 0;	}	if(m_respawnCell!=NULL)		hashmap64_remove(m_respawnCell->_respawnObjects, GetGUID());	if (m_summonedGo && m_summoner)		for(int i = 0; i < 4; i++)			if (m_summoner->m_ObjectSlots[i] == GetLowGUID())				m_summoner->m_ObjectSlots[i] = 0;	if( m_battleground != NULL && m_battleground->GetType() == BATTLEGROUND_ARATHI_BASIN )	{		if( bannerslot >= 0 && static_cast<ArathiBasin*>(m_battleground)->m_controlPoints[bannerslot] == this )			static_cast<ArathiBasin*>(m_battleground)->m_controlPoints[bannerslot] = NULL;		if( bannerauraslot >= 0 && static_cast<ArathiBasin*>(m_battleground)->m_controlPointAuras[bannerauraslot] == this )			static_cast<ArathiBasin*>(m_battleground)->m_controlPointAuras[bannerauraslot] = NULL;	}}bool GameObject::CreateFromProto(uint32 entry,uint32 mapid, float x, float y, float z, float ang){	pInfo= GameObjectNameStorage.LookupEntry(entry);	if(!pInfo)return false;	Object::_Create( mapid, x, y, z, ang );	SetUInt32Value( OBJECT_FIELD_ENTRY, entry );		SetFloatValue( GAMEOBJECT_POS_X, x );	SetFloatValue( GAMEOBJECT_POS_Y, y );	SetFloatValue( GAMEOBJECT_POS_Z, z );	SetFloatValue( GAMEOBJECT_FACING, ang );	SetRotation(ang);	 	//SetUInt32Value( GAMEOBJECT_TIMESTAMP, (uint32)UNIXTIME);//    SetUInt32Value( GAMEOBJECT_ARTKIT, 0 );		   //these must be from wdb somewhere i guess   SetByte( GAMEOBJECT_BYTES_1, 3, 0 );	SetByte( GAMEOBJECT_BYTES_1, 0, 1 );	SetUInt32Value( GAMEOBJECT_DISPLAYID, pInfo->DisplayID );	SetByte( GAMEOBJECT_BYTES_1, 1, pInfo->Type );   	InitAI();	 return true;	/*	original_flags = m_uint32Values[GAMEOBJECT_FLAGS];	original_state = m_uint32Values[GAMEOBJECT_BYTES_1, 0];	*/}/*void GameObject::Create(uint32 mapid, float x, float y, float z, float ang){	Object::_Create( mapid, x, y, z, ang);	SetFloatValue( GAMEOBJECT_POS_X, x);	SetFloatValue( GAMEOBJECT_POS_Y, y );	SetFloatValue( GAMEOBJECT_POS_Z, z );	SetFloatValue( GAMEOBJECT_FACING, ang );	//SetUInt32Value( GAMEOBJECT_TIMESTAMP, (uint32)time(NULL));}void GameObject::Create( uint32 guidlow, uint32 guidhigh,uint32 displayid, uint8 state, uint32 entryid, float scale,uint32 typeId, uint32 type,uint32 flags, uint32 mapid, float x, float y, float z, float ang ){	Object::_Create( mapid, x, y, z, ang);	SetUInt32Value( OBJECT_FIELD_ENTRY, entryid );	SetFloatValue( OBJECT_FIELD_SCALE_X, scale );	SetUInt32Value( GAMEOBJECT_DISPLAYID, displayid );	SetByte( GAMEOBJECT_BYTES_1, 0, state  );	SetByte( GAMEOBJECT_BYTES_1, 1, typeId  );	SetUInt32Value( GAMEOBJECT_FLAGS, flags );}*/void GameObject::EventCastSpell(uint32 guid, uint32 sp, bool triggered){	Spell * spp =SpellPool.PooledNew();	spp->Init((Object*)this,dbcSpell.LookupEntry(sp),false,NULL);	SpellCastTargets tars( guid);	spp->prepare(&tars);}void GameObject::TrapSearchTarget(){	Update(100);}void GameObject::Update(uint32 p_time){	if(m_event_Instanceid != m_instanceId)	{		event_Relocate();		return;	}	if(!IsInWorld())		return;	if(m_deleted)		return;	if(spell && (GetByte(GAMEOBJECT_BYTES_1, 0) == 1))	{		if(checkrate > 1)		{			if(counter++%checkrate)				return;		}		ObjectSet::iterator itr = GetInRangeSetBegin();		ObjectSet::iterator it2 = itr;		ObjectSet::iterator iend = GetInRangeSetEnd();		Unit * pUnit;		float dist;		this->AquireInrangeLock(); //make sure to release lock before exit function !		for(; it2 != iend;)		{			itr = it2;			++it2;			dist = GetDistanceSq((*itr));			if( (*itr) != m_summoner && (*itr)->IsUnit() && dist <= range)			{				pUnit = static_cast<Unit*>(*itr);				if(m_summonedGo)				{					if(!m_summoner)					{						ExpireAndDelete();						return;					}					if(!isAttackable(m_summoner,pUnit))continue;				}								Spell * sp=SpellPool.PooledNew();				sp->Init((Object*)this,spell,true,NULL);				SpellCastTargets tgt((*itr)->GetGUID());				tgt.m_destX = GetPositionX();				tgt.m_destY = GetPositionY();				tgt.m_destZ = GetPositionZ();				sp->prepare(&tgt);				// proc on trap trigger				if( pInfo->Type == GAMEOBJECT_TYPE_TRAP )				{					if( m_summoner != NULL )						m_summoner->HandleProc( PROC_ON_TRAP_TRIGGER, pUnit, spell );				}				if(m_summonedGo)				{					ExpireAndDelete();					this->ReleaseInrangeLock();					return;				}				if(spell->EffectImplicitTargetA[0] == 16 ||					spell->EffectImplicitTargetB[0] == 16)				{					this->ReleaseInrangeLock();					return;	 // on area dont continue.				}			}		}		this->ReleaseInrangeLock();	}}void GameObject::Spawn(MapMgr * m){	PushToWorld(m);		CALL_GO_SCRIPT_EVENT(this, OnSpawn)();}void GameObject::Despawn(uint32 time){	if(!IsInWorld())		return;	loot.items.clear();	//This is for go get deleted while looting	if(m_spawn)	{		SetByte(GAMEOBJECT_BYTES_1, 0, m_spawn->state);		SetUInt32Value(GAMEOBJECT_FLAGS, m_spawn->flags);	}	CALL_GO_SCRIPT_EVENT(this, OnDespawn)();	if(time)	{		/* Get our originiating mapcell */		MapCell * pCell = m_mapCell;		ASSERT(pCell);		hashmap64_put(pCell->_respawnObjects, GetGUID(), NULL);		sEventMgr.RemoveEvents(this);		sEventMgr.AddEvent(m_mapMgr, &MapMgr::EventRespawnGameObject, this, pCell, EVENT_GAMEOBJECT_ITEM_SPAWN, time, 1, 0);		Object::RemoveFromWorld(false);		m_respawnCell=pCell;	}	else	{		Object::RemoveFromWorld(true);		ExpireAndDelete();	}}void GameObject::SaveToDB(){	std::stringstream ss;	ss << "REPLACE INTO gameobject_spawns VALUES("		<< ((m_spawn == NULL) ? 0 : m_spawn->id) << ","		<< GetEntry() << ","		<< GetMapId() << ","		<< GetPositionX() << ","		<< GetPositionY() << ","		<< GetPositionZ() << ","		<< GetOrientation() << ","		<< GetUInt64Value(GAMEOBJECT_ROTATION) << ","		<< GetFloatValue(GAMEOBJECT_PARENTROTATION) << ","		<< GetFloatValue(GAMEOBJECT_PARENTROTATION_02) << ","		<< GetFloatValue(GAMEOBJECT_PARENTROTATION_03) << ","		<< (unsigned short)GetByte(GAMEOBJECT_BYTES_1, 0) << ","		<< GetUInt32Value(GAMEOBJECT_FLAGS) << ","		<< GetUInt32Value(GAMEOBJECT_FACTION) << ","		<< GetFloatValue(OBJECT_FIELD_SCALE_X) << ","		<< "0)";	WorldDatabase.Execute(ss.str().c_str());  /*  std::stringstream ss;	if (!m_sqlid)		m_sqlid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);	ss << "DELETE FROM gameobjects WHERE id=" << m_sqlid;	sDatabase.Execute(ss.str().c_str());	ss.rdbuf()->str("");	ss << "INSERT INTO gameobjects VALUES ( "		<< m_sqlid << ", "		<< m_position.x << ", "		<< m_position.y << ", "		<< m_position.z << ", "		<< m_position.o << ", "		<< GetZoneId() << ", "		<< GetMapId() << ", '";	for( uint32 index = 0; index < m_valuesCount; index ++ )		ss << GetUInt32Value(index) << " ";	ss << "', ";	ss << GetEntry() << ", 0, 0)"; 	sDatabase.Execute( ss.str( ).c_str( ) );*/}void GameObject::SaveToFile(std::stringstream & name){	std::stringstream ss;	ss << "REPLACE INTO gameobject_spawns VALUES("		<< ((m_spawn == NULL) ? 0 : m_spawn->id) << ","		<< GetEntry() << ","		<< GetMapId() << ","		<< GetPositionX() << ","		<< GetPositionY() << ","		<< GetPositionZ() << ","		<< GetOrientation() << ","		<< GetUInt64Value(GAMEOBJECT_ROTATION) << ","		<< GetFloatValue(GAMEOBJECT_PARENTROTATION) << ","		<< GetFloatValue(GAMEOBJECT_PARENTROTATION_02) << ","		<< GetFloatValue(GAMEOBJECT_PARENTROTATION_03) << ","		<< (unsigned short)GetByte(GAMEOBJECT_BYTES_1, 0) << ","		<< GetUInt32Value(GAMEOBJECT_FLAGS) << ","		<< GetUInt32Value(GAMEOBJECT_FACTION) << ","		<< GetFloatValue(OBJECT_FIELD_SCALE_X) << ","		<< "0)";	FILE * OutFile;	OutFile = fopen(name.str().c_str(), "wb");	if (!OutFile) return;	fwrite(ss.str().c_str(),1,ss.str().size(),OutFile);	fclose(OutFile);}void GameObject::InitAI(){		if(!pInfo)		return;		// this fixes those fuckers in booty bay	if(pInfo->SpellFocus == 0 &&		pInfo->sound1 == 0 &&		pInfo->sound2 == 0 &&		pInfo->sound3 != 0 &&		pInfo->sound5 != 3 &&		pInfo->sound9 == 1)		return;	if(pInfo->DisplayID == 1027)//Shaman Shrine	{		if(pInfo->ID != 177964 && pInfo->ID != 153556)		{			//Deactivate			//SetUInt32Value(GAMEOBJECT_DYNAMIC, 0);		}	}	uint32 spellid = 0;	if(pInfo->Type==GAMEOBJECT_TYPE_TRAP)	{			spellid = pInfo->sound3;	}	else if(pInfo->Type == GAMEOBJECT_TYPE_SPELL_FOCUS)	{		// get spellid from attached gameobject - by sound2 field		if( pInfo->sound2 == 0 )			return;		if( GameObjectNameStorage.LookupEntry( pInfo->sound2 ) == NULL )			return;		spellid = GameObjectNameStorage.LookupEntry( pInfo->sound2 )->sound3;	}	else if(pInfo->Type == GAMEOBJECT_TYPE_RITUAL)	{			m_ritualmembers = new uint32[pInfo->SpellFocus];		memset(m_ritualmembers,0,sizeof(uint32)*pInfo->SpellFocus);	}    else if(pInfo->Type == GAMEOBJECT_TYPE_CHEST)    {        Lock *pLock = dbcLock.LookupEntry(GetInfo()->SpellFocus);        if(pLock)        {            for(uint32 i=0; i < 5; i++)            {                if(pLock->locktype[i])                {                    if(pLock->locktype[i] == 2) //locktype;                    {                        //herbalism and mining;                        if(pLock->lockmisc[i] == LOCKTYPE_MINING || pLock->lockmisc[i] == LOCKTYPE_HERBALISM)                        {							CalcMineRemaining(true);                        }                    }                }            }        }    }	else if ( pInfo->Type == GAMEOBJECT_TYPE_FISHINGHOLE )	{		CalcFishRemaining( true );	}	myScript = sScriptMgr.CreateAIScriptClassForGameObject(GetEntry(), this);	// hackfix for bad spell in BWL	if(!spellid || spellid == 22247)		return;	SpellEntry *sp= dbcSpell.LookupEntry(spellid);	if(!sp)	{		spell = NULL;		return;	}	else	{		spell = sp;	}	//ok got valid spell that will be casted on target when it comes close enough	//get the range for that 		float r = 0;	for(uint32 i=0;i<3;i++)	{		if(sp->Effect[i])		{			float t = GetRadius(dbcSpellRadius.LookupEntry(sp->EffectRadiusIndex[i]));			if(t > r)				r = t;		}	}	if(r < 0.1)//no range		r = GetMaxRange(dbcSpellRange.LookupEntry(sp->rangeIndex));	range = r*r;//square to make code faster	checkrate = 20;//once in 2 seconds	}bool GameObject::Load(GOSpawn *spawn){	if(!CreateFromProto(spawn->entry,0,spawn->x,spawn->y,spawn->z,spawn->facing))		return false;	m_spawn = spawn;	SetRotation(spawn->o);	SetUInt32Value(GAMEOBJECT_FLAGS,spawn->flags);//	SetUInt32Value(GAMEOBJECT_LEVEL,spawn->level);	SetByte(GAMEOBJECT_BYTES_1, 0,spawn->state);		if(spawn->faction)	{		SetUInt32Value(GAMEOBJECT_FACTION,spawn->faction);		m_faction = dbcFactionTemplate.LookupEntry(spawn->faction);		if(m_faction)			m_factionDBC = dbcFaction.LookupEntry(m_faction->Faction);	}	SetFloatValue(OBJECT_FIELD_SCALE_X,spawn->scale);	_LoadQuests();	CALL_GO_SCRIPT_EVENT(this, OnCreate)();	CALL_GO_SCRIPT_EVENT(this, OnSpawn)();	InitAI();	_LoadQuests();	return true;}void GameObject::DeleteFromDB(){	if( m_spawn != NULL )		WorldDatabase.Execute("DELETE FROM gameobject_spawns WHERE id=%u", m_spawn->id);}void GameObject::EventCloseDoor(){// gameobject_flags +1 closedoor animate restore the pointer flag.// by cebernic	SetByte(GAMEOBJECT_BYTES_1, 0, 1);  SetUInt32Value(GAMEOBJECT_FLAGS, GetUInt32Value( GAMEOBJECT_FLAGS ) & ~1);}void GameObject::UseFishingNode(Player *player){	sEventMgr.RemoveEvents( this );	if( GetUInt32Value( GAMEOBJECT_FLAGS ) != 32 ) // Clicking on the bobber before something is hooked	{		player->GetSession()->OutPacket( SMSG_FISH_NOT_HOOKED );		EndFishing( player, true );		return;	}		/* Unused code: sAreaStore.LookupEntry(GetMapMgr()->GetAreaID(GetPositionX(),GetPositionY()))->ZoneId*/	uint32 zone = player->GetAreaID();	if( zone == 0 ) // If the player's area ID is 0, use the zone ID instead		zone = player->GetZoneId();	FishingZoneEntry *entry = FishingZoneStorage.LookupEntry( zone );	if( entry == NULL ) // No fishing information found for area or zone, log an error, and end fishing	{		sLog.outError( "ERREUR : Information de la zone de pche pour la zone %d introuvable!", zone );		EndFishing( player, true );		return;	}	uint32 maxskill = entry->MaxSkill;	uint32 minskill = entry->MinSkill;	if( player->_GetSkillLineCurrent( SKILL_FISHING, false ) < maxskill )			player->_AdvanceSkillLine( SKILL_FISHING, float2int32( 1.0f * sWorld.getRate( RATE_SKILLRATE ) ) );	GameObject * school = NULL;	this->AquireInrangeLock(); //make sure to release lock before exit function !	for ( InRangeSet::iterator it = GetInRangeSetBegin(); it != GetInRangeSetEnd(); ++it )	{		if ( (*it) == NULL || (*it)->GetTypeId() != TYPEID_GAMEOBJECT || (*it)->GetByte(GAMEOBJECT_BYTES_1, 1) != GAMEOBJECT_TYPE_FISHINGHOLE)			continue;		school = static_cast<GameObject *>( *it );		if ( !isInRange( school, (float)school->GetInfo()->sound1 ) )		{			school = NULL;			continue;		}		else			break;	}	this->ReleaseInrangeLock();	if ( school != NULL ) // open school loot if school exists	{		lootmgr.FillGOLoot( &school->loot, school->GetEntry(), school->GetMapMgr() ? ( school->GetMapMgr()->iInstanceMode ? true : false ) : false );		player->SendLoot( school->GetGUID(), LOOT_FISHING );		EndFishing( player, false );		school->CatchFish();		if ( !school->CanFish() )			sEventMgr.AddEvent( school, &GameObject::Despawn, ( 1800000 + RandomUInt( 3600000 ) ), EVENT_GAMEOBJECT_EXPIRE, 10000, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT ); // respawn in 30 - 90 minutes	}	else if( Rand( ( ( player->_GetSkillLineCurrent( SKILL_FISHING, true ) - minskill ) * 100 ) / maxskill ) ) // Open loot on success, otherwise FISH_ESCAPED.	{		lootmgr.FillFishingLoot( &loot, zone );		player->SendLoot( GetGUID(), LOOT_FISHING );		EndFishing( player, false );	}	else // Failed	{		player->GetSession()->OutPacket( SMSG_FISH_ESCAPED );		EndFishing( player, true );	}}void GameObject::EndFishing(Player* player, bool abort ){	Spell * spell = player->GetCurrentSpell();		if(spell)	{		if(abort)   // abort becouse of a reason		{			//FIXME: here 'failed' should appear over progress bar			spell->SendChannelUpdate(0);			//spell->cancel();			spell->finish();		}		else		// spell ended		{			spell->SendChannelUpdate(0);			spell->finish();		}	}	if(!abort)		sEventMgr.AddEvent(this, &GameObject::ExpireAndDelete, EVENT_GAMEOBJECT_EXPIRE, 10000, 1,EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);	else		ExpireAndDelete();}void GameObject::FishHooked(Player * player){	WorldPacket  data(12);	data.Initialize(SMSG_GAMEOBJECT_CUSTOM_ANIM); 	data << GetGUID();	data << (uint32)(0); // value < 4	player->GetSession()->SendPacket(&data);	//SetByte(GAMEOBJECT_BYTES_1, 0, 0);	//BuildFieldUpdatePacket(player, GAMEOBJECT_FLAGS, 32);	SetUInt32Value(GAMEOBJECT_FLAGS, 32); }//////////////// Questsvoid GameObject::AddQuest(QuestRelation *Q){	m_quests->push_back(Q);}void GameObject::DeleteQuest(QuestRelation *Q){	list<QuestRelation *>::iterator it;	for( it = m_quests->begin(); it != m_quests->end(); ++it )	{		if( ( (*it)->type == Q->type ) && ( (*it)->qst == Q->qst ) )		{			delete (*it);			m_quests->erase(it);			break;		}	}}Quest* GameObject::FindQuest(uint32 quest_id, uint8 quest_relation){   	list< QuestRelation* >::iterator it;	for( it = m_quests->begin(); it != m_quests->end(); ++it )	{		QuestRelation* ptr = (*it);		if( ( ptr->qst->id == quest_id ) && ( ptr->type & quest_relation ) )		{			return ptr->qst;		}	}	return NULL;}uint16 GameObject::GetQuestRelation(uint32 quest_id){	uint16 quest_relation = 0;	list< QuestRelation* >::iterator it;	for( it = m_quests->begin(); it != m_quests->end(); ++it )	{		if( (*it) != NULL && (*it)->qst->id == quest_id )		{			quest_relation |= (*it)->type;		}	}	return quest_relation;}uint32 GameObject::NumOfQuests(){	return (uint32)m_quests->size();}void GameObject::_LoadQuests(){	sQuestMgr.LoadGOQuests(this);}/////////////////// Summoned Go'svoid GameObject::_Expire(){	sEventMgr.RemoveEvents(this);	if(IsInWorld())		RemoveFromWorld(true);	//sEventMgr.AddEvent(World::getSingletonPtr(), &World::DeleteObject, ((Object*)this), EVENT_DELETE_TIMER, 1000, 1);	delete this;}void GameObject::ExpireAndDelete(){	if(m_deleted)		return;	m_deleted = true;		/* remove any events */	sEventMgr.RemoveEvents(this);	sEventMgr.AddEvent(this, &GameObject::_Expire, EVENT_GAMEOBJECT_EXPIRE, 1, 1,EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);}void GameObject::Deactivate(){	SetUInt32Value(GAMEOBJECT_DYNAMIC, 0);}void GameObject::CallScriptUpdate(){	ASSERT(myScript);	myScript->AIUpdate();}void GameObject::OnPushToWorld(){	Object::OnPushToWorld();}void GameObject::OnRemoveInRangeObject(Object* pObj){	Object::OnRemoveInRangeObject(pObj);	if(m_summonedGo && m_summoner == pObj)	{		for(int i = 0; i < 4; i++)			if (m_summoner->m_ObjectSlots[i] == GetLowGUID())				m_summoner->m_ObjectSlots[i] = 0;		m_summoner = 0;		ExpireAndDelete();	}}void GameObject::RemoveFromWorld(bool free_guid){	WorldPacket data(SMSG_GAMEOBJECT_DESPAWN_ANIM, 8);	data << GetGUID();	SendMessageToSet(&data,true);	sEventMgr.RemoveEvents(this, EVENT_GAMEOBJECT_TRAP_SEARCH_TARGET);	Object::RemoveFromWorld(free_guid);}bool GameObject::HasLoot(){    int count=0;    for(vector<__LootItem>::iterator itr = loot.items.begin(); itr != loot.items.end(); ++itr)	{		if( itr->item.itemproto->Bonding == ITEM_BIND_QUEST || itr->item.itemproto->Bonding == ITEM_BIND_QUEST2 )			continue;		count += (itr)->iItemsCount;	}    return (count>0);}uint32 GameObject::GetGOReqSkill()  {	if(GetEntry() == 180215) return 300;	if(GetInfo() == NULL)		return 0;	Lock *lock = dbcLock.LookupEntry( GetInfo()->SpellFocus );	if(!lock) return 0;	for(uint32 i=0;i<5;i++)		if(lock->locktype[i] == 2 && lock->minlockskill[i])		{			return lock->minlockskill[i];		}	return 0;}void GameObject::SetRotation(float rad){	if (rad > (float)M_PI)		rad -= 2*(float)M_PI;	else if (rad < -(float)M_PI)		rad += 2*(float)M_PI;	float sin = sinf(rad/2.f);	if(sin >= 0)			rad = 1.f + 0.125f * sin;	else		rad = 1.25f + 0.125f * sin;	SetFloatValue(GAMEOBJECT_ROTATION, rad);