bool CreatureObject::mountCreature(CreatureObject &mountObject)
{
	//-- Ensure mounts are enabled.
	if (!ConfigServerGame::getMountsEnabled())
	{
		LOG(cs_mountInfoChannelName, ("CreatureObject::mountCreature() called on rider object id=[%s] when mounts are disabled, ignoring call.", getNetworkId().getValueString().c_str()));
		return false;
	}

	//-- Ensure we (the rider) are not already mounted.
	if (getState(States::RidingMount))
	{
		DEBUG_FATAL(true, ("mountCreature(): rider id=[%s] template=[%s] is already riding a mount.", getNetworkId().getValueString().c_str(), getObjectTemplateName()));
		return false;
	}

	//-- Ensure the mount is mountable.
	if (!mountObject.isMountable())
	{
		DEBUG_FATAL(true, ("mountCreature(): specified mountObject id=[%s] template=[%s] is not mountable.", mountObject.getNetworkId().getValueString().c_str(), mountObject.getObjectTemplateName()));
		return false;
	}

	//-- Ensure both the mount and the rider are authoritative on this server.
	//   (They should be by design of how this function gets called.)
	if (!isAuthoritative() || !mountObject.isAuthoritative())
	{
		DEBUG_WARNING(true, ("mountCreature(): rider id=[%s] or mount id=[%s] was not authoritative on this server, mounting aborted.", getNetworkId().getValueString().c_str(), mountObject.getNetworkId().getValueString().c_str()));
		return false;
	}

	//-- Reject if the player is not in the world cell
	if (!isInWorldCell())
	{
		DEBUG_WARNING(true, ("mountCreature(): rider id=[%s] is not in the world cell, mounting aborted.", getNetworkId().getValueString().c_str()));
		return false;
	}

	//-- Reject if the mount is not in the world cell
	if (!mountObject.isInWorldCell())
	{
		DEBUG_WARNING(true, ("mountCreature(): mount id=[%s] is not in the world cell, mounting aborted.", mountObject.getNetworkId().getValueString().c_str()));
		return false;
	}

	// ... set the new mount-related states on the rider and mount.  This is necessary
	//     so that I can efficiently handle CreatureObject::onContainerTransferComplete,
	//     which is called before transferItemToSlottedContainer() completes.
	setState(States::RidingMount, true);
	mountObject.setState(States::MountedCreature, true);
	
	Container::ContainerErrorCode errorCode = Container::CEC_Success;
	bool transferSuccess = false;

	// transfer into the first available slot

	int const maxSlots = getSaddleSeatingCapacity(&mountObject);

	for (int i = 0; i < maxSlots; ++i)
	{
		if (ContainerInterface::canTransferToSlot(mountObject, *this, s_riderSlotId[i], NULL, errorCode))
		{
			transferSuccess = ContainerInterface::transferItemToSlottedContainer(mountObject, *this, s_riderSlotId[i], NULL, errorCode);

			if ((transferSuccess) && (errorCode == Container::CEC_Success))
			{
				break;
			}
		}
	}
	
	DEBUG_FATAL(transferSuccess && (errorCode != Container::CEC_Success), ("mountCreature(): transferItemToSlottedContainer() returned success but container error code returned error %d.", static_cast<int>(errorCode)));

	if (!transferSuccess)
	{
		// Clear these states so that the objects are not in a funky bad state.
		setState(States::RidingMount, false);

		if (mountObject.getPrimaryMountingRider() == 0)
		{
			// clear state if empty mount
			mountObject.setState(States::MountedCreature, false);
		}

		return transferSuccess;
	}

	//-- Take the rider out of CollisionWorld.
	// @todo: add all object non-auto-delta change info to another function
	//        that can be called via controller message to proxies, end baselines
	//        on proxies and from here.
	if (isInWorld())
		CollisionWorld::removeObject(this);

	CollisionProperty *const collisionProperty = getCollisionProperty();
	if (collisionProperty)
		collisionProperty->setDisableCollisionWorldAddRemove(true);

	//-- Set the mount's AlterScheduler phase to 1 so that it gets an alter after the rider.
	//   The rider will count on this so that the rider can update the mount's server position
	//   prior to the mount getting altered that frame.
	AlterScheduler::setObjectSchedulePhase(mountObject, 1);

	//-- Tell rider to update movement info so it pulls walk/run speed from the mount.
	updateMovementInfo();
	
	//-- Indicate transfer success.
	return transferSuccess;
}