Downloads containing Fio6_a.j2as

Downloads
Name Author Game Mode Rating
JJ2+ Only: Find It Out (Single Player)Featured Download Superjazz Single player 8.7 Download file

File preview

#include "Fio_common.asc"
#include "Fio_cutscene.asc"
#include "Fio_entities.asc"
#include "Fio_globals.asc"

const float CAMERA_FINAL_X = TILE * 47.5;
const float CAMERA_FINAL_Y = TILE * 137;
const float CAMERA_INITIAL_X = TILE * 47.5;
const float CAMERA_INITIAL_Y = TILE * 160;
const float CAMERA_SCROLL_DURATION = CUTSCENE_SECOND * 3;
const float CAMERA_STILL_DURATION = CUTSCENE_SECOND * 22;
const float FADE_BLACK_DURATION_TOTAL = CUTSCENE_SECOND * 2;
const float FADE_BLACK_DURATION_BLACKOUT = CUTSCENE_SECOND;
const float FADE_WHITE_DURATION_TOTAL = CUTSCENE_SECOND;
const float FADE_WHITE_DURATION_WHITEOUT = 15;
const float RABBIT_DIZZY_DURATION = CUTSCENE_SECOND * 2;
const float RABBIT_IDLE_DURATION = CUTSCENE_SECOND * 16;
const float RABBIT_LOOKUP_DURATION = CUTSCENE_SECOND * 4;
const float RABBIT_X = TILE * 44;
const float RABBIT_Y = TILE * 137.4;
const float SPAZ_Y_OFFSET = -0.15;
const float TELEPORT_X = TILE * 47;
const float TELEPORT_Y = TILE * 134;

const string NEXT_LEVEL_FILENAME = "Fio6_End.j2l";

bool isCoinRainActive = false;

ANIM::Set playerAnimSet;

CharacterWithMindStone@ character;

array<string> cutsceneTexts = {
	"||||After reaching the soul of Nicholas, you were taken on another journey through space by mystic energies...",
	"||||After a while, you are finally warped into an environment that somehow seems familiar, even though you don't recall visiting it personally.",
	"", // Empty for focus on visuality
	"", // Empty for focus on visuality
	"|||Welcome my savior, to my home, the tower of Nicus! And thank you for setting me free from the soul prison. I am back to my true form.",
	"|||What you have accomplished is something that many would deem impossible. You truly deserve your prize as I promised.",
	"|||Here you go! I'll give you half of the riches that I have in my storage.",
	"|Ehh, thanks...but I think this is not what I really want or need.",
	"|What I truly need is a new home, since my last one got burned to the ground. As long as I have a home to go to, I need no other riches to myself.",
	"|||Very well. That can be arranged. I will contact your kind and handle that with them, together with the assistance from my servants.",
	"|||We will also need to take care of the lizards so that they won't disturb you again.",
	"|||By the way, where exactly was your home again?"
};

void createRabbitAnimations() {
	float rabbitY = play.charOrig == CHAR::SPAZ ? RABBIT_Y + SPAZ_Y_OFFSET : RABBIT_Y;
	const array<fioCut::Animation@> animationsIntroRabbit = {
		fioCut::Animation(RABBIT_DIZZY_DURATION,
				RABBIT_X, rabbitY,
				RABBIT_X, rabbitY,
				0, 1, 1, playerAnimSet, RABBIT::STONED, 0, playerAnimSet == ANIM::LORI ? 11 : 7, 2),
		fioCut::Animation(RABBIT_IDLE_DURATION,
				RABBIT_X, rabbitY,
				RABBIT_X, rabbitY,
				0, 1, 1, playerAnimSet, character.idleAnimation, character.idleFrame, character.idleFrame, 1), // Framerate doesn't really matter here but w/e
		fioCut::Animation(RABBIT_LOOKUP_DURATION,
				RABBIT_X, rabbitY,
				RABBIT_X, rabbitY,
				0, 1, 1, playerAnimSet, RABBIT::LOOKUP, 0, 0, 1), // Framerate doesn't really matter here but w/e
		fioCut::Animation(RABBIT_IDLE_DURATION * 2, // Just to make sure it's enough :)
				RABBIT_X, rabbitY,
				RABBIT_X, rabbitY,
				0, 1, 1, playerAnimSet, character.idleAnimation, character.idleFrame, character.idleFrame, 1) // Framerate doesn't really matter here but w/e
	};
	fioCut::createAnimationChain(animationsIntroRabbit);
}

