void GameInterface::walkTo(const Common::Point &mouse) {
	Resources::Floor *floor = StarkGlobal->getCurrent()->getFloor();
	Resources::ModelItem *april = StarkGlobal->getCurrent()->getInteractive();
	if (!floor || !april) {
		return;
	}

	Math::Ray mouseRay = StarkScene->makeRayFromMouse(mouse);

	// First look for a direct intersection with the floor
	Math::Vector3d destinationPosition;
	int32 destinationFloorFaceIndex = floor->findFaceHitByRay(mouseRay, destinationPosition);

	// Otherwise fall back to the floor face center closest to the ray
	if (destinationFloorFaceIndex < 0) {
		destinationFloorFaceIndex = floor->findFaceClosestToRay(mouseRay, destinationPosition);
	}

	if (destinationFloorFaceIndex < 0) {
		// No destination was found
		return;
	}

	Walk *walk = new Walk(april);
	walk->setDestination(destinationPosition);
	walk->start();

	april->setMovement(walk);
}
void GameInterface::setAprilRunning() {
	Current *current = StarkGlobal->getCurrent();
	Resources::ModelItem *april = current->getInteractive();
	Movement *movement = april->getMovement();
	Walk *walk = dynamic_cast<Walk *>(movement);
	walk->setRunning();
}
bool GameInterface::isAprilWalking() const {
	Current *current = StarkGlobal->getCurrent();
	if (!current) {
		return false;
	}

	Resources::ModelItem *april = current->getInteractive();
	if (!april) {
		return false;
	}

	Movement *movement = april->getMovement();
	if (!movement) {
		return false;
	}

	Walk *walk = dynamic_cast<Walk *>(movement);
	if (!walk) {
		return false;
	}

	return !walk->hasEnded();
}
void ResourceProvider::setAprilInitialPosition() {
	Current *current = _global->getCurrent();
	Resources::ModelItem *april = current->getInteractive();
	if (!april) {
		return; // No character
	}

	// Set the initial position for April
	if (!_nextPositionBookmarkReference.empty()) {
		Resources::Bookmark *position = _nextPositionBookmarkReference.resolve<Resources::Bookmark>();
		april->placeOnBookmark(position);

		Resources::Camera *camera = current->getCamera();
		Math::Angle cameraAngle = camera->getHorizontalAngle();
		april->setDirection(_nextDirection + cameraAngle);
	} else if (april->getFloorFaceIndex() <= 0) {
		// No target location provided, place April on the first floor face
		april->placeDefaultPosition();
	}

	_nextPositionBookmarkReference = ResourceReference();
	_nextDirection = 0;
}
Command *Command::opWalkTo(Script *script, const ResourceReference &objectRef, int32 suspend) {
	Resources::ModelItem *april = StarkGlobal->getCurrent()->getInteractive();

	Math::Vector3d destinationPosition = getObjectPosition(objectRef);
	Math::Vector3d currentPosition = april->getPosition3D();

	if (destinationPosition == currentPosition) {
		return nextCommand();
	}

	Walk *walk = new Walk(april);
	walk->setDestination(destinationPosition);
	walk->start();

	april->setMovement(walk);

	if (suspend) {
		script->suspend(april);
		april->setMovementSuspendedScript(script);
		return this; // Stay on the same command while suspended
	} else {
		return nextCommand();
	}
}