void Functions::actionDoCommand(Aurora::NWScript::FunctionContext &ctx) {
	Common::UString script = ctx.getScriptName();
	if (script.empty())
		throw Common::Exception("Functions::actionDoCommand(): Script needed");

	const Aurora::NWScript::ScriptState &state = ctx.getParams()[0].getScriptState();

	_game->getModule().delayScript(script, state, ctx.getCaller(), ctx.getTriggerer(), 0);
}
void Functions::beginConversation(Aurora::NWScript::FunctionContext &ctx) {
	ctx.getReturn() = 0;

	// Get the script object parameters
	Aurora::NWScript::Object *obj1 = ctx.getCaller();
	Aurora::NWScript::Object *obj2 = getParamObject(ctx, 1);
	if (!obj2)
		obj2 = ctx.getTriggerer();
	if (!obj2)
		obj2 = _game->getModule().getPC();

	// Try to convert them to an NWN Creature and Object
	NWN::Creature *pc     = NWN::ObjectContainer::toPC(obj2);
	NWN::Object   *object = NWN::ObjectContainer::toObject(obj1);

	// Try the other way round, if necessary
	if (!pc || !object) {
		pc     = NWN::ObjectContainer::toPC(obj1);
		object = NWN::ObjectContainer::toObject(obj2);
	}

	// Fail
	if (!pc || !object)
		return;

	if (object->getPCSpeaker()) {
		if (object->getPCSpeaker() != pc) {
			Creature *otherPC = NWN::ObjectContainer::toPC(object->getPCSpeaker());

			warning("Functions::beginConversation(): "
			        "Object \"%s\" already in conversation with PC \"%s\"",
			        object->getTag().c_str(), otherPC ? otherPC->getName().c_str() : "");
			return;
		}
	}

	Common::UString conversation = ctx.getParams()[0].getString();
	if (conversation.empty())
		conversation = object->getConversation();

	ctx.getReturn() = _game->getModule().startConversation(conversation, *pc, *object);
}
void Functions::getExitingObject(Aurora::NWScript::FunctionContext &ctx) {
	// TODO: This should return the *last* exited object, i.e. it should remember past triggerers.
	ctx.getReturn() = ctx.getTriggerer();
}
void Functions::getClickingObject(Aurora::NWScript::FunctionContext &ctx) {
	ctx.getReturn() = ctx.getTriggerer();
}