void SpatialIndexManager::initObjectsInRange(PlayerObject* player) {
    uint64_t player_id = player->getParentId();
    if (player_id == 0) {
        return;
    }

    Object* tmp = gWorldManager->getObjectById(player_id);
    if (tmp->getType() != ObjType_Cell) {
        return;
    }

    CellObject* cell = static_cast<CellObject*>(tmp);

    tmp = gWorldManager->getObjectById(cell->getParentId());
    if (tmp->getType() != ObjType_Building) {
        return;
    }

    BuildingObject* building = static_cast<BuildingObject*>(tmp);

    ObjectList children = building->getAllCellChilds();

    std::for_each(children.begin(), children.end(), [this, player] (Object* cell_child) {
        if (cell_child->getType() != ObjType_Tangible) {
            return;
        }

        sendCreateObject(cell_child, player, true);
    });
}
//============================================================================================================
// the idea is that the container holding our new item might be held by a container, too
// should this happen, we need to find the main container to determin what kind of creates to send to our player/s
// we will iterate through the parentObjects until the parent is either a player (item has been equipped) or in the inventory or )
// or a cell or a factory
uint64 SpatialIndexManager::getObjectMainParent(Object* object) {

    uint64 parentID = object->getParentId();

    // hack ourselves a player - it is not possible to get an inventory otherwise because
    // inventories are not part of the WorldObjectMap ... which really gets cumbersom (resolved with newest trunc)

    PlayerObject* player = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(parentID-1));
    if(!player)
    {
        // the backpack might have been equipped ?
        //   this way we have of course a player directly
        PlayerObject* player = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(parentID));
        if(!player)
        {
            CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(parentID));
            if(!cell)
            {
                CellObject* cell = dynamic_cast<CellObject*>(object);
                if(cell)
                {
                    return parentID;
                }
                FactoryObject* factory = dynamic_cast<FactoryObject*>(gWorldManager->getObjectById(parentID));
                if(!factory)
                {
                    Object* ob = dynamic_cast<Object*>(gWorldManager->getObjectById(parentID));
                    if(!ob)
                    {
                        return 0;
                    }
                    parentID = getObjectMainParent(ob);
                }
            }
            else
            {
                //return the house
                return cell->getParentId();
            }
        }
    }
    else
    {
        //its in the inventory
        return parentID;
        //Inventory is parent ID +1 - we cannot find inventories in the worldObjectMap but we can find players there
        //so we have to go this way
        //before changing this we need to settle the dispute what objects are part of the world objectmap and need to discuss objectownership
        //Eru is right in saying that we cant have two object owners (well we can but obviously we shouldnt)
    }

    return parentID;
}
//======================================================================================================================
//
// rotates an item
//
void ObjectController::HandleRotateFurniture_(
    uint64 targetId,
    Message* message,
    ObjectControllerCmdProperties* cmdProperties) {

    CreatureObject* creature  = dynamic_cast<CreatureObject*>(mObject); PlayerObject* player = creature->GetGhost();

    if (!player)	{
        assert(false && "ObjectController::HandleRotateFurniture_ Player not found");
        return;
    }

    // Verify that there was a target passed.
    if (!targetId) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player);
        return;
    }

    Object* object = gWorldManager->getObjectById(targetId);

    if(!object)	{
        assert(false && "ObjectController::HandleRotateFurniture_ item not found");
        return;
    }

    // Verify that the item and player are in the same structure.
    CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()));
    if(!playerCell)	{
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player);
        return;
    }
    uint64 playerStructure = playerCell->getParentId();

    CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId()));
    if(!objectCell)	{
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player);
        return;
    }
    uint64 objectStructure = objectCell->getParentId();

    if (objectStructure != playerStructure) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player);
        return;
    }

    // Verify that the player has appropriate rights on this structure.
    if (playerCell) {
        if (BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(playerCell->getParentId()))) {
            if (!building->getAdminData().check_admin(player->getId())) {
                gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "admin_move_only"), player);
                return;
            }
        }	else {
            assert(false && "ObjectController::HandleRotateFurniture_ no structure");
            return;
        }
    } else {
        //were just outside??
        return;
    }

    // Read the message out of the packet.
    BString tmp;
    message->getStringUnicode16(tmp);

    // If the string has no length the message is ill-formatted, send the
    // proper format to the client.
    if (!tmp.getLength()) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "format_rotatefurniture_degrees"), player);
        return;
    }

    // Convert the string to an ansi string for ease with the regex.
    tmp.convert(BSTRType_ANSI);
    std::string input_string(tmp.getAnsi());

    static const regex pattern("(right|left) ([0-9]+)");
    smatch result;

    regex_search(input_string, result, pattern);

    // If the pattern doesn't match all elements then send the proper format
    // to the client.
    if (result.length() < 2) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "format_rotatefurniture_degrees"), player);
        return;
    }

    // Gather the results of the pattern for validation and use.
    std::string direction(result[1]);
    float degrees = boost::lexical_cast<float>(result[2]);

    // If the the specified amount is not within the valid range notify the client.
    if (degrees < 1.0f || degrees > 180.0f) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_params"), player);
        return;
    }

    // Rotate by the necessary amount.
    if (direction.compare("left") == 0) {
        object->rotateLeft(degrees);
    } else {
        object->rotateRight(degrees);
    }

    // Update the world with the changes.
    gMessageLib->sendDataTransformWithParent053(object);
    object->updateWorldPosition();
}
Example #4
0
void CellFactory::handleObjectReady(Object* object,DispatchClient* client)
{
    InLoadingContainer* ilc = _getObject(object->getParentId());

    if (! ilc) {//Crashbug fix: http://paste.swganh.org/viewp.php?id=20100627114151-8f7df7f74013af71c0d0b00bc240770d
        LOG(warning) << "Could not locate InLoadingContainer for object parent id [" << object->getParentId() << "]";
        return;
    }

    CellObject*			cell = dynamic_cast<CellObject*>(ilc->mObject);

    gWorldManager->addObject(object,true);


    switch(object->getType())
    {
    case ObjType_NPC:
    case ObjType_Creature:
    {
        CreatureObject* creature = dynamic_cast<CreatureObject*>(object);

        if(creature->getCreoGroup() == CreoGroup_Shuttle)
            gWorldManager->addShuttle(dynamic_cast<Shuttle*>(creature));
    }
    break;

    case ObjType_Tangible:
    {
        PlayerStructureTerminal* terminal = dynamic_cast<PlayerStructureTerminal*>(object);
        if(terminal)
        {
            terminal->setStructure(cell->getParentId());
        }
    }
    break;

    case ObjType_Building:
    case ObjType_Cell:
    case ObjType_DraftSchematic:
    case ObjType_Structure:
    case ObjType_Intangible:
    case ObjType_Lair:
    case ObjType_Mission:
    case ObjType_None:
    case ObjType_NonPersistant:
    case ObjType_Player:
    case ObjType_Region:

    case ObjType_Waypoint:
    default:
        break;
    }

	auto permissions_objects_ = gObjectManager->GetPermissionsMap();
			
	object->SetPermissions(permissions_objects_.find(swganh::object::DEFAULT_PERMISSION)->second.get());//CREATURE_PERMISSION

	gObjectManager->LoadSlotsForObject(object);
	cell->InitializeObject(object);
	cell->incLoad();

	//LOG(info) << "cellFactory::handleObjectReady -> cell load stuff" << object->getId() << "for " << cell->getId();
	//LOG(info) << "loadcount : " << cell->getLoadCount() << " : count : " << cell->getLoad();

	if(cell->getLoadCount() == cell->getLoad())
    {
		//LOG(info) << "cellFactory::handleObjectReady -> cell done " << cell->getId();

        if(!(_removeFromObjectLoadMap(cell->getId())))
            LOG(warning) << "Failed removing object from loadmap";

        ilc->mOfCallback->handleObjectReady(cell,ilc->mClient);

        mILCPool.free(ilc);
    }
}
Example #5
0
void CellFactory::handleObjectReady(Object* object,DispatchClient* client)
{
    InLoadingContainer* ilc = _getObject(object->getParentId());

    if (! ilc) {//Crashbug fix: http://paste.swganh.org/viewp.php?id=20100627114151-8f7df7f74013af71c0d0b00bc240770d
        gLogger->log(LogManager::WARNING,"CellFactory::handleObjectReady could not locate ILC for objectParentId:%I64u",object->getParentId());
        return;
    }

    CellObject*			cell = dynamic_cast<CellObject*>(ilc->mObject);

    gWorldManager->addObject(object,true);

    switch(object->getType())
    {
    case ObjType_NPC:
    case ObjType_Creature:
    {
        CreatureObject* creature = dynamic_cast<CreatureObject*>(object);

        if(creature->getCreoGroup() == CreoGroup_Shuttle)
            gWorldManager->addShuttle(dynamic_cast<Shuttle*>(creature));
    }
    break;

    case ObjType_Tangible:
    {
        PlayerStructureTerminal* terminal = dynamic_cast<PlayerStructureTerminal*>(object);
        if(terminal)
        {
            terminal->setStructure(cell->getParentId());
        }
    }
    break;

    case ObjType_Building:
    case ObjType_Cell:
    case ObjType_DraftSchematic:
    case ObjType_Structure:
    case ObjType_Intangible:
    case ObjType_Lair:
    case ObjType_Mission:
    case ObjType_None:
    case ObjType_NonPersistant:
    case ObjType_Player:
    case ObjType_Region:

    case ObjType_Waypoint:
    default:
        break;
    }

    cell->addObjectSecure(object);

    if(cell->getLoadCount() == cell->getObjects()->size())
    {
        if(!(_removeFromObjectLoadMap(cell->getId())))
            gLogger->log(LogManager::DEBUG,"CellFactory: Failed removing object from loadmap");

        ilc->mOfCallback->handleObjectReady(cell,ilc->mClient);

        mILCPool.free(ilc);
    }
}
//======================================================================================================================
//
// moves an item
//
void ObjectController::HandleItemMoveDown_(
    uint64 targetId,
    Message* message,
    ObjectControllerCmdProperties* cmdProperties) {

    PlayerObject*	player	= dynamic_cast<PlayerObject*>(mObject);

    if (!player)	{
        assert(false && "ObjectController::HandleItemMoveDown_ Player not found");
        return;
    }

    // Verify that there was a target passed.
    if (!targetId) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player);
        return;
    }

    Object* object = gWorldManager->getObjectById(targetId);

    if(!object)	{
        assert(false && "ObjectController::HandleItemMoveDown_ item not found");
        return;
    }

    // Verify that the item and player are in the same structure.
    // Verify that the item and player are in the same structure.
    CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()));
    if(!playerCell)	{
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player);
        return;
    }
    uint64 playerStructure = playerCell->getParentId();

    CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId()));
    if(!objectCell)	{
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player);
        return;
    }
    uint64 objectStructure = objectCell->getParentId();

    if (objectStructure != playerStructure) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player);
        return;
    }

    // Verify that the player has appropriate rights on this structure.
    if (playerCell) {
        if (BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(playerCell->getParentId()))) {
            if (!building->hasAdminRights(player->getId())) {
                gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "admin_move_only"), player);
                return;
            }
        }	else {
            assert(false && "ObjectController::HandleItemMoveDown_ no structure");
            return;
        }
    } else {
        //were just outside??
        return;
    }

    object->mPosition.y -= MOVE_INCREMENT;

    gMessageLib->sendDataTransformWithParent053(object);
    object->updateWorldPosition();
}
Example #7
0
void ObjectController::handleObjectMenuRequest(Message* message)
{
    //for ever item where we request a radial the client starts by displaying a radial on his own and additionally sends a
    //objectMenuRequest to the server
    //The server then either just resends the radial as send by the client or adds / modifies options on his own
    //this is why sometimes when lag is involved it takes some time for all options to display


    PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject);

    message->getUint32(); // unknown
    uint64 requestedObjectId = message->getUint64();
    message->getUint64(); // player id again ?

    Object* requestedObject = gWorldManager->getObjectById(requestedObjectId);

    uint32 itemCount = message->getUint32();

    BString extendedDescription;
    MenuItemList menuItemList;

    MenuItem* menuItem;
    for(uint32 i = 0; i < itemCount; i++)
    {
        menuItem = new(MenuItem);

        menuItem->sItem			= message->getUint8();   // item nr
        menuItem->sSubMenu		= message->getUint8();   // submenu flag
        menuItem->sIdentifier	= message->getUint8();   // item identifier
        menuItem->sOption		= message->getUint8();   // extended option
        message->getStringUnicode16(extendedDescription);
        menuItemList.push_back(menuItem);
    }

    uint8 responseNr = message->getUint8();

    if(!requestedObject)
    {
        if(playerObject->isConnected())
            gMessageLib->sendEmptyObjectMenuResponse(requestedObjectId,playerObject,responseNr,menuItemList);

        //the list is cleared and items are destroyed in the message lib
        //for the default response
        return;
    }

    requestedObject->setMenuList(&menuItemList);



    //are we an item dropped in a structure awaiting to be moved or picked u`p?
    //just implement this virtual function for items as we need just one central point instead
    //of the same code over and over for all items

    CellObject* itemCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(requestedObject->getParentId()));

    Item* item = dynamic_cast<Item*>(requestedObject);
    ResourceContainer* rC = dynamic_cast<ResourceContainer*>(requestedObject);
    TangibleObject* tO = dynamic_cast<TangibleObject*>(requestedObject);

    //only display that menu when *we* and the item are in the same structure
    if((rC || item) && itemCell && (!tO->getStatic()))
    {
        CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId()));
        if(playerCell && (playerCell->getParentId() == itemCell->getParentId()))
        {
            PlayerStructure* pS = dynamic_cast<PlayerStructure*>(gWorldManager->getObjectById(playerCell->getParentId()));
            if(pS)
                requestedObject->prepareCustomRadialMenuInCell(playerObject,static_cast<uint8>(itemCount));
        }
    }
    /*
    if(rc && requestedObject->getParentId())
    {
        if(CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(requestedObject->getParentId())))
        {
            requestedObject->prepareCustomRadialMenuInCell(playerObject,static_cast<uint8>(itemCount));
        }
    }
    */
    //delete the radials after every use or provide every object with set rules when to delete it ?

    if(!requestedObject->getRadialMenu())
        requestedObject->prepareCustomRadialMenu(playerObject,static_cast<uint8>(itemCount));

    if (requestedObject->getRadialMenu())
    {
        if(playerObject->isConnected())
        {
            gMessageLib->sendObjectMenuResponse(requestedObject,playerObject,responseNr);
        }
        //they only reset if the objects virtual function does it
        //by default it stays
        requestedObject->ResetRadialMenu();
        //the radial menu is supposed to be an intelligent pointer deleting itself when no reference is left
        //however during runtime the item always references the radialmenu that was generated for it on the first call.
        //when the circumstances of the item change we need to delete the pointer and thus force it to generate a new radial
    }
    else
    {
        // putting this for static objects/objects that are not known by the server yet
        // send a default menu,so client stops flooding us with requests

        //empty might just mean that the clients radial is sufficient

        if(playerObject->isConnected())
            gMessageLib->sendEmptyObjectMenuResponse(requestedObjectId,playerObject,responseNr,menuItemList);

        //the list is cleared and items are destroyes in the message lib
        //for the default response
    }


    //we need to clear that if the messagelib wont clear it
    //still want to use it for the player radials at some point
    for(MenuItemList::iterator it=menuItemList.begin(); it != menuItemList.end(); it++)
        delete (*it);

    menuItemList.clear();

}
void WorldManager::initObjectsInRange(PlayerObject* playerObject)
{
	float				viewingRange	= _GetMessageHeapLoadViewingRange();
	//if we are in a playerbuilding create the playerbuilding first
	//otherwise our items will not show when they are created before the cell
	if(CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId())))
	{
		if(HouseObject* playerHouse = dynamic_cast<HouseObject*>(gWorldManager->getObjectById(cell->getParentId())))
		{
			//gLogger->logMsgF("create playerbuilding",MSG_HIGH);
			gMessageLib->sendCreateObject(playerHouse,playerObject);
			playerHouse->addKnownObjectSafe(playerObject);
			playerObject->addKnownObjectSafe(playerHouse);	
		}
	}



	// we still query for players here, cause they are found through the buildings and arent kept in a qtree
	ObjectSet inRangeObjects;
	mSpatialIndex->getObjectsInRange(playerObject,&inRangeObjects,(ObjType_Player | ObjType_Tangible | ObjType_NPC | ObjType_Creature | ObjType_Building | ObjType_Structure ),viewingRange);

	// query the according qtree, if we are in one
	if(playerObject->getSubZoneId())
	{
		if(QTRegion* region = getQTRegion(playerObject->getSubZoneId()))
		{
			Anh_Math::Rectangle qRect;

			if(!playerObject->getParentId())
			{
				qRect = Anh_Math::Rectangle(playerObject->mPosition.x - viewingRange,playerObject->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2);
			}
			else
			{
				CellObject*		cell		= dynamic_cast<CellObject*>(getObjectById(playerObject->getParentId()));
				
				
				if(BuildingObject* house	= dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId())))
				{
					qRect = Anh_Math::Rectangle(house->mPosition.x - viewingRange,house->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2);
				}
			}

			region->mTree->getObjectsInRange(playerObject,&inRangeObjects,ObjType_Player,&qRect);
		}
	}

	// iterate through the results
	ObjectSet::iterator it = inRangeObjects.begin();

	while(it != inRangeObjects.end())
	{
		Object* object = (*it);

		// send create for the type of object
		if (object->getPrivateOwner())	//what is this about ?? does it concern instances ????
		{
			if (object->isOwnedBy(playerObject))
			{
				gMessageLib->sendCreateObject(object,playerObject);
				object->addKnownObjectSafe(playerObject);
				playerObject->addKnownObjectSafe(object);
			}
		}
		else
		{
			gMessageLib->sendCreateObject(object,playerObject);
				
			object->addKnownObjectSafe(playerObject);
			playerObject->addKnownObjectSafe(object);
			
		}
		++it;
	}
}
//*********************************************************************
//a Player or creature is ALWAYS in the grid and possibly in a cell
void SpatialIndexManager::RemoveObjectFromWorld(PlayerObject *removePlayer)
{
    DLOG(info) << "SpatialIndexManager::RemoveObjectFromWorld:: Player : " << removePlayer->getId();

    //remove us from the grid
    _RemoveObjectFromGrid(removePlayer);

    //remove us out of the cell
    if(removePlayer->getParentId() == 0)	{
        return;
    }

    CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(removePlayer->getParentId()));
    if(cell)    {
        //unregister from the building and all its cells
        if(BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId())))		{
            gContainerManager->unRegisterPlayerFromBuilding(building,removePlayer);
        }

        cell->removeObject(removePlayer);
    }
    else    {
        DLOG(info) << "SpatialIndexManager::RemoveObjectFromWorld (player): couldn't find cell " << removePlayer->getParentId();
    }


}
Example #10
0
void BuildingObject::prepareDestruction() 
{
    //iterate through all the registered watchers
    //place players inside into the world and unregister the content
    //add an option to delete those players we send to ...

    gContainerManager->sendToRegisteredPlayers(this, [=] (PlayerObject* player) {

        gSpatialIndexManager->removeStructureItemsForPlayer(player,this);

        //is the player inside ??? or was he merely still watching??
        CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()));
        if (!cell) {
			//we have no interest in bystanders
            return;
        }

        BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId()));
        if (!building || building->getId() != this->getId()) {
            return;
        }

        //No need to update the SI here as we only leave the cell
        player->updatePosition(0, player->getWorldPosition());
        player->setParentIdIncDB(0);

        cell->RemoveObject(this, player);

        gMessageLib->broadcastContainmentMessage(player, 0, 0xffffffff);
    });

    //remove items in the building from the world
    CellObjectList* cell_list = getCellList();
    std::for_each(cell_list->begin(), cell_list->end(), [] (CellObject* cell) {
        cell->prepareDestruction();
    });
}
void  WorldManager::initPlayersInRange(Object* object,PlayerObject* player)
{
    // we still query for players here, cause they are found through the buildings and arent kept in a qtree
    ObjectSet inRangeObjects;
    mSpatialIndex->getObjectsInRange(object,&inRangeObjects,(ObjType_Player),gWorldConfig->getPlayerViewingRange());

    // query the according qtree, if we are in one
    if(object->getSubZoneId())
    {
        if(QTRegion* region = getQTRegion(object->getSubZoneId()))
        {
            float				viewingRange	= _GetMessageHeapLoadViewingRange();
            //float				viewingRange	= (float)gWorldConfig->getPlayerViewingRange();
            Anh_Math::Rectangle qRect;

            if(!object->getParentId())
            {
                qRect = Anh_Math::Rectangle(object->mPosition.x - viewingRange,object->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2);
            }
            else
            {
                CellObject*		cell		= dynamic_cast<CellObject*>(getObjectById(object->getParentId()));
                BuildingObject* building	= dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId()));

                qRect = Anh_Math::Rectangle(building->mPosition.x - viewingRange,building->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2);
            }

            region->mTree->getObjectsInRange(object,&inRangeObjects,ObjType_Player,&qRect);
        }
    }

    // iterate through the results
    ObjectSet::iterator it = inRangeObjects.begin();

    while(it != inRangeObjects.end())
    {
        PlayerObject* pObject = dynamic_cast<PlayerObject*>(*it);

        if(pObject)
        {
            if(pObject != player)
            {
                gMessageLib->sendCreateObject(object,pObject);
                pObject->addKnownObjectSafe(object);
                object->addKnownObjectSafe(pObject);
            }

        }

        ++it;
    }

}
bool ObjectController::_updateInRangeObjectsInside()
{
	PlayerObject*	player = dynamic_cast<PlayerObject*>(mObject);
	CellObject*		playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()));

	// make sure we got a cell
	if (!playerCell)
	{
		gLogger->logMsgF("Error getting cell %"PRIu64" for %"PRIu64" type %u",MSG_NORMAL,player->getParentId(),player->getId(),player->getType());
		return true;	// We are done, nothing we can do...
	}

	// We may wan't to limit the amount of messages sent in one session.
	uint32 updatedObjects = 0;
	const uint32 objectSendLimit = 50;

	//what do we do if the object has been deleted in the meantime?
	//TODO
	while ((mObjectSetIt != mInRangeObjects.end()) && (updatedObjects < objectSendLimit))
	{
		// Object* object = (*mObjectSetIt);
		// Needed since object may be invalid due to the multi-session approach of this function.
		Object* object = dynamic_cast<Object*>(*mObjectSetIt);

		// Create objects that are in the same building as we are OR outside near the building.
		if ((object) && (!player->checkKnownObjects(object)))
		{
			bool validObject = true;	// Assume it's an object we shall add.

			// Object inside a building ?
			if (object->getParentId())
			{
				validObject = false;

				// Yes, get the objects cell.
				CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId()));
				if (objectCell)
				{
					// Are we in the same building?
					if (objectCell->getParentId() == playerCell->getParentId())
					{
						// We are in the same building as the object.
						validObject = true;
					}
				}
				else
				{
					gLogger->logMsgF("Error getting cell %"PRIu64" for %"PRIu64" type %u",MSG_NORMAL,object->getParentId(),object->getId(),object->getType());
				}
			}
			if (validObject)
			{
				// send the according create for the type of object
#if defined(_MSC_VER)
				if (object->getId() > 0x0000000100000000)
#else
				if (object->getId() > 0x0000000100000000LLU)
#endif
				{
					//if its an instance and per chance *our* instance
					if (object->getPrivateOwner()&&object->isOwnedBy(player))
					{
						gMessageLib->sendCreateObject(object,player);
						player->addKnownObjectSafe(object);
						object->addKnownObjectSafe(player);
						updatedObjects++;
		
					}
					else
					{
						//if(!player->checkKnownObjects(object))
						//{
							gMessageLib->sendCreateObject(object,player);
							player->addKnownObjectSafe(object);
							object->addKnownObjectSafe(player);
							updatedObjects++;
						//}
					}
				}
			}
		}
		++mObjectSetIt;
	}
	return (mObjectSetIt == mInRangeObjects.end());
}
//=========================================================================================
//
// Find the objects observed/known objects when inside
//
void ObjectController::_findInRangeObjectsInside(bool updateAll)
{
	PlayerObject*	player = dynamic_cast<PlayerObject*>(mObject);
	float			viewingRange = _GetMessageHeapLoadViewingRange();
	CellObject*		playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()));


	// Make Set ready,
	mInRangeObjects.clear();

	// Init the iterator.
	mObjectSetIt = mInRangeObjects.begin();

	// make sure we got a cell
	if (!playerCell)
	{
		gLogger->logMsg("ERROR: No playerCell.");
		return;
	}

	Object* object = gWorldManager->getObjectById(playerCell->getParentId());
	//BuildingObject* building = dynamic_cast<BuildingObject*>(object);
	BuildingObject* building = dynamic_cast<BuildingObject*>(object);
	// make sure we got a building
	if (!building)
	{
		
		gLogger->logMsg("ERROR: No building.");
		return;
	}


	// mInRangeObjectIndex = 0;

	if (updateAll)
	{
		// This is good to use when entering a building.
		mSI->getObjectsInRange(player,&mInRangeObjects,(ObjType_Player | ObjType_Tangible | ObjType_NPC | ObjType_Creature | ObjType_Building | ObjType_Structure),viewingRange);

		// query the qtree based on the buildings world position
		if (QTRegion* region = mSI->getQTRegion(building->mPosition.x,building->mPosition.z))
		{
			Anh_Math::Rectangle qRect = Anh_Math::Rectangle(building->mPosition.x - viewingRange,building->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2);

			// We need to find moving creatures outside...
			region->mTree->getObjectsInRange(player,&mInRangeObjects,ObjType_Player | ObjType_NPC | ObjType_Creature, &qRect);
		}
	}
	else
	{
		// This is good to use when running around inside a building.

		// We need to see player or creatures spawning inside.

		// Added ObjType_Tangible because Tutorial spawns ObjType_Tangible in a way we don't normally do.
		// If we need more speed in normal cases, just add a test for Tutorial and de-select ObjType_Tangible if not active.
		mSI->getObjectsInRange(player,&mInRangeObjects,(ObjType_Tangible | ObjType_Player | ObjType_Creature | ObjType_NPC),viewingRange);

		// query the qtree based on the buildings world position
		if (QTRegion* region = mSI->getQTRegion(building->mPosition.x,building->mPosition.z))
		{
			Anh_Math::Rectangle qRect = Anh_Math::Rectangle(building->mPosition.x - viewingRange,building->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2);

			// We need to find moving creatures outside...
			region->mTree->getObjectsInRange(player,&mInRangeObjects,ObjType_Player | ObjType_NPC | ObjType_Creature,&qRect);
		}
	}
	// Update the iterator to start of Set.
	mObjectSetIt = mInRangeObjects.begin();
}
Example #14
0
void SpatialIndexManager::createInWorld(PlayerObject* player)
{
    //just create in the SI - it will keep track of nearby players
    this->_AddObject(player);

    //are we in a cell? otherwise bail out
    if(player->getParentId() == 0)	{
        return;
    }

    CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()));
    if(!cell)	{
        assert(false && "cannot cast cell ???? ");
        return;
    }

    BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId()));
    if(!building)	{
        assert(false && "cannot cast building ???? ");
        return;
    }

    //we *should* already be registered as known watcher to the building

    //add the Creature to the cell we are in
    cell->addObjectSecure(player);

    //iterate through all the cells and add the player as listener
    CellObjectList::iterator cellIt = building->getCellList()->begin();

    CellObjectList* cell_list = building->getCellList();

    std::for_each(cell_list->begin(), cell_list->end(), [player] (CellObject* cell) {
        gContainerManager->registerPlayerToContainer(cell, player);
    });
}
Example #15
0
void SpatialIndexManager::createInWorld(CreatureObject* creature)
{
    this->_AddObject(creature);

    //are we in a cell? otherwise bail out
    if(creature->getParentId() == 0)	{
        return;
    }

    CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(creature->getParentId()));
    if(!cell)	{
        assert(false && "SpatialIndexManager::createInWorld cannot cast cell ???? ");
        return;
    }

    BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId()));
    if(!building)	{
        assert(false && "SpatialIndexManager::createInWorld cannot cast building ???? ");
        return;
    }

    //add the Creature to the cell we are in
    cell->addObjectSecure(creature);
}
bool HandleMoveFurniture(
    Object* object,
    Object* target,
    Message* message,
    ObjectControllerCmdProperties* cmdProperties) {

    PlayerObject*	player	= dynamic_cast<PlayerObject*>(object);

    if (!player)	{
        assert(false && "ObjectController::HandleItemMoveDown_ Player not found");
        return false;
    }

    // Verify that there was a target passed.
    if (!target) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player);
        return false;
    }

    if(!target)	{
        assert(false && "ObjectController::HandleItemMoveDown_ item not found");
        return false;
    }

    // Verify that the item and player are in the same structure.
    CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()));
    if(!playerCell)	{
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player);
        return false;
    }
    uint64 playerStructure = playerCell->getParentId();

    CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId()));
    if(!objectCell)	{
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player);
        return false;
    }
    uint64 objectStructure = objectCell->getParentId();

    if (objectStructure != playerStructure) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player);
        return false;
    }

    // Verify that the player has appropriate rights on this structure.
    if (playerCell) {
        if (BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(playerCell->getParentId()))) {
            if (!building->getAdminData().check_admin(player->getId())) {
                gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "admin_move_only"), player);
                return false;
            }
        }	else {
            assert(false && "ObjectController::HandleItemMoveDown_ no structure");
            return false;
        }
    } else {
        //were just outside ??
        return false;
    }

    // Read the message out of the packet.
    BString tmp;
    message->getStringUnicode16(tmp);

    // If the string has no length the message is ill-formatted, send the
    // proper format to the client.
    if (!tmp.getLength()) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "format_movefurniture_distance"), player);
        return false;
    }

    // Convert the string to an ansi string for ease with the regex.
    tmp.convert(BSTRType_ANSI);
    std::string input_string(tmp.getAnsi());

    static const regex pattern("(forward|back|up|down) ([0-9]+)");
    smatch result;

    regex_search(input_string, result, pattern);

    // If the pattern doesn't match all elements then send the proper format
    // to the client.
    if (result.length() < 2) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "format_movefurniture_distance"), player);
        return false;
    }

    // Gather the results of the pattern for validation and use.
    std::string direction(result[1]);
    float distance = boost::lexical_cast<float>(result[2]);

    // If the the specified amount is not within the valid range notify the client.
    if ((distance < 1.0f) || (distance > 500.0f)) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "movefurniture_params"), player);
        return false;
    }

    // Move object an MOVE_INCREMENT times by the amount and direction specified.
    if (direction == "forward") {
        target->move(player->mDirection, distance * MOVE_INCREMENT);
    } else if (direction == "back") {
        target->move(player->mDirection, -distance * MOVE_INCREMENT);
    } else if (direction == "up") {
        target->mPosition.y += distance * MOVE_INCREMENT;
    } else if (direction == "down") {
        target->mPosition.y -= distance * MOVE_INCREMENT;
    }

    // Update the world with the changes.
    gMessageLib->sendDataTransformWithParent053(target);
    target->updateWorldPosition();

    return true;
}
//======================================================================================================================
//
// rotates an item	 90d to right
//
void	ObjectController::HandleItemRotateRight_(
    uint64 targetId,
    Message* message,
    ObjectControllerCmdProperties* cmdProperties) {

    CreatureObject* creature  = dynamic_cast<CreatureObject*>(mObject); PlayerObject* player = creature->GetGhost();

    if (!player)	{
        assert(false && "ObjectController::HandleItemRotateRight_ Player not found");
        return;
    }

    // Verify that there was a target passed.
    if (!targetId) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player);
        return;
    }

    Object* object = gWorldManager->getObjectById(targetId);

    if(!object)	{
        assert(false && "ObjectController::HandleItemRotateRight_ item not found");
        return;
    }

    // Verify that the item and player are in the same structure.
    // Verify that the item and player are in the same structure.
    CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()));
    if(!playerCell)	{
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player);
        return;
    }
    uint64 playerStructure = playerCell->getParentId();

    CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId()));
    if(!objectCell)	{
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player);
        return;
    }
    uint64 objectStructure = objectCell->getParentId();

    if (objectStructure != playerStructure) {
        gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player);
        return;
    }

    // Verify that the player has appropriate rights on this structure.
    if (playerCell) {
        if (BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(playerCell->getParentId()))) {
            if (!building->getAdminData().check_admin(player->getId())) {
                gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "admin_move_only"), player);
                return;
            }
        }	else {
            assert(false && "ObjectController::HandleItemRotateRight_ no structure");
            return;
        }
    } else {
        //were just outside
        return;
    }

    // Rotate the object 90 degree's to the right
    object->rotateRight(ROTATE_INCREMENT);

    gMessageLib->sendDataTransformWithParent053(object);
    object->updateWorldPosition();
}
void WorldManager::createObjectinWorld(Object* object)
{
	float				viewingRange	= _GetMessageHeapLoadViewingRange();
	ObjectSet inRangeObjects;
	mSpatialIndex->getObjectsInRange(object,&inRangeObjects,(ObjType_Player),viewingRange);

	// query the according qtree, if we are in one
	if(object->getSubZoneId())
	{
		if(QTRegion* region = getQTRegion(object->getSubZoneId()))
		{
			
			Anh_Math::Rectangle qRect;

			if(!object->getParentId())
			{
				qRect = Anh_Math::Rectangle(object->mPosition.x - viewingRange,object->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2);
			}
			else
			{
				CellObject*		cell		= dynamic_cast<CellObject*>(getObjectById(object->getParentId()));
				
				
				if(BuildingObject* house	= dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId())))
				{
					qRect = Anh_Math::Rectangle(house->mPosition.x - viewingRange,house->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2);
				}
			}

			region->mTree->getObjectsInRange(object,&inRangeObjects,ObjType_Player,&qRect);
		}
	}

	// iterate through the results
	ObjectSet::iterator it = inRangeObjects.begin();

	while(it != inRangeObjects.end())
	{
		PlayerObject* player = dynamic_cast<PlayerObject*> (*it);
		if(player)
		{
			// send create for the type of object
			if (object->getPrivateOwner())	//what is this about ?? does it concern instances ????
			{
				if (object->isOwnedBy(player))
				{
					gMessageLib->sendCreateObject(object,player);
					object->addKnownObjectSafe(player);
					player->addKnownObjectSafe(object);
				}
			}
			else
			{
				gMessageLib->sendCreateObject(object,player);
				
				object->addKnownObjectSafe(player);
				player->addKnownObjectSafe(object);
			}
		}
		++it;
	}
	
}