void createTeleportAnimations() {
	
	// Duration, xOrigin, yOrigin, xDestination, yDestination, angle, scaleX, scaleY, animSet, animationId,
	// startingFrame, finalFrame, frameRate, repetitions (optional), isReversed (optional)
	// REMINDER: DON'T FORGET TO REMOVE THE TRAILING COMMA, SINCE OTHERWISE AS WILL INSERT A NULL HANDLE AFTER THE LAST ACTUAL OBJECT ELEMENT
	
	const array<fioCut::Animation@> animationsTeleport = {
		fioCut::Animation(25, TELEPORT_X, TELEPORT_Y, TELEPORT_X, TELEPORT_Y,
				0, 12, 12, ANIM::AMMO, 6, 11, 0, 2, 1, true, 0, SPRITE::SINGLECOLOR, 64),
		fioCut::EmptyAnimation(10),
		fioCut::Animation(25, TELEPORT_X, TELEPORT_Y, TELEPORT_X, TELEPORT_Y,
				0, 12, 12, ANIM::AMMO, 6, 0, 11, 2, 1, false, 0, SPRITE::SINGLECOLOR, 64)
	};
	fioCut::createAnimationChain(animationsTeleport);
}

// Required for each level
bool onCheat(string &in cheat) {
	return fio::handleCheat(cheat, NEXT_LEVEL_FILENAME);
}

bool onDrawHealth(jjPLAYER@ play, jjCANVAS@ canvas) {
	fioCut::drawCutscene(canvas, centeredText);
	return true;
}

void onDrawLayer4(jjPLAYER@ play, jjCANVAS@ canvas) {
	fioCut::renderAnimations(canvas);
}

bool onDrawLives(jjPLAYER@ play, jjCANVAS@ canvas) {
	return true;
}

bool onDrawScore(jjPLAYER@ play, jjCANVAS@ canvas) {
	return true;
}

void onLevelBegin() {
	@character = fio::getCharacterWithMindStoneForPlayer(play);
	fioCut::initializeCutscene(@processTickEvents, cutsceneTexts);
}

void onLevelLoad() {
	initializeGlobals(array<Checkpoint@> = {});
	fioCut::clearAnimationChains();
	
	playerAnimSet = fio::getAnimSetForPlayer(jjLocalPlayers[0]);
	
	jjObjectPresets[OBJECT::GOLDCOIN].deactivates = false;
}


void onPlayer(jjPLAYER@ play) {
	if (jjGameTicks == 1) {
		play.noFire = true;
		play.cameraFreeze(CAMERA_INITIAL_X, CAMERA_INITIAL_Y, true, true);
	}
	
	fio::controlPressedKeys();
	runCutscene();
	
	if (isCoinRainActive) {
		if (jjGameTicks % 10 == 0) {
			summonCoinsFromTheSky();
		}
	}
}

void onPlayerInput(jjPLAYER@ play) {
	fioCut::controlPlayerInput(play);
	if (fioCut::isCutsceneSkipInitiatedAfterDelay(play)) {
		fioCut::setCutsceneSkipInitiated();
		fio::handleLevelCycle(NEXT_LEVEL_FILENAME, false, true);
	}
}

void processTickEvents(jjPLAYER@ play) {
	switch(uint(fioCut::getElapsedCutscene())) {
		case CUTSCENE_SECOND * 1:
			fioCut::startTextSliding();
			break;
		case CUTSCENE_SECOND * 14:
			fioCut::createEventCameraScroll(CAMERA_SCROLL_DURATION, CAMERA_INITIAL_X, CAMERA_INITIAL_Y,
					CAMERA_FINAL_X, CAMERA_FINAL_Y);
			break;
		case CUTSCENE_SECOND * 17:
			createTeleportAnimations();
			break;
		case CUTSCENE_SECOND * 17 + 20:
			fioCut::createEventFade(FADE_WHITE_DURATION_TOTAL, FADE_WHITE_DURATION_WHITEOUT, true, true, 64);
			break;
		case CUTSCENE_SECOND * 18:
			createRabbitAnimations();
			jjGenerateSettableTileArea(4, 50, 136, 2, 2);
			jjTileSet(4, 50, 136, 240);
			jjTileSet(4, 51, 136, 241);
			jjTileSet(4, 50, 137, 250);
			jjTileSet(4, 51, 137, 251);
			jjSamplePriority(SOUND::COMMON_TELPORT2);
			break;
		case CUTSCENE_SECOND * 36:
			isCoinRainActive = true;
			break;
		case CUTSCENE_SECOND * 40:
			isCoinRainActive = false;
			break;
		case CUTSCENE_SECOND * 71:
			fioCut::createEventFade(FADE_BLACK_DURATION_TOTAL, FADE_BLACK_DURATION_BLACKOUT, true, false);
			break;
		case CUTSCENE_SECOND * 73:
			fio::increaseCutscenesWatchedIfFastForwardWasNotUsed(fioCut::wasFastForwardUsed);
			fio::handleLevelCycle(NEXT_LEVEL_FILENAME, false, true);
			break;
	}
}

void runCutscene() {
	fioCut::run();
	
	if (!fioCut::isTickEventsProcessed()) {
		processTickEvents(play);
		fioCut::setTickEventsProcessed(true);
	}
}

void summonCoinsFromTheSky() {
	for (uint i = 46; i < 50; i++) {
		jjOBJ@ obj = jjObjects[jjAddObject(OBJECT::GOLDCOIN, TILE * i, TILE * 125)];
		// MAKE SURE TO SET THE STATE TO FLOATFALL
		obj.state = STATE::FLOATFALL;
	}
}