//*********************************************************************
//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 #2
0
void MovingObject::updatePositionInCell(uint64 parentId, const glm::vec3& newPosition)
{
    uint64 oldParentId = this->getParentId();
    if (oldParentId != parentId)
    {
        // We changed cell
        CellObject* cell = NULL;

        // Remove us.
        if (!this->getKnownPlayers()->empty())
        {
            gMessageLib->broadcastContainmentMessage(this,oldParentId,0);
        }

        // only remove us from si, if we just entered the building
        if (oldParentId != 0)
        {
            // We are still inside.
            if ((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(oldParentId))))
            {
                cell->removeObject(this);
            }
            else
            {
                LOG(WARNING) << "Error removing " << this->getId() << " from cell " << this->getParentId();
            }
        }
        else
        {
            // remove us from qt
            // We just entered a building.
            if (this->getSubZoneId())
            {
                if (std::shared_ptr<QTRegion> region = gWorldManager->getQTRegion(this->getSubZoneId()))
                {
                    this->setSubZoneId(0);
                    region->mTree->removeObject(this);
                }
            }
        }

        // put us into new one
        if (!this->getKnownPlayers()->empty())
        {
            gMessageLib->broadcastContainmentMessage(this,parentId,4);
        }
        if ((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(parentId))))
        {
            cell->addObjectSecure(this);
        }
        else
        {
            LOG(WARNING) << "Error adding " << this->getId() << " from cell " << this->getParentId();
        }
        // update the player
        this->setParentId(parentId);
    }
}
void ElevatorTerminal::handleObjectMenuSelect(uint8 messageType,Object* srcObject)
{
	PlayerObject* playerObject = dynamic_cast<PlayerObject*>(srcObject);

	if(!playerObject || !playerObject->isConnected() || playerObject->getSamplingState() || playerObject->isIncapacitated() || playerObject->isDead())
	{
		return;
	}

	if(messageType == radId_elevatorUp)
	{
		gMessageLib->sendPlayClientEffectObjectMessage(gWorldManager->getClientEffect(mEffectUp),"",playerObject);

		// remove player from current position, elevators can only be inside
		CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId()));

		if(cell)
		{
			cell->removeObject(playerObject);
		}
		else
		{
			gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,playerObject->getParentId());
		}

		// put him into new one
		playerObject->mDirection = mDstDirUp;
		playerObject->mPosition  = mDstPosUp;
		playerObject->setParentId(mDstCellUp);

		cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(mDstCellUp));

		if(cell)
		{
			cell->addObjectSecure(playerObject);
		}
		else
		{
			gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,mDstCellUp);
		}

		gMessageLib->sendDataTransformWithParent(playerObject);

	}
	else if(messageType == radId_elevatorDown)
	{
		gMessageLib->sendPlayClientEffectObjectMessage(gWorldManager->getClientEffect(mEffectDown),"",playerObject);
	
		// remove player from current position, elevators can only be inside
		CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId()));

		if(cell)
		{
			cell->removeObject(playerObject);
		}
		else
		{
			gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,playerObject->getParentId());
		}

		// put him into new one
		playerObject->mDirection = mDstDirDown;
		playerObject->mPosition  = mDstPosDown;
		playerObject->setParentId(mDstCellDown);
		
		cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(mDstCellDown));

		if(cell)
		{
			cell->addObjectSecure(playerObject);
		}
		else
		{
			gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,mDstCellDown);
		}

		gMessageLib->sendDataTransformWithParent(playerObject);
	}
	else
	{
		gLogger->logMsgF("ElevatorTerminal: Unhandled MenuSelect: %u",MSG_HIGH,messageType);
	}
}
Example #4
0
bool ObjectController::removeFromContainer(uint64 targetContainerId, uint64 targetId)
{
	PlayerObject*	playerObject	=	dynamic_cast<PlayerObject*>(mObject);
	Object*			itemObject		=	gWorldManager->getObjectById(targetId);
	Inventory*		inventory		=	dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory));
	TangibleObject* targetContainer = dynamic_cast<TangibleObject*>(gWorldManager->getObjectById(targetContainerId));

	TangibleObject* tangible = dynamic_cast<TangibleObject*>(itemObject);

	Item* item = dynamic_cast<Item*>(itemObject);

	// its us
	if (tangible->getParentId() == playerObject->getId())
	{
		// unequip it
		return playerObject->getEquipManager()->unEquipItem(itemObject);
		
	}
	
	//the containerObject is the container used in the tutorial or some random dungeon container
	Container* container = dynamic_cast<Container*>(gWorldManager->getObjectById(tangible->getParentId()));
	if (container)
	{
		container->removeObject(itemObject);
		//gContainerManager->destroyObjectToRegisteredPlayers(container, tangible->getId());
		if (gWorldConfig->isTutorial())
		{
			playerObject->getTutorial()->transferedItemFromContainer(targetId, tangible->getParentId());

			// If object is owned by player (private owned for instancing), we remove the owner from the object.
			// what is this used for ???
			if (itemObject->getPrivateOwner() == playerObject->getId())
			{
				itemObject->setPrivateOwner(0);
			}
		}
		return true;
	}

	//creature inventories are a special case - their items are temporary!!! we cannot loot them directly
	CreatureObject* unknownCreature;
	Inventory*		creatureInventory;


	if (itemObject->getParentId() &&
		(unknownCreature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(itemObject->getParentId() - INVENTORY_OFFSET))) &&
		(creatureInventory = dynamic_cast<Inventory*>(unknownCreature->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))) &&
		(creatureInventory->getId() == itemObject->getParentId()) && (creatureInventory->getId() != inventory->getId()))
	{
		
		if(!creatureInventory->removeObject(itemObject))
		{
			LOG(warning) << "ObjectController::removeFromContainer: Internal Error could not remove  " <<  itemObject->getId() << " from creature inventory "  << creatureInventory->getId();
			return false;
		}


		// we destroy the item in this case as its a temporary!! 
		// we do not want to clog the db with unlooted items
		gContainerManager->destroyObjectToRegisteredPlayers(creatureInventory, tangible->getId());

		ObjectIDList* invObjList = creatureInventory->getObjects();
		if (invObjList->size() == 0)
		{
			// Put this creature in the pool of delayed destruction and remove the corpse from scene.
			gWorldManager->addCreatureObjectForTimedDeletion(creatureInventory->getParentId(), LootedCorpseTimeout);
		}
		
		if (gWorldConfig->isTutorial())
		{
			// TODO: Update tutorial about the loot.
			playerObject->getTutorial()->transferedItemFromContainer(targetId, creatureInventory->getId());
		}

		//bail out here and request the item over the db - as the item in the NPC has a temporary id and we dont want that in the db
		// This ensure that we do not use/store any of the temp id's in the database.
        gObjectFactory->requestNewDefaultItem(inventory, item->getItemFamily(), item->getItemType(), inventory->getId(), 99, glm::vec3(), "");
		return false;

	}		   

	//cells are NOT tangibles - thei are static Objects
	CellObject* cell;
	if(cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(itemObject->getParentId())))
	{
		// Stop playing if we pick up the (permanently placed) instrument we are playing
		if (item && (item->getItemFamily() == ItemFamily_Instrument))
		{
			uint32 instrumentType = item->getItemType();
			if ((instrumentType == ItemType_Nalargon) || (instrumentType == ItemType_omni_box) || (instrumentType == ItemType_nalargon_max_reebo))
			{
				// It's a placeable original instrument.
				// Are we targeting the instrument we actually play on?
				if (playerObject->getActiveInstrumentId() == item->getId())
				{
					gEntertainerManager->stopEntertaining(playerObject);
				}
			}
		}
		
		//we *cannot* remove static tangibles like the structureterminal!!!!
		if(tangible->getStatic())
		{
			return false;
		}

		// Remove object from cell.
		cell->removeObject(itemObject);
		return true;
	}

	//some other container ... hopper backpack chest etc
	TangibleObject* containingContainer = dynamic_cast<TangibleObject*>(gWorldManager->getObjectById(tangible->getParentId()));
	if(containingContainer && containingContainer->removeObject(itemObject))
	{
		return true;
	}
	
	return false;
}
void ObjectController::handleDataTransformWithParent(Message* message,bool inRangeUpdate)
{
	// FIXME: for now assume we only get messages from players
	PlayerObject*	player = dynamic_cast<PlayerObject*>(mObject);
    glm::vec3       pos;
    glm::quat       dir;
	uint32          inMoveCount;
	uint32			tickCount;
	uint64			parentId;
	float			speed;
	bool			updateAll = false;

	// get tick and move counters
	tickCount	= message->getUint32();
	inMoveCount = message->getUint32();

	// only process if its in sequence
	if (player->getInMoveCount() <= inMoveCount)
	{
		uint64 oldParentId = player->getParentId();

		//uint32 ticks = tickCount - player->getClientTickCount();

		// update tick and move counters
		player->setClientTickCount(tickCount);
		player->setInMoveCount(inMoveCount);

		// get new direction, position, parent and speed
		parentId = message->getUint64();
		dir.x = message->getFloat();
		dir.y = message->getFloat();
		dir.z = message->getFloat();
		dir.w = message->getFloat();
		pos.x = message->getFloat();
		pos.y = message->getFloat();
		pos.z = message->getFloat();
		speed  = message->getFloat();


		// gLogger->logMsgF("Position inside = %f, %f, %f",MSG_NORMAL, pos.x,  pos.y, pos.z);
		// gLogger->logMsgF("Direction = %f, %f, %f, %f",MSG_NORMAL, dir.x, dir.y, dir.z, dir.w);

		// stop entertaining, if we were
		if(player->getPerformingState() != PlayerPerformance_None && player->getPosture() != CreaturePosture_SkillAnimating)
		{
			gEntertainerManager->stopEntertaining(player);
		}

		// if we changed cell
		if (oldParentId != parentId)
		{

			

			CellObject* cell = NULL;

			// gLogger->logMsgF("We changed cell from (%"PRIu64") to (%"PRIu64")",MSG_NORMAL, oldParentId, parentId);

			// Remove us from whatever we where in before.
			// (4 for add and 0 for remove)
			gMessageLib->broadcastContainmentMessage(player->getId(),oldParentId,0,player);

			// only remove us from si, if we just entered the building
			if (oldParentId != 0)
			{
				if((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(oldParentId))))
				{
					cell->removeObject(player);
					// Done above.. gMessageLib->broadcastContainmentMessage(player->getId(),parentId,4,player);
				}
				else
				{
					gLogger->logMsgF("Error removing %"PRIu64" from cell(%"PRIu64")",MSG_NORMAL,player->getId(),oldParentId);
				}
			}
			else
			{
				updateAll = true;		// We just entered the building.

				// remove us from qt
				if(player->getSubZoneId())
				{
					if(QTRegion* region = gWorldManager->getQTRegion(player->getSubZoneId()))
					{
						player->setSubZoneId(0);
						region->mTree->removeObject(player);
						//If our player is mounted lets update his mount aswell
						if(player->checkIfMounted() && player->getMount())
						{
							player->getMount()->setSubZoneId(0);
							region->mTree->removeObject(player->getMount());

							//Can't ride into a building with a mount! :-p
							//However, its easy to do so we have handling incase the client is tricked.


							// the vehicle is the INTANGIBLE Datapad Controller
							// the *vehicle* itself is the BODY
							if(Vehicle* datapad_pet = dynamic_cast<Vehicle*>(gWorldManager->getObjectById(player->getMount()->getPetController())))
							{
								datapad_pet->dismountPlayer();
								datapad_pet->store();
							}
						}
					}
				}
			}

			// put us into new one
			gMessageLib->broadcastContainmentMessage(player->getId(),parentId,4,player);
			if((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(parentId))))
			{

				cell->addObjectSecure(player);

				// Inform tutorial about cell change.
				if (gWorldConfig->isTutorial())
				{
					player->getTutorial()->setCellId(parentId);
					// gLogger->logMsgF("handleDataTransformWithParent: Adding %"PRIu64" to cell(%"PRIu64")",MSG_NORMAL,player->getId(),parentId);
				}
			}
			else
			{
				gLogger->logMsgF("Error adding %"PRIu64" to cell(%"PRIu64")",MSG_NORMAL,player->getId(),parentId);
			}
		}

		// update the player
		player->setParentId(parentId);
		player->mDirection = dir;
		player->mPosition  = pos;
		player->setCurrentSpeed(speed);

		// destroy the instanced instrument if out of range
		if (player->getPlacedInstrumentId())
		{
			if (!gWorldManager->objectsInRange(player->getId(), player->getPlacedInstrumentId(), 5.0))
			{
				if (Item* item = dynamic_cast<Item*>(gWorldManager->getObjectById(player->getPlacedInstrumentId())))
				{
					destroyObject(item->getId());
				}
			}
		}

		// Terminate active conversation with npc if to far away (trainers only so far).
		ActiveConversation* ac = gConversationManager->getActiveConversation(player->getId());
		if (ac != NULL)
		{
			// We do have a npc conversation going.
			if (!gWorldManager->objectsInRange(player->getId(), (ac->getNpc())->getId(), 11.0))
			{
				// Terminate conversation, since we are out of range.
				gMessageLib->sendSystemMessage(player,L"","system_msg","out_of_range");
				gConversationManager->stopConversation(player, true);			// We will get the current dialog text in a chat bubble, only seen by me. Impressive :)
			}
		}

		if (updateAll)
		{
			// Update our world.
			playerWorldUpdate(true);

			// Speed up the timed update, if any pending.
			gWorldManager->addPlayerMovementUpdateTime(player, 250);
		}
		else
		{
			if (!gWorldConfig->isInstance())
			{
				// send out updates
				gMessageLib->sendUpdateTransformMessageWithParent(player);
			}
			else
			{
				// send out position updates to known players in group or self only
				gMessageLib->sendUpdateTransformMessageWithParent(player, player);
			}
		}
	}
}