AiLocation::AiLocation ( NetworkId const & cellId, Vector const & position, float radius )
:	m_valid(true),
	m_attached(false),
	m_object(NULL),
	m_objectId(),
	m_cellObject(NULL),
	m_position_p(position),
	m_position_w(position),
	m_radius(radius),
	m_offset_p(Vector::zero),
	m_relativeOffset(false),
	m_hasChanged(true),
	m_cuttable(true),
	m_debugId(gs_debugCounter++)
{
	if(cellId.isValid())
	{
		m_cellObject = NetworkIdManager::getObjectById(cellId);
	}
	else
	{
		m_cellObject = &CellProperty::getWorldCellProperty()->getOwner();
	}

	if(m_cellObject)
	{
		m_position_w = CollisionUtils::transformToWorld(m_cellObject->getCellProperty(),m_position_p);
	}

	VALIDATE_LOCATION();
}
void CreatureObject::makePetMountable()
{
	//-- Ensure mounts are enabled.
	if (!ConfigServerGame::getMountsEnabled())
	{
		LOG(cs_mountInfoChannelName, ("CreatureObject::makePetMountable() called on object id=[%s] when mounts are disabled, ignoring call.", getNetworkId().getValueString().c_str()));
		return;
	}
	
	//-- Validate preconditions.
	DEBUG_FATAL(!isAuthoritative(), ("makePetMountable(): called on non-authoritative creature id=[%s],template=[%s].", getNetworkId().getValueString().c_str(), getObjectTemplateName()));
	DEBUG_FATAL(getMountabilityStatus() != static_cast<int>(MountValidScaleRangeTable::MS_creatureMountable), ("makePetMountable(): creature id=[%s],template=[%s] this creature cannot be made mountable. Caller should have checked getMountabilityStatus() first.", getNetworkId().getValueString().c_str(), getObjectTemplateName()));
	DEBUG_FATAL(isMountable(), ("makePetMountable(): creature id=[%s],template=[%s] already is mountable.  Caller doesn't need to call makePetMountable().", getNetworkId().getValueString().c_str(), getObjectTemplateName()));

	//-- Get the pet control device network id.
	NetworkId const pcdNetworkId = getPetControlDeviceId();
	if (!pcdNetworkId.isValid())
	{
		DEBUG_FATAL(true, ("makePetMountable(): creature id=[%s],template=[%s] does not have a valid pet control device id on it. Expecting script to place this objvar on the pet.", getNetworkId().getValueString().c_str(), getObjectTemplateName()));
		return;
	}

	//-- Set the Condition bit to indicate we're a mount.
	setCondition(getCondition() | static_cast<int>(ServerTangibleObjectTemplate::C_mount));

	//-- Set the Creature as static so that it doesn't count against the spawn limit.
	setIsStatic(true);
}
BufferId NetworkModelController::findQueryBuffer(const QModelIndex &index, const QString &predefinedNick) const
{
    NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
    if (!networkId.isValid())
        return BufferId();

    QString nick = predefinedNick.isEmpty() ? nickName(index) : predefinedNick;
    if (nick.isEmpty())
        return BufferId();

    return findQueryBuffer(networkId, nick);
}
Beispiel #4
0
void NickView::startQuery(const QModelIndex &index)
{
    if (index.data(NetworkModel::ItemTypeRole) != NetworkModel::IrcUserItemType)
        return;

    IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
    NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
    if (!ircUser || !networkId.isValid())
        return;

    Client::bufferModel()->switchToOrStartQuery(networkId, ircUser->nick());
}
void ContextMenuActionProvider::addNetworkItemActions(QMenu *menu, const QModelIndex &index)
{
    NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
    if (!networkId.isValid())
        return;
    const Network *network = Client::network(networkId);
    Q_CHECK_PTR(network);
    if (!network)
        return;

    addAction(NetworkConnect, menu, network->connectionState() == Network::Disconnected);
    addAction(NetworkDisconnect, menu, network->connectionState() != Network::Disconnected);
    menu->addSeparator();
    addAction(ShowChannelList, menu, index, ActiveState);
    addAction(JoinChannel, menu, index, ActiveState);
}
void PositionUpdateTracker::sendPositionUpdate(ServerObject &obj)
{
	if (!s_installed)
		return;

	std::map<ServerObject *, ServerObject **>::iterator i = s_positionUpdateCallbackMap.find(&obj);
	if (i != s_positionUpdateCallbackMap.end())
	{
		*((*i).second) = 0;
		s_positionUpdateCallbackMap.erase(i);
	}

	if (!shouldSendPositionUpdate(obj))
		return;

	if (ConfigServerGame::getLogPositionUpdates())
	{
		LOG("PositionUpdate", ("Sending position update for %s", obj.getNetworkId().getValueString().c_str()));
	}

	NetworkId const loadWithId = ContainerInterface::getLoadWithContainerId(obj);

	//-- Determine Object container's network id and Object's arrangement as far as the Database is concerned.
	NetworkId containerNetworkIdForDatabase = ContainerInterface::getContainedByProperty(obj)->getContainedByNetworkId();
	int objectArrangementForDatabase = ContainerInterface::getSlottedContainmentProperty(obj)->getCurrentArrangement();
	Transform transformForDatabase(obj.getTransform_o2p());
	Transform worldspaceTransformForDatabase(obj.getTransform_o2w());

	// if it's a player inside a container, the world space coordinate
	// that should be saved is the world space coordinate of the topmost
	// container; this way, player logging out of a house will get
	// loaded back into the same game server as the house, thus maximizing
	// that chance that the player will loaded back into the house
	if (obj.isPlayerControlled() && obj.asCreatureObject())
	{
		Object const *containerObj = ContainerInterface::getTopmostContainer(obj);
		if (containerObj && (containerObj != &obj))
		{
			worldspaceTransformForDatabase = containerObj->getTransform_o2w();
		}
	}

	// Ships should be persisted in their ship control device if they have one
	ShipObject const * const ship = obj.asShipObject();
	if (ship)
	{
		ServerObject const * const shipControlDevice = ship->getControlDevice();
		if (shipControlDevice)
		{
			containerNetworkIdForDatabase = shipControlDevice->getNetworkId();
			objectArrangementForDatabase = -1;
			transformForDatabase.resetRotateTranslate_l2p();
		}
	}
	else
	{
		ShipObject const * const containingShip = ShipObject::getContainingShipObject(&obj);

		if (obj.isPlayerControlled())
		{
			if (containingShip)
			{
				// Player controlled objects in ships persist at the location of the ship.
				// Note: we need a more general solution if we decide to allow ships in interiors of ships.
				containerNetworkIdForDatabase = ContainerInterface::getContainedByProperty(*containingShip)->getContainedByNetworkId();
				objectArrangementForDatabase = -1;
				transformForDatabase = containingShip->getTransform_o2p();
			}
			else
			{
				ServerObject const * const container = safe_cast<ServerObject const *>(ContainerInterface::getContainedByObject(obj));
				CreatureObject const * const creatureContainer = (container ? container->asCreatureObject() : NULL);
				if (creatureContainer && creatureContainer->isMountable())
				{
					// Riders of mounts persist at the location of the mount
					containerNetworkIdForDatabase = ContainerInterface::getContainedByProperty(*creatureContainer)->getContainedByNetworkId();
					objectArrangementForDatabase = -1;
					transformForDatabase = creatureContainer->getTransform_o2p();
				}
			}
		}
	}

	// Make sure we aren't about to try to save an invalid containment/load_with state
	if (containerNetworkIdForDatabase == NetworkId::cms_invalid && loadWithId != obj.getNetworkId())
	{
		WARNING_DEBUG_FATAL(true, ("Tried to send a position update to the db for object %s with load_with=%s but contained_by=0!", obj.getNetworkId().getValueString().c_str(), loadWithId.getValueString().c_str()));
		obj.unload();
		return;
	}

	// Make sure we aren't about to try to save a persisted non-player in a space scene away from the origin
	FATAL(ServerWorld::isSpaceScene() && !obj.isPlayerControlled() && !containerNetworkIdForDatabase.isValid() && transformForDatabase.getPosition_p() != Vector::zero, ("Tried to send a non-origin persisted object position to the db in a space scene for non-player object %s", obj.getDebugInformation().c_str()));

	//Vector vp = transformForDatabase.getPosition_p();
	//Vector vw = obj.getTransform_o2w().getPosition_p();
	//LOG("PositionUpdateTracker",("sendPositionUpdate PS XYZ (%f %f %f)   WS XYZ (%f %f %f)",vp.x, vp.y, vp.z, vw.x, vw.y, vw.z));

	UpdateObjectPositionMessage const positionMessage(
		obj.getNetworkId(),
		transformForDatabase,
		worldspaceTransformForDatabase,
		containerNetworkIdForDatabase,
		objectArrangementForDatabase,
		loadWithId,
		obj.isPlayerControlled(),
		obj.asCreatureObject() ? true : false);

	GameServer::getInstance().sendToDatabaseServer(positionMessage);

	if (loadWithId != obj.getLoadWith())
	{
		obj.setLoadWith(loadWithId);
		Container * const container = ContainerInterface::getContainer(obj);
		if (container)
		{
			for (ContainerIterator j = container->begin(); j != container->end(); ++j)
			{
				ServerObject * const content = safe_cast<ServerObject *>((*j).getObject());
				if (content)
					sendPositionUpdate(*content);
			}
		}
	}
}
void AiLocation::unpack( Archive::ReadIterator & source )
{
	Archive::get(source, m_valid);
	Archive::get(source, m_attached);
	Archive::get(source, m_relativeOffset);
	Archive::get(source, m_hasChanged);
	Archive::get(source, m_cuttable);
	Archive::get(source, m_debugId);
	Archive::get(source, m_radius);

	uint8 package;
	Archive::get(source, package);
	switch (static_cast<AiLocationArchive::AiLocationPackage>(package))
	{
		case AiLocationArchive::ALP_None:
			// do nothing
			break;
		case AiLocationArchive::ALP_Cell:
			{
				NetworkId cellId;
				Archive::get(source, cellId);
				Archive::get(source, m_position_p);
				m_position_w = m_position_p;
				if (cellId.isValid())
				{
					m_cellObject = NetworkIdManager::getObjectById(cellId);
				}
				else
				{
					m_cellObject = &CellProperty::getWorldCellProperty()->getOwner();
				}

				if (m_cellObject)
				{
					m_position_w = CollisionUtils::transformToWorld(m_cellObject->getCellProperty(),m_position_p);
				}
			}
			break;
		case AiLocationArchive::ALP_World:
			{
				Archive::get(source, m_position_w);
				m_position_p = m_position_w;
			}
			break;
		case AiLocationArchive::ALP_Object:
			{
				NetworkId objectId;
				Archive::get(source, objectId);
				setObject(NetworkIdManager::getObjectById(objectId));
			}
			break;
		case AiLocationArchive::ALP_OffsetObject:
			{
				NetworkId objectId;
				Archive::get(source, objectId);
				Archive::get(source, m_offset_p);
				setObject(NetworkIdManager::getObjectById(objectId));
			}
			break;
		default:
			WARNING(true, ("AiLocation::AiLocation(archive) received unknown data "
				"type %d", static_cast<int>(package)));
			break;
	}
	
	VALIDATE_LOCATION();	
}