예제 #1
0
void MoonInstanceScript::SetCellForcedStates(float pMinX, float pMaxX, float pMinY, float pMaxY, bool pActivate)
{
	if(pMinX == pMaxX || pMinY == pMaxY)
		return;

	float Y = pMinY;
	while(pMinX < pMaxX)
	{
		while(pMinY < pMaxY)
		{
			MapCell* CurrentCell = mInstance->GetCellByCoords(pMinX, pMinY);
			if(pActivate && CurrentCell == NULL)
			{
				CurrentCell = mInstance->CreateByCoords(pMinX, pMinY);
				if(CurrentCell != NULL)
					CurrentCell->Init(mInstance->GetPosX(pMinX), mInstance->GetPosY(pMinY), mInstance);
			}

			if(CurrentCell != NULL)
				pActivate ? mInstance->AddForcedCell(CurrentCell) : mInstance->RemoveForcedCell(CurrentCell);

			pMinY += 40.0f;
		}

		pMinY = Y;
		pMinX += 40.0f;
	}
}
예제 #2
0
파일: MapMgr.cpp 프로젝트: Chero/abcwow
void MapMgr::SendChatMessageToCellPlayers(Object * obj, WorldPacket * packet, uint32 cell_radius, uint32 langpos, int32 lang, WorldSession * originator)
{
	uint32 cellX = GetPosX(obj->GetPositionX());
	uint32 cellY = GetPosY(obj->GetPositionY());
	uint32 endX = ((cellX+cell_radius) <= _sizeX) ? cellX + cell_radius : (_sizeX-1);
	uint32 endY = ((cellY+cell_radius) <= _sizeY) ? cellY + cell_radius : (_sizeY-1);
	uint32 startX = (cellX-cell_radius) > 0 ? cellX - cell_radius : 0;
	uint32 startY = (cellY-cell_radius) > 0 ? cellY - cell_radius : 0;

	uint32 posX, posY;
	MapCell *cell;
	MapCell::ObjectSet::iterator iter, iend;
	for (posX = startX; posX <= endX; ++posX )
	{
		for (posY = startY; posY <= endY; ++posY )
		{
			cell = GetCell(posX, posY);
			if (cell && cell->HasPlayers() )
			{
				iter = cell->Begin();
				iend = cell->End();
				for(; iter != iend; ++iter)
				{
					if((*iter)->IsPlayer())
					{
						//static_cast< Player* >(*iter)->GetSession()->SendPacket(packet);
						static_cast< Player* >(*iter)->GetSession()->SendChatPacket(packet, langpos, lang, originator);
					}
				}
			}
		}
	}
}
예제 #3
0
파일: MapMgr.cpp 프로젝트: Chero/abcwow
bool MapMgr::_CellActive(uint32 x, uint32 y)
{
	uint32 endX = ((x+1) <= _sizeX) ? x + 1 : (_sizeX-1);
	uint32 endY = ((y+1) <= _sizeY) ? y + 1 : (_sizeY-1);
	uint32 startX = x > 0 ? x - 1 : 0;
	uint32 startY = y > 0 ? y - 1 : 0;
	uint32 posX, posY;

	MapCell *objCell;

	for (posX = startX; posX <= endX; posX++ )
	{
		for (posY = startY; posY <= endY; posY++ )
		{
			objCell = GetCell(posX, posY);

			if (objCell)
			{
				if (objCell->HasPlayers())
				{
					return true;
				}
			}
		}
	}

	return false;
}
예제 #4
0
void SystemManager::select_stage_code_map(int stage_id) {
	vector<MapCell>& map = Stage::GetInstance() -> m_Map;
	map.clear();
	try {
		Kompex::SQLiteDatabase *pDatabase = new Kompex::SQLiteDatabase(m_db_full_path.c_str(), SQLITE_OPEN_READWRITE, 0);
		Kompex::SQLiteStatement *pStmt = new Kompex::SQLiteStatement(pDatabase);

		pStmt -> Sql("SELECT * FROM stage_code_map WHERE stage_id = @stage_id");
		pStmt -> BindInt(1, stage_id);

		while (pStmt -> FetchRow()) {
			MapCell mc;
			CCPoint loc = Stage::GetInstance() -> idx2loc(pStmt -> GetColumnInt("cell_idx"));
			mc.setMapCell(loc, (enumMapCellCode)(pStmt -> GetColumnInt("cell_code")));
			mc.poll_code = (enumMapCellPollCode)(pStmt -> GetColumnInt("cell_poll_code"));
			//mc.setPollCode((enumMapCellPollCode)(pStmt -> GetColumnInt("cell_poll_code")));
			map.push_back(mc);
		}

		delete pStmt;
		delete pDatabase;

	} catch(Kompex::SQLiteException &exception) {
		//std::cerr << "\nException Occured" << std::endl;
		CCLOGERROR("\nException Occured: \n%s", exception.GetString().c_str());
		exception.Show();
	}
}
예제 #5
0
파일: MapMgr.cpp 프로젝트: Chero/abcwow
void MapMgr::UnloadCell(uint32 x,uint32 y)
{
	MapCell * c = GetCell(x,y);
	if(c == NULL || c->HasPlayers() || _CellActive(x,y) || !c->IsUnloadPending()) return;

	sLog.outDetail("Unloading Cell [%d][%d] on map %d (instance %d)...", 
		x,y,_mapId,m_instanceID);

	c->Unload();
}
예제 #6
0
파일: MapMgr.cpp 프로젝트: Thomas195/arcemu
void MapMgr::UnloadCell(uint32 x, uint32 y)
{
	MapCell* c = GetCell(x, y);
	if(c == NULL || c->HasPlayers() || _CellActive(x, y) || !c->IsUnloadPending()) return;

	LOG_DETAIL("Unloading Cell [%u][%u] on map %u (instance %u)...",
	           x, y, _mapId, m_instanceID);

	c->Unload();
}
예제 #7
0
파일: MapMgr.cpp 프로젝트: Chero/abcwow
void MapMgr::ChangeFarsightLocation(Player *plr, DynamicObject *farsight)
{
	if(farsight == 0)
	{
		// We're clearing.
		for(ObjectSet::iterator itr = plr->m_visibleFarsightObjects.begin(); itr != plr->m_visibleFarsightObjects.end();
			++itr)
		{
			if(plr->IsVisible((*itr)) && !plr->CanSee((*itr)))
			{
				// Send destroy
				plr->PushOutOfRange((*itr)->GetNewGUID());
			}
		}
		plr->m_visibleFarsightObjects.clear();
	}
	else
	{
		uint32 cellX = GetPosX(farsight->GetPositionX());
		uint32 cellY = GetPosY(farsight->GetPositionY());
		uint32 endX = (cellX <= _sizeX) ? cellX + 1 : (_sizeX-1);
		uint32 endY = (cellY <= _sizeY) ? cellY + 1 : (_sizeY-1);
		uint32 startX = cellX > 0 ? cellX - 1 : 0;
		uint32 startY = cellY > 0 ? cellY - 1 : 0;
		uint32 posX, posY;
		MapCell *cell;
		Object *obj;
		MapCell::ObjectSet::iterator iter, iend;
		uint32 count;
		for (posX = startX; posX <= endX; ++posX )
		{
			for (posY = startY; posY <= endY; ++posY )
			{
				cell = GetCell(posX, posY);
				if (cell)
				{
					iter = cell->Begin();
					iend = cell->End();
					for(; iter != iend; ++iter)
					{
						obj = (*iter);
						if(!plr->IsVisible(obj) && plr->CanSee(obj) && farsight->GetDistance2dSq(obj) <= m_UpdateDistance)
						{
							ByteBuffer buf;
							count = obj->BuildCreateUpdateBlockForPlayer(&buf, plr);
							plr->PushCreationData(&buf, count);
							plr->m_visibleFarsightObjects.insert(obj);
						}
					}
					
				}
			}
		}
	}
}
예제 #8
0
void Corpse::SetOwner(uint64 guid)
{
	SetUInt64Value(CORPSE_FIELD_OWNER, guid);
	if(guid == 0)
	{
		//notify the MapCell that the Corpse has no more an owner so the MapCell can go idle (if there's nothing else)
		MapCell* cell = GetMapCell();
		if(cell != NULL)
			cell->CorpseGoneIdle(this);
	}
}
예제 #9
0
파일: MapMgr.cpp 프로젝트: Thomas195/arcemu
// Spawns the object too, without which you can not interact with the object
GameObject* MapMgr::CreateAndSpawnGameObject(uint32 entryID, float x, float y, float z, float o, float scale)
{
	GameObjectInfo* goi = GameObjectNameStorage.LookupEntry(entryID);
	if(!goi)
	{
		LOG_DEBUG("Error looking up entry in CreateAndSpawnGameObject");
		return NULL;
	}

	LOG_DEBUG("CreateAndSpawnGameObject: By Entry '%u'", entryID);

	GameObject* go = CreateGameObject(entryID);

	//Player *chr = m_session->GetPlayer();
	uint32 mapid = GetMapId();
	// Setup game object
	go->CreateFromProto(entryID, mapid, x, y, z, o);
	go->SetScale(scale);
	go->InitAI();
	go->PushToWorld(this);

	// Create spawn instance
	GOSpawn* gs = new GOSpawn;
	gs->entry = go->GetEntry();
	gs->facing = go->GetOrientation();
	gs->faction = go->GetFaction();
	gs->flags = go->GetUInt32Value(GAMEOBJECT_FLAGS);
	gs->id = objmgr.GenerateGameObjectSpawnID();
	gs->o = 0.0f;
	gs->o1 = go->GetParentRotation(0);
	gs->o2 = go->GetParentRotation(2);
	gs->o3 = go->GetParentRotation(3);
	gs->scale = go->GetScale();
	gs->x = go->GetPositionX();
	gs->y = go->GetPositionY();
	gs->z = go->GetPositionZ();
	gs->state = go->GetByte(GAMEOBJECT_BYTES_1, 0);
	//gs->stateNpcLink = 0;
	gs->overrides = go->GetOverrides();

	uint32 cx = GetPosX(x);
	uint32 cy = GetPosY(y);

	GetBaseMap()->GetSpawnsListAndCreate(cx, cy)->GOSpawns.push_back(gs);
	go->m_spawn = gs;

	MapCell* mCell = GetCell(cx, cy);

	if(mCell != NULL)
		mCell->SetLoaded();

	return go;
}
예제 #10
0
파일: Level2.cpp 프로젝트: Ikesters/ArcPro
bool ChatHandler::HandleGOPhaseCommand(const char* args, WorldSession* m_session)
{
	char* sPhase = strtok((char*)args, " ");
	if(!sPhase)
		return false;

	uint32 newphase = atoi(sPhase);

	bool Save = false;
	char* pSave = strtok(NULL, " ");
	if(pSave)
		Save = (atoi(pSave) > 0 ? true : false);

	GameObject* go = m_session->GetPlayer()->GetSelectedGo();
	if(!go)
	{
		RedSystemMessage(m_session, "No selected GameObject...");
		return true;
	}

	go->Phase(PHASE_SET, newphase);

	GOSpawn* gs = go->m_spawn;
	if(gs == NULL)
	{
		RedSystemMessage(m_session, "The GameObject got no spawn, not saving and not logging...");
		return true;
	}
	//VLack: We have to have a spawn, or SaveToDB would write a 0 into the first column (ID), and would erroneously overwrite something in the DB.
	//The code which saves creatures is a bit more forgiving, as it creates a new spawn on-demand, but the gameobject code does not.

	gs->phase = go->GetPhase();

	uint32 cx = m_session->GetPlayer()->GetMapMgr()->GetPosX(m_session->GetPlayer()->GetPositionX());
	uint32 cy = m_session->GetPlayer()->GetMapMgr()->GetPosY(m_session->GetPlayer()->GetPositionY());

	MapCell* mCell = m_session->GetPlayer()->GetMapMgr()->GetCell(cx, cy);

	if(mCell != NULL)
		mCell->SetLoaded();

	if(Save == true)
	{
		// If we're saving, create template and add index
		go->SaveToDB();
		go->m_loadedFromDB = true;
	}
	sGMLog.writefromsession(m_session, "phased gameobject %s to %u, entry %u at %u %f %f %f%s", GameObjectNameStorage.LookupEntry(gs->entry)->Name, newphase, gs->entry, m_session->GetPlayer()->GetMapId(), gs->x, gs->y, gs->z, Save ? ", saved in DB" : "");
	return true;
}
예제 #11
0
파일: MapMgr.cpp 프로젝트: Artea/mangos-svn
void MapMgr::RemoveObject(Object *obj)
{
    ASSERT(obj);
    ASSERT(obj->GetMapId() == _mapId);
    ASSERT(obj->GetPositionX() > _minX && obj->GetPositionX() < _maxX);
    ASSERT(obj->GetPositionY() > _minY && obj->GetPositionY() < _maxY);
    ASSERT(_cells);

    sLog.outDetail("Removing object "I64FMT" with type %i from the world.",
        obj->GetGUID(), obj->GetTypeId());

    // That object types are not map objects. TODO: add AI groups here?
    if(obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER)
    {
    // remove updatable flag and exit
        obj->RemoveFromWorld();
        return;
    }

    obj->RemoveFromWorld();

    ObjectMap::iterator itr = _objects.find(obj->GetGUID());
    _objects.erase(itr);

    // remove us from updated objects list
    ObjectSet::iterator updi = _updatedObjects.find(obj);
    if(updi != _updatedObjects.end())
        _updatedObjects.erase(updi);

    MapCell *objCell = obj->GetMapCell();

    obj->SetMapCell(0);
    objCell->RemoveObject(obj);

    for (Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin();
        iter != obj->GetInRangeSetEnd(); iter++)
    {
        (*iter)->RemoveInRangeObject(obj);

        if((*iter)->GetTypeId() == TYPEID_PLAYER)
            obj->DestroyForPlayer( (Player*)*iter );
    }

    obj->ClearInRangeSet();
}
예제 #12
0
파일: MapMgr.cpp 프로젝트: Chero/abcwow
void MapMgr::LoadAllCells()
{
	// eek
	MapCell * cellInfo;
	CellSpawns * spawns;

	for( uint32 x = 0 ; x < _sizeX ; x ++ )
	{
		for( uint32 y = 0 ; y < _sizeY ; y ++ )
		{
			cellInfo = GetCell( x , y );
			
			if( !cellInfo )
			{
				// Cell doesn't exist, create it.
				// There is no spoon. Err... cell.
				cellInfo = Create( x , y );
				cellInfo->Init( x , y , _mapId , this );
				sLog.outDetail( "Created cell [%u,%u] on map %d (instance %d)." , x , y , _mapId , m_instanceID );
				cellInfo->SetActivity( true );
				_map->CellGoneActive( x , y );
				ASSERT( !cellInfo->IsLoaded() );

				spawns = _map->GetSpawnsList( x , y );
				if( spawns )
					cellInfo->LoadObjects( spawns );
			}
			else
			{
				// Cell exists, but is inactive
				if ( !cellInfo->IsActive() )
				{
					sLog.outDetail("Activated cell [%u,%u] on map %d (instance %d).", x, y, _mapId, m_instanceID );
					_map->CellGoneActive( x , y );
					cellInfo->SetActivity( true );

					if (!cellInfo->IsLoaded())
					{
						//sLog.outDetail("Loading objects for Cell [%d][%d] on map %d (instance %d)...", 
						//	posX, posY, this->_mapId, m_instanceID);
						spawns = _map->GetSpawnsList( x , y );
						if( spawns )
							cellInfo->LoadObjects( spawns );
					}
				}
			}
		}
	}
}
예제 #13
0
uint32 MapScriptInterface::GetPlayerCountInRadius(float x, float y, float z /* = 0.0f */, float radius /* = 5.0f */)
{
	// use a cell radius of 2
	uint32 PlayerCount = 0;
	uint32 cellX = mapMgr.GetPosX(x);
	uint32 cellY = mapMgr.GetPosY(y);

	uint32 endX = cellX < _sizeX ? cellX + 1 : _sizeX;
	uint32 endY = cellY < _sizeY ? cellY + 1 : _sizeY;
	uint32 startX = cellX > 0 ? cellX - 1 : 0;
	uint32 startY = cellY > 0 ? cellY - 1 : 0;
	MapCell* pCell;
	ObjectSet::iterator iter, iter_end;

	for(uint32 cx = startX; cx < endX; ++cx)
	{
		for(uint32 cy = startY; cy < endY; ++cy)
		{
			pCell = mapMgr.GetCell(cx, cy);
			if(pCell == 0 || pCell->GetPlayerCount() == 0)
				continue;

			iter = pCell->Begin();
			iter_end = pCell->End();

			for(; iter != iter_end; ++iter)
			{
				if((*iter)->IsPlayer() &&
				        (*iter)->CalcDistance(x, y, (z == 0.0f ? (*iter)->GetPositionZ() : z)) < radius)
				{
					++PlayerCount;
				}
			}
		}
	}

	return PlayerCount;
}
예제 #14
0
bool ChatHandler::HandleGOSpawn(const char *args, WorldSession *m_session)
{
	std::stringstream sstext;

	char* pEntryID = strtok((char*)args, " ");
	if (!pEntryID)
		return false;

	uint32 EntryID  = atoi(pEntryID);

	bool Save = false;
	char* pSave = strtok(NULL, " ");
	if (pSave)
		Save = (atoi(pSave)>0?true:false);

	GameObjectInfo* goi = GameObjectNameStorage.LookupEntry(EntryID);
	if(!goi)
	{
		sstext << "GameObject Info '" << EntryID << "' Not Found" << '\0';
		SystemMessage(m_session, sstext.str().c_str());
		return true;
	}

	sLog.outDebug("Spawning GameObject By Entry '%u'", EntryID);
	sstext << "Spawning GameObject By Entry '" << EntryID << "'" << '\0';
	SystemMessage(m_session, sstext.str().c_str());

	GameObject *go = m_session->GetPlayer()->GetMapMgr()->CreateGameObject(EntryID);

	Player *chr = m_session->GetPlayer();
	uint32 mapid = chr->GetMapId();
	float x = chr->GetPositionX();
	float y = chr->GetPositionY();
	float z = chr->GetPositionZ();
	float o = chr->GetOrientation();

	go->SetInstanceID(chr->GetInstanceID());
	go->CreateFromProto(EntryID,mapid,x,y,z,o);

	/* f**k blizz coordinate system */
	go->SetFloatValue(GAMEOBJECT_ROTATION_02, sinf(o / 2));
	go->SetFloatValue(GAMEOBJECT_ROTATION_03, cosf(o / 2));
	go->PushToWorld(m_session->GetPlayer()->GetMapMgr());

	// Create sapwn instance
	GOSpawn * gs = new GOSpawn;
	gs->entry = go->GetEntry();
	gs->facing = go->GetOrientation();
	gs->faction = go->GetUInt32Value(GAMEOBJECT_FACTION);
	gs->flags = go->GetUInt32Value(GAMEOBJECT_FLAGS);
	gs->id = objmgr.GenerateGameObjectSpawnID();
	gs->o = go->GetFloatValue(GAMEOBJECT_ROTATION);
	gs->o1 = go->GetFloatValue(GAMEOBJECT_ROTATION_01);
	gs->o2 = go->GetFloatValue(GAMEOBJECT_ROTATION_02);
	gs->o3 = go->GetFloatValue(GAMEOBJECT_ROTATION_03);
	gs->scale = go->GetFloatValue(OBJECT_FIELD_SCALE_X);
	gs->x = go->GetPositionX();
	gs->y = go->GetPositionY();
	gs->z = go->GetPositionZ();
	gs->state = go->GetUInt32Value(GAMEOBJECT_STATE);
	//gs->stateNpcLink = 0;

	uint32 cx = m_session->GetPlayer()->GetMapMgr()->GetPosX(m_session->GetPlayer()->GetPositionX());
	uint32 cy = m_session->GetPlayer()->GetMapMgr()->GetPosY(m_session->GetPlayer()->GetPositionY());

	m_session->GetPlayer()->GetMapMgr()->GetBaseMap()->GetSpawnsListAndCreate(cx,cy)->GOSpawns.push_back(gs);
	go->m_spawn = gs;

	MapCell * mCell = m_session->GetPlayer()->GetMapMgr()->GetCell( cx, cy );

	if( mCell != NULL )
		mCell->SetLoaded();

	if(Save == true)
	{
		// If we're saving, create template and add index
		go->SaveToDB();
		go->m_loadedFromDB = true;
	}
	sGMLog.writefromsession( m_session, "spawned gameobject %s, entry %u at %u %f %f %f%s", GameObjectNameStorage.LookupEntry(gs->entry)->Name, gs->entry, m_session->GetPlayer()->GetMapId(), gs->x, gs->y, gs->z, Save ? ", saved in DB" : "" );
	return true;
}
예제 #15
0
파일: MapMgr.cpp 프로젝트: Thomas195/arcemu
void MapMgr::PushObject(Object* obj)
{
	/////////////
	// Assertions
	/////////////
	ARCEMU_ASSERT(obj != NULL);

	// That object types are not map objects. TODO: add AI groups here?
	if(obj->IsItem() || obj->IsContainer())
	{
		// mark object as updatable and exit
		return;
	}

	if(obj->IsCorpse())
	{
		m_corpses.insert(TO< Corpse* >(obj));
	}

	obj->ClearInRangeSet();

	ARCEMU_ASSERT(obj->GetMapId() == _mapId);
	if(!(obj->GetPositionX() < _maxX && obj->GetPositionX() > _minX) ||
	        !(obj->GetPositionY() < _maxY && obj->GetPositionY() > _minY))
	{
		if(obj->IsPlayer())
		{
			Player* plr = TO< Player* >(obj);
			if(plr->GetBindMapId() != GetMapId())
			{
				plr->SafeTeleport(plr->GetBindMapId(), 0, plr->GetBindPositionX(), plr->GetBindPositionY(), plr->GetBindPositionZ(), 0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				return;
			}
			else
			{
				obj->GetPositionV()->ChangeCoords(plr->GetBindPositionX(), plr->GetBindPositionY(), plr->GetBindPositionZ(), 0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				plr->SendTeleportAckMsg(plr->GetPosition());
			}
		}
		else
		{
			obj->GetPositionV()->ChangeCoords(0, 0, 0, 0);
		}
	}

	ARCEMU_ASSERT(obj->GetPositionY() < _maxY && obj->GetPositionY() > _minY);
	ARCEMU_ASSERT(_cells != NULL);

	///////////////////////
	// Get cell coordinates
	///////////////////////

	uint32 x = GetPosX(obj->GetPositionX());
	uint32 y = GetPosY(obj->GetPositionY());

	if(x >= _sizeX || y >= _sizeY)
	{
		if(obj->IsPlayer())
		{
			Player* plr = TO< Player* >(obj);
			if(plr->GetBindMapId() != GetMapId())
			{
				plr->SafeTeleport(plr->GetBindMapId(), 0, plr->GetBindPositionX(), plr->GetBindPositionY(), plr->GetBindPositionZ(), 0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				return;
			}
			else
			{
				obj->GetPositionV()->ChangeCoords(plr->GetBindPositionX(), plr->GetBindPositionY(), plr->GetBindPositionZ(), 0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				plr->SendTeleportAckMsg(plr->GetPosition());
			}
		}
		else
		{
			obj->GetPositionV()->ChangeCoords(0, 0, 0, 0);
		}

		x = GetPosX(obj->GetPositionX());
		y = GetPosY(obj->GetPositionY());
	}

	MapCell* objCell = GetCell(x, y);
	if(objCell == NULL)
	{
		objCell = Create(x, y);
		objCell->Init(x, y, this);
	}
	ARCEMU_ASSERT(objCell != NULL);

	uint32 endX = (x <= _sizeX) ? x + 1 : (_sizeX - 1);
	uint32 endY = (y <= _sizeY) ? y + 1 : (_sizeY - 1);
	uint32 startX = x > 0 ? x - 1 : 0;
	uint32 startY = y > 0 ? y - 1 : 0;
	uint32 posX, posY;
	MapCell* cell;
	//MapCell::ObjectSet::iterator iter;

	ByteBuffer* buf = 0;
	uint32 count;
	Player* plObj;

	if(obj->IsPlayer())
		plObj = TO< Player* >(obj);
	else
		plObj = NULL;

	if(plObj != NULL)
	{
		LOG_DETAIL("Creating player " I64FMT " for himself.", obj->GetGUID());
		ByteBuffer pbuf(10000);
		count = plObj->BuildCreateUpdateBlockForPlayer(&pbuf, plObj);
		plObj->PushCreationData(&pbuf, count);
	}

	//////////////////////
	// Build in-range data
	//////////////////////

	for(posX = startX; posX <= endX; posX++)
	{
		for(posY = startY; posY <= endY; posY++)
		{
			cell = GetCell(posX, posY);
			if(cell)
			{
				UpdateInRangeSet(obj, plObj, cell, &buf);
			}
		}
	}

	//Add to the cell's object list
	objCell->AddObject(obj);

	obj->SetMapCell(objCell);
	//Add to the mapmanager's object list
	if(plObj != NULL)
	{
		m_PlayerStorage[plObj->GetLowGUID()] = plObj;
		UpdateCellActivity(x, y, 2);
	}
	else
	{
		switch(obj->GetTypeFromGUID())
		{
			case HIGHGUID_TYPE_PET:
				m_PetStorage[obj->GetUIdFromGUID()] = TO< Pet* >(obj);
				break;

			case HIGHGUID_TYPE_UNIT:
			case HIGHGUID_TYPE_VEHICLE:
				{
					ARCEMU_ASSERT(obj->GetUIdFromGUID() <= m_CreatureHighGuid);
					CreatureStorage[ obj->GetUIdFromGUID() ] = TO< Creature* >(obj);
					if(TO_CREATURE(obj)->m_spawn != NULL)
					{
						_sqlids_creatures.insert(make_pair(TO_CREATURE(obj)->m_spawn->id, TO_CREATURE(obj)));
					}
				}
				break;

			case HIGHGUID_TYPE_GAMEOBJECT:
				{
					GOStorage[ obj->GetUIdFromGUID() ] = TO< GameObject* >(obj);
					if(TO_GAMEOBJECT(obj)->m_spawn != NULL)
					{
						_sqlids_gameobjects.insert(make_pair(TO_GAMEOBJECT(obj)->m_spawn->id, TO_GAMEOBJECT(obj)));
					}
				}
				break;

			case HIGHGUID_TYPE_DYNAMICOBJECT:
				m_DynamicObjectStorage[obj->GetLowGUID()] = (DynamicObject*)obj;
				break;
		}
	}

	// Handle activation of that object.
	if(objCell->IsActive() && obj->CanActivate())
		obj->Activate(this);

	// Add the session to our set if it is a player.
	if(plObj != NULL)
	{
		Sessions.insert(plObj->GetSession());

		// Change the instance ID, this will cause it to be removed from the world thread (return value 1)
		plObj->GetSession()->SetInstance(GetInstanceID());

		/* Add the map wide objects */
		if(_mapWideStaticObjects.size())
		{
			uint32 globalcount = 0;
			if(!buf)
				buf = new ByteBuffer(300);

			for(set<Object*>::iterator itr = _mapWideStaticObjects.begin(); itr != _mapWideStaticObjects.end(); ++itr)
			{
				count = (*itr)->BuildCreateUpdateBlockForPlayer(buf, plObj);
				globalcount += count;
			}
			//VLack: It seems if we use the same buffer then it is a BAD idea to try and push created data one by one, add them at once!
			//       If you try to add them one by one, then as the buffer already contains data, they'll end up repeating some object.
			//       Like 6 object updates for Deeprun Tram, but the built package will contain these entries: 2AFD0, 2AFD0, 2AFD1, 2AFD0, 2AFD1, 2AFD2
			if(globalcount > 0) plObj->PushCreationData(buf, globalcount);
		}
	}

	if(buf)
		delete buf;

	if(plObj != NULL && InactiveMoveTime && !forced_expire)
		InactiveMoveTime = 0;
}
예제 #16
0
파일: MapMgr.cpp 프로젝트: Thomas195/arcemu
void MapMgr::RemoveObject(Object* obj, bool free_guid)
{
	/////////////
	// Assertions
	/////////////

	ARCEMU_ASSERT(obj != NULL);
	ARCEMU_ASSERT(obj->GetMapId() == _mapId);
	//ARCEMU_ASSERT(   obj->GetPositionX() > _minX && obj->GetPositionX() < _maxX);
	//ARCEMU_ASSERT(   obj->GetPositionY() > _minY && obj->GetPositionY() < _maxY);
	ARCEMU_ASSERT(_cells != NULL);

	if(obj->IsActive())
		obj->Deactivate(this);

	//there is a very small chance that on double player ports on same update player is added to multiple insertpools but not removed
	//one clear example was the double port proc when exploiting double resurrect
	m_objectinsertlock.Acquire();
	m_objectinsertpool.erase(obj);
	m_objectinsertlock.Release();

	_updates.erase(obj);
	obj->ClearUpdateMask();

	///////////////////////////////////////
	// Remove object from all needed places
	///////////////////////////////////////

	switch(obj->GetTypeFromGUID())
	{
		case HIGHGUID_TYPE_UNIT:
		case HIGHGUID_TYPE_VEHICLE:
			ARCEMU_ASSERT(obj->GetUIdFromGUID() <= m_CreatureHighGuid);
			CreatureStorage[ obj->GetUIdFromGUID() ] = NULL;
			if(TO_CREATURE(obj)->m_spawn != NULL)
			{
				_sqlids_creatures.erase(TO_CREATURE(obj)->m_spawn->id);
			}

			if(free_guid)
				_reusable_guids_creature.push_back(obj->GetUIdFromGUID());

			break;

		case HIGHGUID_TYPE_PET:
			if(pet_iterator != m_PetStorage.end() && pet_iterator->second->GetGUID() == obj->GetGUID())
				++pet_iterator;
			m_PetStorage.erase(obj->GetUIdFromGUID());
			break;

		case HIGHGUID_TYPE_DYNAMICOBJECT:
			m_DynamicObjectStorage.erase(obj->GetLowGUID());
			break;

		case HIGHGUID_TYPE_GAMEOBJECT:
			ARCEMU_ASSERT(obj->GetUIdFromGUID() <= m_GOHighGuid);
			GOStorage[ obj->GetUIdFromGUID() ] = NULL;
			if(TO_GAMEOBJECT(obj)->m_spawn != NULL)
			{
				_sqlids_gameobjects.erase(TO_GAMEOBJECT(obj)->m_spawn->id);
			}

			if(free_guid)
				_reusable_guids_gameobject.push_back(obj->GetUIdFromGUID());

			break;
	}

	// That object types are not map objects. TODO: add AI groups here?
	if(obj->IsItem() || obj->IsContainer())
	{
		return;
	}

	if(obj->IsCorpse())
	{
		m_corpses.erase(TO< Corpse* >(obj));
	}

	MapCell* cell = GetCell(obj->GetMapCellX(), obj->GetMapCellY());
	if(cell == NULL)
	{
		/* set the map cell correctly */
		if(obj->GetPositionX() >= _maxX || obj->GetPositionX() <= _minY ||
		        obj->GetPositionY() >= _maxY || obj->GetPositionY() <= _minY)
		{
			// do nothing
		}
		else
		{
			cell = this->GetCellByCoords(obj->GetPositionX(), obj->GetPositionY());
			obj->SetMapCell(cell);
		}
	}

	if(cell != NULL)
	{
		// Remove object from cell
		cell->RemoveObject(obj);

		// Unset object's cell
		obj->SetMapCell(NULL);
	}

	Player* plObj = NULL;
	// Clear any updates pending
	if(obj->IsPlayer())
	{
		plObj = TO_PLAYER(obj);
		_processQueue.erase(plObj);
		plObj->ClearAllPendingUpdates();
	}

	obj->RemoveSelfFromInrangeSets();

	// Clear object's in-range set
	obj->ClearInRangeSet();

	// If it's a player - update his nearby cells
	if(!_shutdown && obj->IsPlayer())
	{
		// get x/y
		if(obj->GetPositionX() >= _maxX || obj->GetPositionX() <= _minY ||
		        obj->GetPositionY() >= _maxY || obj->GetPositionY() <= _minY)
		{
			// do nothing
		}
		else
		{
			uint32 x = GetPosX(obj->GetPositionX());
			uint32 y = GetPosY(obj->GetPositionY());
			UpdateCellActivity(x, y, 2);
		}
		m_PlayerStorage.erase(TO< Player* >(obj)->GetLowGUID());
	}

	// Remove the session from our set if it is a player.
	if(obj->IsPlayer())
	{
		for(set<Object*>::iterator itr = _mapWideStaticObjects.begin(); itr != _mapWideStaticObjects.end(); ++itr)
		{
			plObj->PushOutOfRange((*itr)->GetNewGUID());
		}

		// Setting an instance ID here will trigger the session to be removed
		// by MapMgr::run(). :)
		plObj->GetSession()->SetInstance(0);

		// Add it to the global session set.
		// Don't "re-add" to session if it is being deleted.
		if(!plObj->GetSession()->bDeleted)
			sWorld.AddGlobalSession(plObj->GetSession());
	}

	if(!HasPlayers())
	{
		if(this->pInstance != NULL && this->pInstance->m_persistent)
			this->pInstance->m_creatorGroup = 0;
		if(!InactiveMoveTime && !forced_expire && GetMapInfo()->type != INSTANCE_NULL)
		{
			InactiveMoveTime = UNIXTIME + (MAPMGR_INACTIVE_MOVE_TIME * 60);
			Log.Debug("MapMgr", "Instance %u is now idle. (%s)", m_instanceID, GetBaseMap()->GetName());
		}
	}
}
예제 #17
0
파일: MapMgr.cpp 프로젝트: Chero/abcwow
void MapMgr::ChangeObjectLocation( Object *obj )
{
	// Items and containers are of no interest for us
	if( obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER || obj->GetMapMgr() != this )
	{
		return;
	}

	Player* plObj;
	ByteBuffer * buf = 0;

	if( obj->GetTypeId() == TYPEID_PLAYER )
	{
		plObj = static_cast< Player* >( obj );
	}
	else
	{
		plObj = NULL;
	}

	Object* curObj;
	float fRange;

	///////////////////////////////////////
	// Update in-range data for old objects
	///////////////////////////////////////

	/** let's duplicate some code here :P Less branching is always good.
	 * - Burlex
	 */
/*#define IN_RANGE_LOOP \
	for (Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin(), iter2; \
		iter != obj->GetInRangeSetEnd();) \
	{ \
		curObj = *iter; \
		iter2 = iter; \
		++iter; \
		if(curObj->IsPlayer() && obj->IsPlayer() && plObj->m_TransporterGUID && plObj->m_TransporterGUID == static_cast< Player* >( curObj )->m_TransporterGUID ) \
			fRange = 0.0f;		\
		else if((curObj->GetGUIDHigh() == HIGHGUID_TRANSPORTER || obj->GetGUIDHigh() == HIGHGUID_TRANSPORTER)) \
			fRange = 0.0f;		\
		else if((curObj->GetGUIDHigh() == HIGHGUID_GAMEOBJECT && curObj->GetUInt32Value(GAMEOBJECT_TYPE_ID) == GAMEOBJECT_TYPE_TRANSPORT || obj->GetGUIDHigh() == HIGHGUID_GAMEOBJECT && obj->GetUInt32Value(GAMEOBJECT_TYPE_ID) == GAMEOBJECT_TYPE_TRANSPORT)) \
			fRange = 0.0f;		\
		else \
			fRange = m_UpdateDistance;	\
		if (curObj->GetDistance2dSq(obj) > fRange && fRange > 0) \

#define END_IN_RANGE_LOOP } \

	if(plObj)
	{
		IN_RANGE_LOOP
		{
			plObj->RemoveIfVisible(curObj);
			plObj->RemoveInRangeObject(iter2);

			if(curObj->NeedsInRangeSet())
				curObj->RemoveInRangeObject(obj);

			if(curObj->IsPlayer())
				static_cast< Player* >( curObj )->RemoveIfVisible(obj);
		}
		END_IN_RANGE_LOOP
	}
	else if(obj->NeedsInRangeSet())
	{
		IN_RANGE_LOOP
		{
			if(curObj->NeedsInRangeSet())
				curObj->RemoveInRangeObject(obj);

			if(curObj->IsPlayer())
				static_cast< Player* >( curObj )->RemoveIfVisible(obj);

			obj->RemoveInRangeObject(iter2);
		}
		END_IN_RANGE_LOOP
	}
	else
	{
		IN_RANGE_LOOP
		{
			if(curObj->NeedsInRangeSet())
				curObj->RemoveInRangeObject(obj);

			if(curObj->IsPlayer())
			{
				static_cast< Player* >( curObj )->RemoveIfVisible(obj);
				obj->RemoveInRangePlayer(curObj);
			}
		}
		END_IN_RANGE_LOOP
	}

#undef IN_RANGE_LOOP
#undef END_IN_RANGE_LOOP*/

	if(obj->HasInRangeObjects()) {
		for (Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin(), iter2;
			iter != obj->GetInRangeSetEnd();)
		{
			curObj = *iter;
			iter2 = iter++;
			if( curObj->IsPlayer() && obj->IsPlayer() && plObj->m_TransporterGUID && plObj->m_TransporterGUID == static_cast< Player* >( curObj )->m_TransporterGUID )
				fRange = 0.0f; // unlimited distance for people on same boat
			else if( curObj->GetTypeFromGUID() == HIGHGUID_TYPE_TRANSPORTER )
				fRange = 0.0f; // unlimited distance for transporters (only up to 2 cells +/- anyway.)
			else
				fRange = m_UpdateDistance; // normal distance

			if( fRange > 0.0f && curObj->GetDistance2dSq(obj) > fRange )
			{
				if( plObj )
					plObj->RemoveIfVisible(curObj);

				if( curObj->IsPlayer() )
					static_cast< Player* >( curObj )->RemoveIfVisible(obj);

				curObj->RemoveInRangeObject(obj);

				if( obj->GetMapMgr() != this )
				{
					/* Something removed us. */
					return;
				}
				obj->RemoveInRangeObject(iter2);
			}
		}
	}

	///////////////////////////
	// Get new cell coordinates
	///////////////////////////
	if(obj->GetMapMgr() != this)
	{
		/* Something removed us. */
		return;
	}

	if(obj->GetPositionX() >= _maxX || obj->GetPositionX() <= _minX ||
		obj->GetPositionY() >= _maxY || obj->GetPositionY() <= _minY)
	{
		if(obj->IsPlayer())
		{
			Player* plr = static_cast< Player* >( obj );
			if(plr->GetBindMapId() != GetMapId())
			{
				plr->SafeTeleport(plr->GetBindMapId(),0,plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				return;
			}
			else
			{
				obj->GetPositionV()->ChangeCoords(plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				WorldPacket * data = plr->BuildTeleportAckMsg(plr->GetPosition());
				plr->GetSession()->SendPacket(data);
				delete data;
			}
		}
		else
		{
			obj->GetPositionV()->ChangeCoords(0,0,0,0);
		}
	}

	uint32 cellX = GetPosX(obj->GetPositionX());
	uint32 cellY = GetPosY(obj->GetPositionY());

	if(cellX >= _sizeX || cellY >= _sizeY)
	{
		return;
	}

	MapCell *objCell = GetCell(cellX, cellY);
	MapCell * pOldCell = obj->GetMapCell();
	if (!objCell)
	{
		objCell = Create(cellX,cellY);
		objCell->Init(cellX, cellY, _mapId, this);
	}

	// If object moved cell
	if (objCell != obj->GetMapCell())
	{
		// THIS IS A HACK!
		// Current code, if a creature on a long waypoint path moves from an active
		// cell into an inactive one, it will disable itself and will never return.
		// This is to prevent cpu leaks. I will think of a better solution very soon :P

		if(!objCell->IsActive() && !plObj && obj->Active)
			obj->Deactivate(this);

		if(obj->GetMapCell())
			obj->GetMapCell()->RemoveObject(obj);
	
		objCell->AddObject(obj);
		obj->SetMapCell(objCell);

		// if player we need to update cell activity
		// radius = 2 is used in order to update both
		// old and new cells
		if(obj->GetTypeId() == TYPEID_PLAYER)
		{
			// have to unlock/lock here to avoid a deadlock situation.
			UpdateCellActivity(cellX, cellY, 2);
			if( pOldCell != NULL )
			{
				// only do the second check if theres -/+ 2 difference
				if( abs( (int)cellX - (int)pOldCell->_x ) > 2 ||
					abs( (int)cellY - (int)pOldCell->_y ) > 2 )
				{
					UpdateCellActivity( pOldCell->_x, pOldCell->_y, 2 );
				}
			}
		}
	}


	//////////////////////////////////////
	// Update in-range set for new objects
	//////////////////////////////////////

	uint32 endX = cellX <= _sizeX ? cellX + 1 : (_sizeX-1);
	uint32 endY = cellY <= _sizeY ? cellY + 1 : (_sizeY-1);
	uint32 startX = cellX > 0 ? cellX - 1 : 0;
	uint32 startY = cellY > 0 ? cellY - 1 : 0;
	uint32 posX, posY;
	MapCell *cell;
	MapCell::ObjectSet::iterator iter;

	for (posX = startX; posX <= endX; ++posX )
	{
		for (posY = startY; posY <= endY; ++posY )
		{
			cell = GetCell(posX, posY);
			if (cell)
			UpdateInRangeSet(obj, plObj, cell, &buf);
		}
	}

	if(buf)
		delete buf;
}
예제 #18
0
파일: MapMgr.cpp 프로젝트: Thomas195/arcemu
void MapMgr::ChangeObjectLocation(Object* obj)
{
	/*
	if ( !obj ) return; // crashfix
	*/

	ARCEMU_ASSERT(obj != NULL);

	// Items and containers are of no interest for us
	if(obj->IsItem() || obj->IsContainer() || obj->GetMapMgr() != this)
	{
		return;
	}

	Player* plObj = NULL;
	ByteBuffer* buf = 0;

	if(obj->IsPlayer())
	{
		plObj = TO< Player* >(obj);
	}

	Object* curObj;
	float fRange = 0.0f;

	///////////////////////////////////////
	// Update in-range data for old objects
	///////////////////////////////////////

	if(obj->HasInRangeObjects())
	{
		for(Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin(); iter != obj->GetInRangeSetEnd();)
		{
			curObj = *iter;
			++iter;

			if(curObj->IsPlayer() && plObj != NULL && plObj->transporter_info.guid && plObj->transporter_info.guid == TO< Player* >(curObj)->transporter_info.guid)
				fRange = 0.0f; // unlimited distance for people on same boat
			else if(curObj->GetTypeFromGUID() == HIGHGUID_TYPE_TRANSPORTER)
				fRange = 0.0f; // unlimited distance for transporters (only up to 2 cells +/- anyway.)
			//If the object announcing its position is a transport, or other special object, then deleting it from visible objects should be avoided. - By: VLack
			else if(obj->IsGameObject() && (TO< GameObject* >(obj)->GetOverrides() & GAMEOBJECT_INFVIS) && obj->GetMapId() == curObj->GetMapId())
				fRange = 0.0f;
			//If the object we're checking for possible removal is a transport or other special object, and we are players on the same map, don't remove it...
			else if(plObj && curObj->IsGameObject() && (TO< GameObject* >(curObj)->GetOverrides() & GAMEOBJECT_INFVIS) && obj->GetMapId() == curObj->GetMapId())
				fRange = 0.0f;
			else if(curObj->IsPlayer() && TO< Player* >(curObj)->GetFarsightTarget() == obj->GetGUID())
				fRange = 0.0f;//Mind Vision, Eye of Kilrogg
			else
				fRange = m_UpdateDistance; // normal distance

			if(fRange > 0.0f && (curObj->GetDistance2dSq(obj) > fRange))
			{
				if(plObj != NULL)
					plObj->RemoveIfVisible(curObj->GetGUID());

				if(curObj->IsPlayer())
					TO< Player* >(curObj)->RemoveIfVisible(obj->GetGUID());

				curObj->RemoveInRangeObject(obj);

				if(obj->GetMapMgr() != this)
				{
					/* Something removed us. */
					return;
				}
				obj->RemoveInRangeObject(curObj);
			}
		}
	}

	///////////////////////////
	// Get new cell coordinates
	///////////////////////////
	if(obj->GetMapMgr() != this)
	{
		/* Something removed us. */
		return;
	}

	if(obj->GetPositionX() >= _maxX || obj->GetPositionX() <= _minX ||
	        obj->GetPositionY() >= _maxY || obj->GetPositionY() <= _minY)
	{
		if(plObj != NULL)
		{
			if(plObj->GetBindMapId() != GetMapId())
			{
				plObj->SafeTeleport(plObj->GetBindMapId(), 0, plObj->GetBindPositionX(), plObj->GetBindPositionY(), plObj->GetBindPositionZ(), 0);
				plObj->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				return;
			}
			else
			{
				obj->GetPositionV()->ChangeCoords(plObj->GetBindPositionX(), plObj->GetBindPositionY(), plObj->GetBindPositionZ(), 0);
				plObj->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				plObj->SendTeleportAckMsg(plObj->GetPosition());
			}
		}
		else
		{
			obj->GetPositionV()->ChangeCoords(0, 0, 0, 0);
		}
	}

	uint32 cellX = GetPosX(obj->GetPositionX());
	uint32 cellY = GetPosY(obj->GetPositionY());

	if(cellX >= _sizeX || cellY >= _sizeY)
	{
		return;
	}

	MapCell* objCell = GetCell(cellX, cellY);
	MapCell* pOldCell = obj->GetMapCell();
	if(objCell == NULL)
	{
		objCell = Create(cellX, cellY);
		objCell->Init(cellX, cellY, this);
	}

	ARCEMU_ASSERT(objCell != NULL);

	// If object moved cell
	if(objCell != pOldCell)
	{
		// THIS IS A HACK!
		// Current code, if a creature on a long waypoint path moves from an active
		// cell into an inactive one, it will disable itself and will never return.
		// This is to prevent cpu leaks. I will think of a better solution very soon :P

		if(!objCell->IsActive() && !plObj && obj->IsActive())
			obj->Deactivate(this);

		if(pOldCell != NULL)
			pOldCell->RemoveObject(obj);

		objCell->AddObject(obj);
		obj->SetMapCell(objCell);

		// if player we need to update cell activity
		// radius = 2 is used in order to update both
		// old and new cells
		if(obj->IsPlayer())
		{
			// have to unlock/lock here to avoid a deadlock situation.
			UpdateCellActivity(cellX, cellY, 2);
			if(pOldCell != NULL)
			{
				// only do the second check if there's -/+ 2 difference
				if(abs((int)cellX - (int)pOldCell->_x) > 2 ||
				        abs((int)cellY - (int)pOldCell->_y) > 2)
				{
					UpdateCellActivity(pOldCell->_x, pOldCell->_y, 2);
				}
			}
		}
	}


	//////////////////////////////////////
	// Update in-range set for new objects
	//////////////////////////////////////

	uint32 endX = cellX <= _sizeX ? cellX + 1 : (_sizeX - 1);
	uint32 endY = cellY <= _sizeY ? cellY + 1 : (_sizeY - 1);
	uint32 startX = cellX > 0 ? cellX - 1 : 0;
	uint32 startY = cellY > 0 ? cellY - 1 : 0;
	uint32 posX, posY;
	MapCell* cell;

	//If the object announcing it's position is a special one, then it should do so in a much wider area - like the distance between the two transport towers in Orgrimmar, or more. - By: VLack
	if(obj->IsGameObject() && (TO< GameObject* >(obj)->GetOverrides() & GAMEOBJECT_ONMOVEWIDE))
	{
		endX = cellX + 5 <= _sizeX ? cellX + 6 : (_sizeX - 1);
		endY = cellY + 5 <= _sizeY ? cellY + 6 : (_sizeY - 1);
		startX = cellX > 5 ? cellX - 6 : 0;
		startY = cellY > 5 ? cellY - 6 : 0;
	}

	for(posX = startX; posX <= endX; ++posX)
	{
		for(posY = startY; posY <= endY; ++posY)
		{
			cell = GetCell(posX, posY);
			if(cell)
				UpdateInRangeSet(obj, plObj, cell, &buf);
		}
	}

	if(buf)
		delete buf;
}
예제 #19
0
bool ChatHandler::HandleVehicleSpawn(const char * args, WorldSession * m_session)
{
	uint32 entry = atol(args);
	uint8 gender = 0; 

	if(entry == 0)
		return false;

	CreatureProto * proto = CreatureProtoStorage.LookupEntry(entry);
	CreatureInfo * info = CreatureNameStorage.LookupEntry(entry);
	if(proto == 0 || info == 0)
	{
		RedSystemMessage(m_session, "Invalid entry id.");
		return true;
	}

	CreatureSpawn * sp = new CreatureSpawn;
	gender = info->GenerateModelId(&sp->displayid);
 	sp->entry = entry; 
	sp->entry = entry;
	sp->form = 0;
	sp->id = objmgr.GenerateCreatureSpawnID();
	sp->movetype = 0;
	sp->x = m_session->GetPlayer()->GetPositionX();
	sp->y = m_session->GetPlayer()->GetPositionY();
	sp->z = m_session->GetPlayer()->GetPositionZ();
	sp->o = m_session->GetPlayer()->GetOrientation();
	sp->emote_state = 0;
	sp->flags = 0;
	sp->factionid = proto->Faction;
	sp->bytes0 = sp->setbyte(0,2,gender);
	sp->bytes1 = 0;
	sp->bytes2 = 0;
	//sp->respawnNpcLink = 0;
	sp->stand_state = 0;
	sp->channel_target_creature = sp->channel_target_go = sp->channel_spell = 0;
	sp->MountedDisplayID = 0;
	sp->Item1SlotDisplay = 0;
	sp->Item2SlotDisplay = 0;
	sp->Item3SlotDisplay = 0;


	Creature * p = m_session->GetPlayer()->GetMapMgr()->CreateCreature(entry, true);
	Arcemu::Util::ARCEMU_ASSERT(   p != NULL );
	p->Load(sp, (uint32)NULL, NULL);
	p->m_loadedFromDB = true;
	p->PushToWorld(m_session->GetPlayer()->GetMapMgr());
	
	uint32 x = m_session->GetPlayer()->GetMapMgr()->GetPosX(m_session->GetPlayer()->GetPositionX());
	uint32 y = m_session->GetPlayer()->GetMapMgr()->GetPosY(m_session->GetPlayer()->GetPositionY());

	// Add spawn to map
	m_session->GetPlayer()->GetMapMgr()->GetBaseMap()->GetSpawnsListAndCreate(
		x,
		y)->CreatureSpawns.push_back(sp);

	MapCell * mCell = m_session->GetPlayer()->GetMapMgr()->GetCell( x, y );

	if( mCell != NULL )
		mCell->SetLoaded();

	BlueSystemMessage(m_session, "Spawned a vehicle `%s` with entry %u at %f %f %f on map %u", info->Name, 
		entry, sp->x, sp->y, sp->z, m_session->GetPlayer()->GetMapId());

	sGMLog.writefromsession(m_session, "spawned a %s at %u %f %f %f", info->Name, m_session->GetPlayer()->GetMapId(),sp->x,sp->y,sp->z);

	return true;
}
예제 #20
0
파일: MapMgr.cpp 프로젝트: Chero/abcwow
void MapMgr::PushObject(Object *obj)
{
	/////////////
	// Assertions
	/////////////
	ASSERT(obj);
	
	// That object types are not map objects. TODO: add AI groups here?
	if(obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER)
	{
		// mark object as updatable and exit
		return;
	}

	if(obj->GetTypeId() == TYPEID_CORPSE)
	{
		m_corpses.insert(((Corpse*)obj));
	}	
	
	obj->ClearInRangeSet();
	ASSERT(obj->GetMapId() == _mapId);
	if(!(obj->GetPositionX() < _maxX && obj->GetPositionX() > _minX) || 
	   !(obj->GetPositionY() < _maxY && obj->GetPositionY() > _minY))
	{
		if(obj->IsPlayer())
		{
			Player * plr = static_cast< Player* >( obj );
			if(plr->GetBindMapId() != GetMapId())
			{
				plr->SafeTeleport(plr->GetBindMapId(),0,plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				return;
			}
			else
			{
				obj->GetPositionV()->ChangeCoords(plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				WorldPacket * data = plr->BuildTeleportAckMsg(plr->GetPosition());
				plr->GetSession()->SendPacket(data);
				delete data;
			}
		}
		else
		{
			obj->GetPositionV()->ChangeCoords(0,0,0,0);
		}
	}

	ASSERT(obj->GetPositionY() < _maxY && obj->GetPositionY() > _minY);
	ASSERT(_cells);

	///////////////////////
	// Get cell coordinates
	///////////////////////

	uint32 x = GetPosX(obj->GetPositionX());
	uint32 y = GetPosY(obj->GetPositionY());

	if(x >= _sizeX || y >= _sizeY)
	{
		if(obj->IsPlayer())
		{
			Player * plr = static_cast< Player* >( obj );
			if(plr->GetBindMapId() != GetMapId())
			{
				plr->SafeTeleport(plr->GetBindMapId(),0,plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				return;
			}
			else
			{
				obj->GetPositionV()->ChangeCoords(plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0);
				plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries.");
				WorldPacket * data = plr->BuildTeleportAckMsg(plr->GetPosition());
				plr->GetSession()->SendPacket(data);
				delete data;
			}
		}
		else
		{
			obj->GetPositionV()->ChangeCoords(0,0,0,0);
		}

		x = GetPosX(obj->GetPositionX());
		y = GetPosY(obj->GetPositionY());
	}

	MapCell *objCell = GetCell(x,y);
	if (!objCell)
	{
		objCell = Create(x,y);
		objCell->Init(x, y, _mapId, this);
	}

	uint32 endX = (x <= _sizeX) ? x + 1 : (_sizeX-1);
	uint32 endY = (y <= _sizeY) ? y + 1 : (_sizeY-1);
	uint32 startX = x > 0 ? x - 1 : 0;
	uint32 startY = y > 0 ? y - 1 : 0;
	uint32 posX, posY;
	MapCell *cell;
	MapCell::ObjectSet::iterator iter;

	ByteBuffer * buf = 0;
	uint32 count;
	Player *plObj;

	if(obj->GetTypeId() == TYPEID_PLAYER)
		plObj = static_cast< Player* >( obj );
	else
		plObj = NULL;

	if(plObj)
	{
		sLog.outDetail("Creating player "I64FMT" for himself.", obj->GetGUID());
		ByteBuffer pbuf(10000);
		count = plObj->BuildCreateUpdateBlockForPlayer(&pbuf, plObj);
		plObj->PushCreationData(&pbuf, count);
	}

	//////////////////////
	// Build in-range data
	//////////////////////

	for (posX = startX; posX <= endX; posX++ )
	{
		for (posY = startY; posY <= endY; posY++ )
		{
			cell = GetCell(posX, posY);
			if (cell)
			{
				UpdateInRangeSet(obj, plObj, cell, &buf);
			}
		}
	}

	//Add to the cell's object list
	objCell->AddObject(obj);

	obj->SetMapCell(objCell);
	 //Add to the mapmanager's object list
	if(plObj)
	{
	   m_PlayerStorage[plObj->GetLowGUID()] = plObj;
	   UpdateCellActivity(x, y, 2);
	}
	else
	{
		switch(obj->GetTypeFromGUID())
		{
		case HIGHGUID_TYPE_PET:
			m_PetStorage[obj->GetUIdFromGUID()] = static_cast< Pet* >( obj );
			break;

		case HIGHGUID_TYPE_UNIT:
			{
				ASSERT((obj->GetUIdFromGUID()) <= m_CreatureHighGuid);
				m_CreatureStorage[obj->GetUIdFromGUID()] = (Creature*)obj;
				if(((Creature*)obj)->m_spawn != NULL)
				{
					_sqlids_creatures.insert(make_pair( ((Creature*)obj)->m_spawn->id, ((Creature*)obj) ) );
				}
			}break;

		case HIGHGUID_TYPE_GAMEOBJECT:
			{
				m_GOStorage[obj->GetUIdFromGUID()] = (GameObject*)obj;
				if(((GameObject*)obj)->m_spawn != NULL)
				{
					_sqlids_gameobjects.insert(make_pair( ((GameObject*)obj)->m_spawn->id, ((GameObject*)obj) ) );
				}
			}break;

		case HIGHGUID_TYPE_DYNAMICOBJECT:
			m_DynamicObjectStorage[obj->GetLowGUID()] = (DynamicObject*)obj;
			break;
		}
	}

	// Handle activation of that object.
	if(objCell->IsActive() && obj->CanActivate())
		obj->Activate(this);

	// Add the session to our set if it is a player.
	if(plObj)
	{
		Sessions.insert(plObj->GetSession());

		// Change the instance ID, this will cause it to be removed from the world thread (return value 1)
		plObj->GetSession()->SetInstance(GetInstanceID());

		/* Add the map wide objects */
		if(_mapWideStaticObjects.size())
		{
			if(!buf)
				buf = new ByteBuffer(300);

			for(set<Object*>::iterator itr = _mapWideStaticObjects.begin(); itr != _mapWideStaticObjects.end(); ++itr)
			{
				count = (*itr)->BuildCreateUpdateBlockForPlayer(buf, plObj);
				plObj->PushCreationData(buf, count);
			}
		}
	}

	if(buf)
		delete buf;

	if(plObj && InactiveMoveTime && !forced_expire)
		InactiveMoveTime = 0;
}
예제 #21
0
파일: MapMgr.cpp 프로젝트: Artea/mangos-svn
void MapMgr::ChangeObjectLocation(Object *obj)
{
    ASSERT(obj);
    ASSERT(obj->GetMapId() == _mapId);
    ASSERT(_cells);

    if(obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER)
        return;

    WorldPacket packet;
    UpdateData data;
    UpdateData playerData;

    Object* curObj;

    for (Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin();
        iter != obj->GetInRangeSetEnd();)
    {
        curObj = *iter;
        iter++;

        if (curObj->GetDistance2dSq(obj) > UPDATE_DISTANCE*UPDATE_DISTANCE)
        {
            sLog.outDetail("Object "I64FMT" no longer in field of view of object "I64FMT".",
                obj->GetGUID(), (curObj)->GetGUID());

            if( obj->GetTypeId() == TYPEID_PLAYER )
                curObj->BuildOutOfRangeUpdateBlock( &playerData );

            obj->RemoveInRangeObject(curObj);

            if( curObj->GetTypeId() == TYPEID_PLAYER )
            {
                data.Clear();
                obj->BuildOutOfRangeUpdateBlock( &data );
                data.BuildPacket(&packet);
                ((Player*)curObj)->GetSession()->SendPacket( &packet );
            }

            curObj->RemoveInRangeObject(obj);
        }
    }

    uint32 cellX = (uint32)(obj->GetPositionX() > 0 ? abs(_minX) + obj->GetPositionX() :
    abs(_minX) - abs(obj->GetPositionX()));
    uint32 cellY = (uint32)(obj->GetPositionY() > 0 ? abs(_minY) + obj->GetPositionY() :
    abs(_minY) - abs(obj->GetPositionY()));
    cellX /= _sizeX;
    cellY /= _sizeY;

/*
    sLog.outDetail("Obj position: %f %f Cell position: %u %u",
    obj->GetPositionX(), obj->GetPositionY(), cellX, cellY);
*/

    MapCell *objCell = &(_cells[cellX][cellY]);

    if (objCell != obj->GetMapCell())
    {
        obj->GetMapCell()->RemoveObject(obj);
        objCell->AddObject(obj);
        obj->SetMapCell(objCell);
    }

    uint32 endX = cellX < _sizeX ? cellX + 1 : _sizeX;
    uint32 endY = cellY < _sizeY ? cellY + 1 : _sizeY;
    uint32 startX = cellX > 0 ? cellX - 1 : 0;
    uint32 startY = cellY > 0 ? cellY - 1 : 0;
    uint32 posX, posY;
    MapCell *cell;
    MapCell::ObjectSet::iterator iter;

    for (posX = startX; posX <= endX; posX++ )
    {
        for (posY = startY; posY <= endY; posY++ )
        {
            cell = &(_cells[posX][posY]);
            ASSERT(cell);

            for (iter = cell->Begin(); iter != cell->End(); iter++)
            {
                curObj = *iter;
                if (curObj != obj &&
                    (curObj)->GetDistance2dSq(obj) <= UPDATE_DISTANCE*UPDATE_DISTANCE &&
                    !obj->IsInRangeSet(curObj))
                {
                    // Object in range, add to set
                    if((curObj)->GetTypeId() == TYPEID_PLAYER)
                    {
                        sLog.outDetail("Creating object "I64FMT" for player "I64FMT".",
                            obj->GetGUID(), (curObj)->GetGUID());

                        data.Clear();
                        obj->BuildCreateUpdateBlockForPlayer( &data, (Player*)curObj );
                        data.BuildPacket(&packet);

                        ((Player*)curObj)->GetSession()->SendPacket( &packet );
                    }

                    (curObj)->AddInRangeObject(obj);

                    if(obj->GetTypeId() == TYPEID_PLAYER)
                    {
                        sLog.outDetail("Creating object "I64FMT" for player "I64FMT".",
                            (curObj)->GetGUID(), obj->GetGUID());

                        (curObj)->BuildCreateUpdateBlockForPlayer( &playerData, (Player*)obj );
                    }

                    obj->AddInRangeObject(curObj);
                }
            }
        }
    }

    if (obj->GetTypeId() == TYPEID_PLAYER)
    {
        playerData.BuildPacket(&packet);
        ((Player*)obj)->GetSession()->SendPacket( &packet );
    }
}
예제 #22
0
파일: MapMgr.cpp 프로젝트: Chero/abcwow
void MapMgr::UpdateCellActivity(uint32 x, uint32 y, int radius)
{
	CellSpawns * sp;
	uint32 endX = (x + radius) <= _sizeX ? x + radius : (_sizeX-1);
	uint32 endY = (y + radius) <= _sizeY ? y + radius : (_sizeY-1);
	uint32 startX = x - radius > 0 ? x - radius : 0;
	uint32 startY = y - radius > 0 ? y - radius : 0;
	uint32 posX, posY;

	MapCell *objCell;

	for (posX = startX; posX <= endX; posX++ )
	{
		for (posY = startY; posY <= endY; posY++ )
		{
			objCell = GetCell(posX, posY);

			if (!objCell)
			{
				if (_CellActive(posX, posY))
				{
					objCell = Create(posX, posY);
					objCell->Init(posX, posY, _mapId, this);

					sLog.outDetail("Cell [%d,%d] on map %d (instance %d) is now active.", 
						posX, posY, this->_mapId, m_instanceID);
					objCell->SetActivity(true);
					_map->CellGoneActive(posX, posY);

					ASSERT(!objCell->IsLoaded());

					sLog.outDetail("Loading objects for Cell [%d][%d] on map %d (instance %d)...", 
						posX, posY, this->_mapId, m_instanceID);

					sp = _map->GetSpawnsList(posX, posY);
					if(sp) objCell->LoadObjects(sp);
				}
			}
			else
			{
				//Cell is now active
				if (_CellActive(posX, posY) && !objCell->IsActive())
				{
					sLog.outDetail("Cell [%d,%d] on map %d (instance %d) is now active.", 
						posX, posY, this->_mapId, m_instanceID);
					_map->CellGoneActive(posX, posY);
					objCell->SetActivity(true);

					if (!objCell->IsLoaded())
					{
						sLog.outDetail("Loading objects for Cell [%d][%d] on map %d (instance %d)...", 
							posX, posY, this->_mapId, m_instanceID);
						sp = _map->GetSpawnsList(posX, posY);
						if(sp) objCell->LoadObjects(sp);
					}
				}
				//Cell is no longer active
				else if (!_CellActive(posX, posY) && objCell->IsActive())
				{
					sLog.outDetail("Cell [%d,%d] on map %d (instance %d) is now idle.", 
						posX, posY, this->_mapId, m_instanceID);
					_map->CellGoneIdle(posX, posY);
					objCell->SetActivity(false);
				}
			}
		}
	}

}
예제 #23
0
파일: MapMgr.cpp 프로젝트: Thomas195/arcemu
void MapMgr::UpdateCellActivity(uint32 x, uint32 y, uint32 radius)
{
	CellSpawns* sp;
	uint32 endX = (x + radius) <= _sizeX ? x + radius : (_sizeX - 1);
	uint32 endY = (y + radius) <= _sizeY ? y + radius : (_sizeY - 1);
	uint32 startX = x > radius ? x - radius : 0;
	uint32 startY = y > radius ? y - radius : 0;
	uint32 posX, posY;

	MapCell* objCell;

	for(posX = startX; posX <= endX; posX++)
	{
		for(posY = startY; posY <= endY; posY++)
		{
			objCell = GetCell(posX, posY);

			if(!objCell)
			{
				if(_CellActive(posX, posY))
				{
					objCell = Create(posX, posY);
					objCell->Init(posX, posY, this);

					LOG_DETAIL("Cell [%u,%u] on map %u (instance %u) is now active.",
					           posX, posY, this->_mapId, m_instanceID);
					objCell->SetActivity(true);
					_map->CellGoneActive(posX, posY);
					_terrain->LoadTile((int32)posX / 8, (int32)posY / 8);

					ARCEMU_ASSERT(!objCell->IsLoaded());

					LOG_DETAIL("Loading objects for Cell [%u][%u] on map %u (instance %u)...",
					           posX, posY, this->_mapId, m_instanceID);

					sp = _map->GetSpawnsList(posX, posY);
					if(sp) objCell->LoadObjects(sp);
				}
			}
			else
			{
				//Cell is now active
				if(_CellActive(posX, posY) && !objCell->IsActive())
				{
					LOG_DETAIL("Cell [%u,%u] on map %u (instance %u) is now active.",
					           posX, posY, this->_mapId, m_instanceID);
					_map->CellGoneActive(posX, posY);
					_terrain->LoadTile((int32)posX / 8, (int32)posY / 8);
					objCell->SetActivity(true);

					if(!objCell->IsLoaded())
					{
						LOG_DETAIL("Loading objects for Cell [%u][%u] on map %u (instance %u)...",
						           posX, posY, this->_mapId, m_instanceID);
						sp = _map->GetSpawnsList(posX, posY);
						if(sp) objCell->LoadObjects(sp);
					}
				}
				//Cell is no longer active
				else if(!_CellActive(posX, posY) && objCell->IsActive())
				{
					LOG_DETAIL("Cell [%u,%u] on map %u (instance %u) is now idle.", posX, posY, _mapId, m_instanceID);
					_map->CellGoneIdle(posX, posY);
					objCell->SetActivity(false);
					_terrain->UnloadTile((int32)posX / 8, (int32)posY / 8);
				}
			}
		}
	}

}
예제 #24
0
void GameMapRecrusive::makeMap(int mLevel, int vLevel)
{
    m_mLevel = mLevel;
    m_vLevel = vLevel;

    //10*20 -> 20*20 -> 20*30 -> 30*30
    m_mapRows = 10* (vLevel/2+1);
    m_mapCols = 20+10*vLevel/2;
    m_mapCols = min(50, m_mapCols);

    m_roomSize = 5;//5-vLevel/3;//3 + vLevel/2;
    m_roomSize = max(3, m_roomSize);

    m_mineCount = 5 + 20*vLevel;
    m_coinCount = 5+vLevel;// + 10*vLevel;
    m_propCount = 5+vLevel;// + 10*vLevel;
// 	m_hallMin = max(2, 5 - vLevel/2);
    //
    m_objects.resize(m_mapRows);

    for(int r=0; r<m_mapRows; ++r)
    {
        m_objects[r].resize(m_mapCols);

        for(int c=0; c<m_mapCols; ++c)
        {
            MapCell* cell = MapCell::create();
            cell->setPosition(Point(c*m_tw, r*m_th) + Point(0, m_th) /*+ m_border*/);
            cell->setLocalZOrder((m_mapRows-r-1)*m_mapCols + c);
            addChild(cell);
            m_objects[r][c] = cell;
        }
    }

    //
    this->setContentSize(Size(m_mapCols*m_tw/*+m_border.width*2*/, m_mapRows*m_th/*+m_border.height*2*/));
    generate(0, 0, m_mapRows, m_mapCols);

    while(m_mineCount>0)
    {
        int r = rand()% (m_mapRows-2)+1;
        int c = rand()% (m_mapCols-2)+1;
        setTrap(r, c);
    }

    while(m_coinCount>0)
    {
        int r = rand()% (m_mapRows-2)+1;
        int c = rand()% (m_mapCols-2)+1;
        setCoin(r, c);
    }

    while(m_propCount > 0)
    {
        int r = rand()% (m_mapRows-2)+1;
        int c = rand()% (m_mapCols-2)+1;
        setProp(r, c);
    }

	for (int r = 0; r < m_mapRows; ++r)
	{
		for (int j=0; j < m_mapCols; ++j)
		{
			if (m_objects[r][j]->empty())
			{
				if (rand()%100<70)
				{
					setSoil(r, j, false);
				}
			}
		}
	}
    //
    const Index2 pos(rand()%m_mapRows,0);
    m_pPlayer = Player::create();
    m_pPlayer->setPosition(index2ToPoint(pos)+Point(m_tw/2, m_th/2));
    addChild(m_pPlayer, m_mapRows*m_mapCols+1);
    m_objects[pos.first][pos.second]->clear();

    for(auto x : getSurrounding(pos))
    {
        m_objects[x.first][x.second]->clear();
    }

    //
    ValueMap val;
    val["type"] = "LevelStair";
    const Index2 win(rand()%m_mapRows, m_mapCols-1);
    m_objects[win.first][win.second]->clear();
    m_objects[win.first][win.second]->pushObjBy(val);
}
예제 #25
0
파일: Level2.cpp 프로젝트: Ikesters/ArcPro
bool ChatHandler::HandleGOSpawn(const char* args, WorldSession* m_session)
{
	std::stringstream sstext;

	char* pEntryID = strtok((char*)args, " ");
	if(!pEntryID)
		return false;

	uint32 EntryID  = atoi(pEntryID);

	bool Save = false;
	char* pSave = strtok(NULL, " ");
	if(pSave)
		Save = (atoi(pSave) > 0 ? true : false);

	GameObjectInfo* goi = GameObjectNameStorage.LookupEntry(EntryID);
	if(!goi)
	{
		sstext << "GameObject Info '" << EntryID << "' Not Found" << '\0';
		SystemMessage(m_session, sstext.str().c_str());
		return true;
	}

	LOG_DEBUG("Spawning GameObject By Entry '%u'", EntryID);
	sstext << "Spawning GameObject By Entry '" << EntryID << "'" << '\0';
	SystemMessage(m_session, sstext.str().c_str());

	Player* chr = m_session->GetPlayer();

	GameObject* go = chr->GetMapMgr()->CreateGameObject(EntryID);

	uint32 mapid = chr->GetMapId();
	float x = chr->GetPositionX();
	float y = chr->GetPositionY();
	float z = chr->GetPositionZ();
	float o = chr->GetOrientation();

	go->CreateFromProto(EntryID, mapid, x, y, z, o);
	go->PushToWorld(chr->GetMapMgr());
	go->Phase(PHASE_SET, chr->GetPhase());
	// Create spawn instance
	GOSpawn* gs = new GOSpawn;
	gs->entry = go->GetEntry();
	gs->facing = go->GetOrientation();
	gs->faction = go->GetFaction();
	gs->flags = go->GetUInt32Value(GAMEOBJECT_FLAGS);
	gs->id = objmgr.GenerateGameObjectSpawnID();
	gs->o = 0.0f;
	gs->o1 = go->GetParentRotation(0);
	gs->o2 = go->GetParentRotation(2);
	gs->o3 = go->GetParentRotation(3);
	gs->scale = go->GetScale();
	gs->x = go->GetPositionX();
	gs->y = go->GetPositionY();
	gs->z = go->GetPositionZ();
	gs->state = go->GetByte(GAMEOBJECT_BYTES_1, 0);
	//gs->stateNpcLink = 0;
	gs->phase = go->GetPhase();
	gs->overrides = go->GetOverrides();

	uint32 cx = chr->GetMapMgr()->GetPosX(chr->GetPositionX());
	uint32 cy = chr->GetMapMgr()->GetPosY(chr->GetPositionY());

	chr->GetMapMgr()->GetBaseMap()->GetSpawnsListAndCreate(cx, cy)->GOSpawns.push_back(gs);
	go->m_spawn = gs;

	MapCell* mCell = chr->GetMapMgr()->GetCell(cx, cy);

	if(mCell != NULL)
		mCell->SetLoaded();

	if(Save == true)
	{
		// If we're saving, create template and add index
		go->SaveToDB();
		go->m_loadedFromDB = true;
	}
	sGMLog.writefromsession(m_session, "spawned gameobject %s, entry %u at %u %f %f %f%s", GameObjectNameStorage.LookupEntry(gs->entry)->Name, gs->entry, chr->GetMapId(), gs->x, gs->y, gs->z, Save ? ", saved in DB" : "");
	return true;
}
예제 #26
0
파일: GameMap.cpp 프로젝트: gittor/Explore
list<GameMap::Index2> GameMap::getPath( const Index2& from, const Index2& to )
{
	if (from==to || (to.first<0 || to.first>=m_objects.size() || to.second<0 || to.second>=m_objects[0].size()))
		return list<Index2>();

	struct AStarInfo
	{
		int g;
		int h;
		Index2 parent;
		int f(){ return g+h; }
		AStarInfo(int argg, int argh){
			g = argg;
			h = argh;
			parent.first = parent.second = -1;
		}
	};
	map<Index2, AStarInfo> opened;
	map<Index2, AStarInfo> closed;
	auto last_obj = opened.end();
	opened.insert( make_pair(from, AStarInfo(0,0)) );
	do
	{
		Break_If( opened.empty() );
		int min_cost = INT_MAX;
		Index2 curPos(-1,-1);
		AStarInfo curInfo(INT_MAX, 0);
		map<Index2, AStarInfo>::iterator cur;
		for (map<Index2, AStarInfo>::iterator it = opened.begin(); it != opened.end(); ++it)
		{
			if (it->second.f() < curInfo.f())
			{
				curPos = it->first;
				curInfo = it->second;
				cur = it;
			}
		}
		opened.erase(cur);
		closed.insert( make_pair(curPos, curInfo) );

		auto surround = getSurrounding(curPos, 1);
		for (auto it = surround.begin(); it != surround.end(); ++it)
		{
			MapCell* cell = m_objects[it->first][it->second];
			if ( *it == to )
			{
				AStarInfo info( curInfo.g+loss(curPos,*it), loss(*it, to) );
				info.parent = curPos;
				opened.insert( make_pair(*it, info) );
			}
			else if ( cell->getAStarCost()==INT_MAX || closed.find(*it)!=closed.end() )
			{
				//do nothing
			}
			else if ( opened.find(*it) == opened.end() )
			{
				AStarInfo info( curInfo.g+loss(curPos,*it), loss(*it, to) );
				info.parent = curPos;
				opened.insert( make_pair(*it, info) );
			}
			else//已经在开启列表中,检查新的路径是否更好
			{
				auto has = opened.find(*it);
				if (has->second.g > curInfo.g+loss(curPos,*it))
				{
					has->second.parent = curPos;
					has->second.g = curInfo.g+loss(curPos,*it);
				}
			}
		}
		
		last_obj = opened.find(to);
		if (last_obj != opened.end())
			break;

	} while (true);

	if (last_obj == opened.end())
	{
		return list<Index2>();
	}

	list<Index2> ret;
	ret.push_front( last_obj->first );
	auto path = closed.find( last_obj->second.parent );
	while (path != closed.end())
	{
		ret.push_front(path->first);
		path = closed.find( path->second.parent );
	}
	if (!ret.empty())
		ret.pop_front();

	if (ret.size() > 10)
	{
		ret.clear();
	}
	return ret;
}
예제 #27
0
파일: MapMgr.cpp 프로젝트: Artea/mangos-svn
void MapMgr::AddObject(Object *obj)
{
    ASSERT(obj);
    // make sure object is a virgin
    ASSERT(obj->GetInRangeSetBegin() == obj->GetInRangeSetEnd());
    ASSERT(obj->GetMapId() == _mapId);
    ASSERT(obj->GetPositionX() < _maxX && obj->GetPositionX() > _minX);
    ASSERT(obj->GetPositionY() < _maxY && obj->GetPositionY() > _minY);
    ASSERT(_cells);

    // That object types are not map objects. TODO: add AI groups here?
    if(obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER)
    {
    // mark object as updatable and exit
        obj->AddToWorld();
        return;
    }

    uint32 x = (uint32)(obj->GetPositionX() > 0 ? abs(_minX) + obj->GetPositionX() :
    abs(_minX) - abs(obj->GetPositionX()));
    uint32 y = (uint32)(obj->GetPositionY() > 0 ? abs(_minY) + obj->GetPositionY() :
    abs(_minY) - abs(obj->GetPositionY()));
    x /= _sizeX;
    y /= _sizeY;

/*
    sLog.outDetail("Obj position: %f %f Cell position: %u %u",
    obj->GetPositionX(), obj->GetPositionY(), x, y);
*/

    MapCell *objCell = &(_cells[x][y]);

    uint32 endX = x < _sizeX ? x + 1 : _sizeX;
    uint32 endY = y < _sizeY ? y + 1 : _sizeY;
    uint32 startX = x > 0 ? x - 1 : 0;
    uint32 startY = y > 0 ? y - 1 : 0;
    uint32 posX, posY;
    MapCell *cell;
    MapCell::ObjectSet::iterator iter;

    WorldPacket packet;
    UpdateData data;
    UpdateData playerData;

    for (posX = startX; posX <= endX; posX++ )
    {
        for (posY = startY; posY <= endY; posY++ )
        {
            cell = &(_cells[posX][posY]);
            ASSERT(cell);

            for (iter = cell->Begin(); iter != cell->End(); iter++)
            {
                if ((*iter)->GetDistance2dSq(obj) <= UPDATE_DISTANCE*UPDATE_DISTANCE)
                {
                    // Object in range, add to set
                    if((*iter)->GetTypeId() == TYPEID_PLAYER)
                    {
                        sLog.outDetail("Creating object "I64FMT" for player "I64FMT".",
                            obj->GetGUID(), (*iter)->GetGUID());

                        data.Clear();
                        obj->BuildCreateUpdateBlockForPlayer( &data, (Player*)*iter );
                        data.BuildPacket(&packet);

                        ((Player*)*iter)->GetSession()->SendPacket( &packet );
                    }

                    (*iter)->AddInRangeObject(obj);

                    if(obj->GetTypeId() == TYPEID_PLAYER)
                    {
                        sLog.outDetail("Creating object "I64FMT" for player "I64FMT".",
                            (*iter)->GetGUID(), obj->GetGUID());

                        (*iter)->BuildCreateUpdateBlockForPlayer( &playerData, (Player*)obj );
                    }

                    obj->AddInRangeObject(*iter);
                }
            }
        }
    }

    if(obj->GetTypeId() == TYPEID_PLAYER)
    {
        sLog.outDetail("Creating player "I64FMT" for himself.", obj->GetGUID());
        obj->BuildCreateUpdateBlockForPlayer( &playerData, (Player*)obj );

        playerData.BuildPacket( &packet );
        ((Player*)obj)->GetSession()->SendPacket( &packet );
    }

    objCell->AddObject(obj);

    _objects[obj->GetGUID()] = obj;

    obj->SetMapCell(objCell);
    obj->AddToWorld();
}