Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Find It Out (Single Player) | Superjazz | Single player | 9.1 |
const bool MLLESetupSuccessful = MLLE::Setup(); ///@MLLE-Generated
#include "MLLE-Include-1.6.asc" ///@MLLE-Generated
#pragma require "Fio3_b-MLLE-Data-1.j2l" ///@MLLE-Generated
#pragma require "wbrg.j2t" ///@MLLE-Generated
#pragma require "Oasis.j2t" ///@MLLE-Generated
#pragma require "Fio3_b.j2l" ///@MLLE-Generated
#include "Fio_common.asc"
#include "Fio_cutscene.asc"
#include "Fio_drawing.asc"
#include "Fio_entities.asc"
#include "Fio_globals.asc"
enum Cutscene { CUTSCENE_NONE, CUTSCENE_INTRO, CUTSCENE_OUTRO };
class Door {
Node@ node;
int warpID;
Door(Node@ node, int warpID) {
@this.node = node;
this.warpID = warpID;
}
}
class MoreVisibleRapier : RemovableEnemy {
MoreVisibleRapier(jjOBJ@ preset) {
super(preset);
}
void onDraw(jjOBJ@ obj) override {
if (obj.justHit > 0) {
jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::SINGLECOLOR, 15);
} else {
jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::TINTED, 15);
}
}
}
const float DURATION_FADE_TOTAL = CUTSCENE_SECOND * 4;
const float DURATION_FADE_BLACKOUT = CUTSCENE_SECOND * 2;
const float RABBIT_HURT_DURATION = CUTSCENE_SECOND * 2 + 10;
const float RABBIT_RUN_1_END_X = TILE * 486;
const float RABBIT_RUN_1_END_Y = TILE * 75;
const float RABBIT_RUN_1_START_X = TILE * 449;
const float RABBIT_RUN_1_START_Y = TILE * 75;
const float RABBIT_RUN_1_DURATION = CUTSCENE_SECOND * 6;
const float RABBIT_RUN_2_END_X = TILE * 490.5;
const float RABBIT_RUN_2_END_Y = TILE * 77;
const float RABBIT_RUN_2_DURATION = CUTSCENE_SECOND;
const float RABBIT_RUN_3_END_X = TILE * 492.5;
const float RABBIT_RUN_3_END_Y = TILE * 79;
const float RABBIT_RUN_3_DURATION = CUTSCENE_SECOND;
const float RABBIT_RUN_4_END_X = TILE * 496;
const float RABBIT_RUN_4_END_Y = TILE * 81;
const float RABBIT_RUN_4_DURATION = CUTSCENE_SECOND;
const float RABBIT_RUN_5_END_X = TILE * 508;
const float RABBIT_RUN_5_END_Y = TILE * 81;
const float RABBIT_RUN_5_DURATION = CUTSCENE_SECOND * 2;
const float RABBIT_RUN_6_END_X = TILE * 512;
const float RABBIT_RUN_6_END_Y = TILE * 79;
const float RABBIT_RUN_6_DURATION = CUTSCENE_SECOND;
const float RABBIT_RUN_7_END_X = TILE * 525;
const float RABBIT_RUN_7_END_Y = TILE * 79;
const float RABBIT_RUN_7_DURATION = CUTSCENE_SECOND * 3;
const float RABBIT_RUN_8_END_X = TILE * 540;
const float RABBIT_RUN_8_END_Y = TILE * 79;
const float RABBIT_RUN_8_DURATION = CUTSCENE_SECOND * 4;
const float RABBIT_RUN_9_START_X = TILE * 2;
const float RABBIT_RUN_9_START_Y = TILE * 79.25;
const float RABBIT_RUN_9_END_X = TILE * 15;
const float RABBIT_RUN_9_END_Y = TILE * 79.25;
const float RABBIT_RUN_9_DURATION = CUTSCENE_SECOND * 4;
const float RABBIT_STILL_DURATION = CUTSCENE_SECOND * 6 - 10;
const float OUTRO_X = TILE * 393;
const float OUTRO_Y = TILE * 34 +16;
const string NEXT_LEVEL_FILENAME = "Fio3_y.j2l";
const array<ArmoryItem@> ARMORY_ITEMS = {
ArmoryItem(0, "||||Bouncer Power up@+ 20 ammo", 20, 52, ANIM::PICKUPS, 61, 0, @fio::sellArmoryItemBouncerPU),
ArmoryItem(1, "||||Toaster Power up@+20 ammo", 15, 48, ANIM::PICKUPS, 65, 0, @fio::sellArmoryItemToasterPU),
ArmoryItem(2, "||||Pepperspray Power up@+20 ammo", 25, 48, ANIM::PICKUPS, 66, 0, @fio::sellArmoryItemPeppersprayPU),
ArmoryItem(3, "||||+15 Seeker ammo", 25, 48, ANIM::AMMO, 37, 1, @fio::sellArmoryItemSeekerAmmo),
ArmoryItem(4, "", 15, 44, ANIM::PICKUPS, 72, 5, @fio::sellArmoryItemInvincibility, @fio::canBuyInvincibility), // Text updated later when currentGameSession has been loaded
ArmoryItem(5, "", 10, 56, ANIM::PICKUPS, 21, 0, @fio::sellArmoryItemPocketCarrot, @fio::canBuyPocketCarrot) // Text updated later when currentGameSession has been loaded
};
const array<Door@> DOORS = {
Door(Node(TILE * 176, TILE * 76.5), 0),
Door(Node(TILE * 22, TILE * 15), 1),
Door(Node(TILE * 156, TILE * 19), 2),
Door(Node(TILE * 241, TILE * 73.5), 3),
Door(Node(TILE * 267, TILE * 74.5), 4),
Door(Node(TILE * 177, TILE * 20), 5),
Door(Node(TILE * 279, TILE * 74.5), 6),
Door(Node(TILE * 191, TILE * 20), 7),
Door(Node(TILE * 361, TILE * 5.5), 8),
Door(Node(TILE * 316, TILE * 5), 9),
Door(Node(TILE * 369, TILE * 5.5), 10),
Door(Node(TILE * 328, TILE * 5), 11),
Door(Node(TILE * 410, TILE * 30.5), 12),
Door(Node(TILE * 195, TILE * 34), 13),
Door(Node(TILE * 410, TILE * 39), 14),
Door(Node(TILE * 195, TILE * 42), 15)
};
uint8 activeCutscene = uint8(CUTSCENE_NONE);
bool canFireFirstTnt = false;
bool canFireSecondTnt = false;
bool isHoldingKeyUp = false;
ANIM::Set playerAnimSet;
array<Checkpoint@> fio3bCheckpoints = {
Checkpoint(0, TILE * 15, TILE * 79),
Checkpoint(1, TILE * 21, TILE * 15),
Checkpoint(2, TILE * 241, TILE * 73),
Checkpoint(3, TILE * 341, TILE * 41)
};
array<string> questTexts = {
fio::getQuestText(10, 15, 10000),
fio::getQuestTextComplete(10000),
fio::getQuestTextPerfect(5000)
};
array<string> texts = {
"|There seems to be a passage behind the last door to the right. With any luck I could get to the other side of the city.",
"|Damned demons or whoever have put spike bolls as traps for bypassers. I guess my weapons are no use against them either. I've got to be careful now...",
"|I guess the statue lies on the higher level. I need something to get up there. Maybe there is a switch.",
"Temple of Victoria@For the mighty!",
"|I'm gonna need some heavy tools to get through this.",
"|I fear these explosives are the only ones to be found nearby. I have to rely on that chance and use them wisely!", // 5
"|Let's place an explosive here. One should be enough...",
"|Great! That must be the statue of curses! Now just how can I get close enough to blast it off?",
"|Alright. Here goes my last boom.",
"|The spirits in this land are more shiny than I expected. At least that makes them easier to spot from far."
};
array<string> cutsceneTextsIntro = {
"||||After around twelve hours of tiresome walking through the dry and hot desert...",
"||||...you finally reach the outskirts of the city of Rine.",
"||||Weary from the travel, you decide to hide in to the bushes nearby to talk to Nicholas peacefully.",
"||||You touch your mindstone and hear the voice of Nicholas in your head once again...",
"|||So, you've reached the ancient city of Rine I told you about. Perfect!",
"|||The statue of Curses is not going down easily. I hope you have equipped yourself well in order to do that.",
"|||...Or at least the city should be big enough to find the right tools for it.",
"|||I wish you good luck! You're going to need it.",
"|I won't let you down.",
"||||You no longer hear Nicholas, and decide to move on."
};
array<string> cutsceneTextsOutro = {
"|Now I should be close enough. Let's get this done!",
"|Alright. Here goes my last boom. Three...two...one...",
"|AAARGGH! WHAT IS HAPPENING NOW?"
};
// Call this before setting isHoldingKeyUp to true in the calling method (onPlayerInput)
void controlDoorInput(jjPLAYER@ play) {
for (uint i = 0; i < DOORS.length(); ++i) {
Door@ door = DOORS[i];
if (!isHoldingKeyUp
&& play.keyUp
&& abs((play.xPos / TILE) - (door.node.x / TILE)) <= 1.f
&& abs((play.yPos / TILE) - (door.node.y / TILE)) <= 1.f) {
play.warpToID(door.warpID, true);
return; // To ensure no extra warps may happen when the player lands on the opposing door side
}
}
}
void drawDoorArrows(jjCANVAS@ canvas) {
for (uint i = 0; i < DOORS.length(); ++i) {
Door@ door = DOORS[i];
fioDraw::drawArrowUp(canvas, int(door.node.x), int(door.node.y) + int(jjSin(jjGameTicks % 128 * 8) * 8));
}
}
int getPointRewardByDifficulty() {
if (jjDifficulty >= 3) return 30000;
if (jjDifficulty == 2) return 10000;
if (jjDifficulty == 1) return 1000;
return 500;
}
void initializeIntro() {
fioCut::initializeCutscene(@processTickEvents, cutsceneTextsIntro);
fioCut::createEventFade(DURATION_FADE_TOTAL, DURATION_FADE_BLACKOUT, false, true);
fioCut::setTickEventsProcessed(true);
play.noFire = true;
play.cameraFreeze(RABBIT_RUN_1_START_X, RABBIT_RUN_1_START_Y, true, true);
activeCutscene = CUTSCENE_INTRO;
}
void initializeIntroAnimationChain() {
// Duration, xOrigin, yOrigin, xDestination, yDestination, angle, scaleX, scaleY, animSet, animationId,
// startingFrame, finalFrame, frameRate, repetitions (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@> animationsIntroRabbit = {
fioCut::Animation(RABBIT_RUN_1_DURATION,
RABBIT_RUN_1_START_X, RABBIT_RUN_1_START_Y,
RABBIT_RUN_1_END_X, RABBIT_RUN_1_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT),
fioCut::Animation(RABBIT_RUN_2_DURATION,
RABBIT_RUN_1_END_X, RABBIT_RUN_1_END_Y,
RABBIT_RUN_2_END_X, RABBIT_RUN_2_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT),
fioCut::Animation(RABBIT_RUN_3_DURATION,
RABBIT_RUN_2_END_X, RABBIT_RUN_2_END_Y,
RABBIT_RUN_3_END_X, RABBIT_RUN_3_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT),
fioCut::Animation(RABBIT_RUN_4_DURATION,
RABBIT_RUN_3_END_X, RABBIT_RUN_3_END_Y,
RABBIT_RUN_4_END_X, RABBIT_RUN_4_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT),
fioCut::Animation(RABBIT_RUN_5_DURATION,
RABBIT_RUN_4_END_X, RABBIT_RUN_4_END_Y,
RABBIT_RUN_5_END_X, RABBIT_RUN_5_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT),
fioCut::Animation(RABBIT_RUN_6_DURATION,
RABBIT_RUN_5_END_X, RABBIT_RUN_5_END_Y,
RABBIT_RUN_6_END_X, RABBIT_RUN_6_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT),
fioCut::Animation(RABBIT_RUN_7_DURATION,
RABBIT_RUN_6_END_X, RABBIT_RUN_6_END_Y,
RABBIT_RUN_7_END_X, RABBIT_RUN_7_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT)
};
fioCut::createAnimationChain(animationsIntroRabbit);
}
void initializeOutro() {
isPlayerUnableToMove = true;
fioCut::initializeCutscene(@processTickEvents, cutsceneTextsOutro);
fioCut::setTickEventsProcessed(true);
fioCut::startTextSliding();
play.noFire = true;
play.cameraFreeze(OUTRO_X, OUTRO_Y, true, true);
activeCutscene = CUTSCENE_OUTRO;
}
void initializeOutroAnimationChain() {
// Duration, xOrigin, yOrigin, xDestination, yDestination, angle, scaleX, scaleY, animSet, animationId,
// startingFrame, finalFrame, frameRate, repetitions (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@> animationsOutroRabbit = {
fioCut::Animation(RABBIT_STILL_DURATION,
OUTRO_X, OUTRO_Y,
OUTRO_X, OUTRO_Y,
0, 1, 1, playerAnimSet, RABBIT::IDLE2, 0, 0, 1, 0, false, -1),
fioCut::Animation(RABBIT_HURT_DURATION,
OUTRO_X, OUTRO_Y,
OUTRO_X, OUTRO_Y,
0, 1, 1, playerAnimSet, RABBIT::HURT, 0, 0, 2, 1, false, -1)
};
fioCut::createAnimationChain(animationsOutroRabbit);
}
// Required for each level
bool onCheat(string &in cheat) {
return fio::handleCheat(cheat, NEXT_LEVEL_FILENAME);
}
// Required for each level
bool onDrawHealth(jjPLAYER@ play, jjCANVAS@ canvas) {
fioDraw::animateHud();
fioDraw::drawHud(play, canvas, activeCutscene != CUTSCENE_NONE);
if (activeCutscene != CUTSCENE_NONE) {
fioCut::drawCutscene(canvas, centeredText);
}
if (isPlayerInArmory) {
fioDraw::drawArmoryInterface(canvas, 38, true);
}
return activeCutscene != CUTSCENE_NONE;
}
void onDrawLayer4(jjPLAYER@ play, jjCANVAS@ canvas) {
if (activeCutscene != CUTSCENE_NONE) {
fioCut::renderAnimations(canvas);
}
fio::renderCommon(play, canvas);
fioDraw::drawArmoryAtPos(canvas, TILE * 414.5, TILE * 39.75, 35); // Offset with +0.5 xTiles and +0.75 yTiles + color 33 for this level
drawDoorArrows(canvas);
}
bool onDrawLives(jjPLAYER@ play, jjCANVAS@ canvas) {
return true;
}
bool onDrawScore(jjPLAYER@ play, jjCANVAS@ canvas) {
return activeCutscene != CUTSCENE_NONE;
}
void onFunction0() {
if (!checkpoints[0].isReached()) {
checkpoints[0].setReached();
fioDraw::doShowOptionalQuest(0);
}
play.lighting = LIGHTING_TWILIGHT;
}
void onFunction1() {
fioDraw::doShowText(0);
}
void onFunction2() {
fioDraw::doShowText(1);
}
// Replaced obsolete function
void onFunction3() {
fioDraw::doShowText(9);
}
void onFunction4() {
if (!checkpoints[2].isReached()) {
checkpoints[2].setReached();
}
play.lighting = LIGHTING_TWILIGHT;
}
void onFunction5() {
if (!jjTriggers[3]) {
fioDraw::doShowText(2);
}
}
void onFunction6() {
fioDraw::doShowText(3);
}
void onFunction7() {
if (play.ammo[7] >= 3) {
play.currWeapon = WEAPON::TNT;
canFireFirstTnt = true;
fioDraw::doShowText(6);
} else {
fioDraw::doShowText(4);
}
}
void onFunction8() {
if (play.currWeapon == WEAPON::TNT) {
play.currWeapon = WEAPON::BLASTER;
}
canFireFirstTnt = false;
}
void onFunction9() {
fioDraw::doShowText(5);
}
void onFunction10() {
if (!checkpoints[3].isReached()) {
checkpoints[3].setReached();
}
if (play.currWeapon == WEAPON::TNT) {
play.currWeapon = WEAPON::BLASTER;
}
play.lighting = LIGHTING_TWILIGHT;
// Just in case
canFireSecondTnt = false;
}
void onFunction11() {
fioDraw::doShowText(7);
}
void onFunction12() {
play.ammo[7] = 0;
fio::rewardPoints(getPointRewardByDifficulty());
initializeOutro();
}
void onFunction13() {
if (play.ammo[7] >= 2) {
play.currWeapon = WEAPON::TNT;
canFireSecondTnt = true;
fioDraw::doShowText(6);
} else {
fioDraw::doShowText(4);
}
}
void onFunction14() {
if (play.currWeapon == WEAPON::TNT) {
play.currWeapon = WEAPON::BLASTER;
}
canFireSecondTnt = false;
}
void onFunction15(bool show) {
if (show) {
play.noFire = true;
isPlayerInArmory = true;
} else {
play.noFire = false;
isPlayerInArmory = false;
}
}
void onFunction16() {
if (!checkpoints[1].isReached()) {
checkpoints[1].setReached();
}
play.lighting = LIGHTING_DARK;
}
void onLevelBegin() {
initializeIntro();
}
// Required for each level
void onLevelLoad() {
initializeGlobals(fio3bCheckpoints, 10, 10000, 5000);
fioDraw::initializeDrawing(texts, questTexts, true);
playerAnimSet = fio::getAnimSetForPlayer(jjLocalPlayers[0]);
// Re-assignment via static declaration
armoryItems = ARMORY_ITEMS;
// Global indice
armoryItemIndexInvincibility = 4;
armoryItemIndexPocketCarrot = 5;
armoryItems[armoryItemIndexInvincibility].text = fio::getInvincibilityItemText();
armoryItems[armoryItemIndexPocketCarrot].text = fio::getPocketCarrotItemText();
mindstoneCommunicationTileIds = array<uint16>(5);
mindstoneCommunicationTileIds[0] = 1953;
mindstoneCommunicationTileIds[1] = 1962;
mindstoneCommunicationTileIds[2] = 1963;
mindstoneCommunicationTileIds[3] = 1972;
mindstoneCommunicationTileIds[4] = 1973;
MoreVisibleRapier(jjObjectPresets[OBJECT::RAPIER]); // Override the default RemovableEnemy from Fio_entities.asc
}
// Required for each level
void onLevelReload() {
reloadGlobals();
fioDraw::initializeDrawing(texts, questTexts, true);
if (fio::handleLevelReload()) {
activeCutscene = CUTSCENE_NONE;
} else {
initializeIntro();
}
if (play.ammo[7] == 2 || play.ammo[7] == 1) {
// Spaghetti code here we come!
jjTileSet(4, 396, 74, 0);
jjTileSet(4, 396, 75, 0);
jjTileSet(4, 396, 76, 0);
jjTileSet(4, 396, 77, 0);
jjTileSet(4, 396, 78, 0);
jjTileSet(4, 396, 79, 0);
jjTileSet(4, 396, 80, 0);
}
if (play.ammo[7] == 1) {
jjTileSet(4, 338, 31, 0);
jjTileSet(4, 338, 32, 0);
jjTileSet(4, 338, 33, 0);
jjTileSet(4, 338, 34, 0);
jjTileSet(4, 338, 35, 0);
jjTileSet(4, 338, 36, 0);
jjTileSet(4, 338, 37, 0);
jjTileSet(4, 338, 38, 0);
jjTileSet(4, 338, 39, 0);
jjTileSet(4, 338, 40, 0);
jjTileSet(4, 338, 41, 0);
jjTileSet(4, 339, 31, 0);
jjTileSet(4, 339, 32, 0);
jjTileSet(4, 339, 33, 0);
jjTileSet(4, 339, 34, 0);
jjTileSet(4, 339, 35, 0);
jjTileSet(4, 339, 36, 0);
jjTileSet(4, 339, 37, 0);
jjTileSet(4, 339, 38, 0);
jjTileSet(4, 339, 39, 0);
jjTileSet(4, 339, 40, 0);
jjTileSet(4, 339, 41, 0);
}
}
// Required for each level
void onMain() {
fio::controlPressedKeys();
fioDraw::controlHud();
}
// Required for each level
void onPlayer(jjPLAYER@ play) {
fio::handlePlayer(play);
fio::controlQuest();
if (activeCutscene != CUTSCENE_NONE) {
fioCut::run();
if (!fioCut::isTickEventsProcessed()) {
processTickEvents(play);
fioCut::setTickEventsProcessed(true);
}
}
if (play.ammo[7] == 2) {
canFireFirstTnt = false;
jjEnabledASFunctions[7] = false;
} else if (play.ammo[7] == 1) {
canFireSecondTnt = false;
jjEnabledASFunctions[13] = false;
}
if (play.currWeapon == WEAPON::TNT && (canFireFirstTnt || canFireSecondTnt)) {
play.noFire = false;
} else if (play.currWeapon == WEAPON::TNT) {
play.noFire = true;
} else {
play.noFire = false;
}
}
void onPlayerInput(jjPLAYER@ play) {
fio::controlArmoryInput(play);
fio::controlPlayerInput(play, activeCutscene != CUTSCENE_NONE);
if (activeCutscene != CUTSCENE_NONE) {
fioCut::controlPlayerInput(play);
if (fioCut::isCutsceneSkipInitiatedAfterDelay(play)) {
fioCut::setCutsceneSkipInitiated();
if (activeCutscene == CUTSCENE_INTRO) {
fioCut::endCutscene(RABBIT_RUN_9_END_X, RABBIT_RUN_9_END_Y);
play.lighting = LIGHTING_TWILIGHT;
activeCutscene = CUTSCENE_NONE;
fioUtils::releasePlayer();
} else if (activeCutscene == CUTSCENE_OUTRO) {
fio::handleLevelCycle(NEXT_LEVEL_FILENAME, true, true);
// Don't set activeCutscene to CUTSCENE_NONE so that the cutscene engine can process the level cycle event properly
}
}
}
controlDoorInput(play);
// To ensure no further warps may happen when the player lands on the opposing door side
// This should be only a level-specific feature so no need to move it to the common library
if (play.keyUp) {
isHoldingKeyUp = true;
} else {
isHoldingKeyUp = false;
}
}
// Required for each level
void onRoast(jjPLAYER@ victim, jjPLAYER@ killer) {
fio::saveTriggerStates();
asPlay.savePlayerProperties(play);
}
void processCutsceneIntro(jjPLAYER@ play) {
switch(uint(fioCut::getElapsedCutscene())) {
case CUTSCENE_SECOND * 1:
fioCut::startTextSliding();
play.lighting = LIGHTING_TWILIGHT;
break;
case CUTSCENE_SECOND * 2:
initializeIntroAnimationChain();
fioCut::createEventCameraScroll(RABBIT_RUN_1_DURATION, RABBIT_RUN_1_START_X, RABBIT_RUN_1_START_Y,
RABBIT_RUN_1_END_X, RABBIT_RUN_1_END_Y);
break;
case CUTSCENE_SECOND * 8:
fioCut::createEventCameraScroll(RABBIT_RUN_2_DURATION, RABBIT_RUN_1_END_X, RABBIT_RUN_1_END_Y,
RABBIT_RUN_2_END_X, RABBIT_RUN_2_END_Y);
break;
case CUTSCENE_SECOND * 9:
fioCut::createEventCameraScroll(RABBIT_RUN_3_DURATION, RABBIT_RUN_2_END_X, RABBIT_RUN_2_END_Y,
RABBIT_RUN_3_END_X, RABBIT_RUN_3_END_Y);
break;
case CUTSCENE_SECOND * 10:
fioCut::createEventCameraScroll(RABBIT_RUN_4_DURATION, RABBIT_RUN_3_END_X, RABBIT_RUN_3_END_Y,
RABBIT_RUN_4_END_X, RABBIT_RUN_4_END_Y);
break;
case CUTSCENE_SECOND * 11:
fioCut::createEventCameraScroll(RABBIT_RUN_5_DURATION, RABBIT_RUN_4_END_X, RABBIT_RUN_4_END_Y,
RABBIT_RUN_5_END_X, RABBIT_RUN_5_END_Y);
break;
case CUTSCENE_SECOND * 13:
fioCut::createEventCameraScroll(RABBIT_RUN_6_DURATION, RABBIT_RUN_5_END_X, RABBIT_RUN_5_END_Y,
RABBIT_RUN_6_END_X, RABBIT_RUN_6_END_Y);
break;
case CUTSCENE_SECOND * 14:
fioCut::createEventCameraScroll(RABBIT_RUN_7_DURATION, RABBIT_RUN_6_END_X, RABBIT_RUN_6_END_Y,
RABBIT_RUN_7_END_X, RABBIT_RUN_7_END_Y);
break;
case CUTSCENE_SECOND * 22:
fioCut::isMindstoneCommunicationRendered = true;
break;
case CUTSCENE_SECOND * 51:
fioCut::isMindstoneCommunicationRendered = false;
break;
case CUTSCENE_SECOND * 52:
{
const array<fioCut::Animation@> furtherAnimationsRabbit = {
fioCut::Animation(RABBIT_RUN_8_DURATION,
RABBIT_RUN_7_END_X, RABBIT_RUN_7_END_Y,
RABBIT_RUN_8_END_X, RABBIT_RUN_8_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT),
fioCut::Animation(RABBIT_RUN_9_DURATION,
RABBIT_RUN_9_START_X, RABBIT_RUN_9_START_Y,
RABBIT_RUN_9_END_X, RABBIT_RUN_9_END_Y,
0, 1, 1, playerAnimSet, RABBIT::RUN1, 0, 7, FRAME_RATE_INTRO_RABBIT)
};
fioCut::createAnimationChain(furtherAnimationsRabbit);
fioCut::createEventCameraScroll(RABBIT_RUN_8_DURATION, RABBIT_RUN_7_END_X, RABBIT_RUN_7_END_Y,
RABBIT_RUN_8_END_X, RABBIT_RUN_8_END_Y);
}
break;
case CUTSCENE_SECOND * 54:
fioCut::createEventFade(DURATION_FADE_TOTAL, DURATION_FADE_BLACKOUT, true, true);
break;
case CUTSCENE_SECOND * 56:
isPlayerHiddenAndUnableToMove = true;
play.xPos = TILE * 15;
play.yPos = TILE * 82;
fioCut::createEventCameraScroll(RABBIT_RUN_9_DURATION, RABBIT_RUN_9_START_X, RABBIT_RUN_9_START_Y,
RABBIT_RUN_9_END_X, RABBIT_RUN_9_END_Y);
break;
case CUTSCENE_SECOND * 60:
play.xPos = TILE * 15;
play.yPos = TILE * 79;
fioUtils::releasePlayer();
fio::increaseCutscenesWatchedIfFastForwardWasNotUsed(fioCut::wasFastForwardUsed);
fioCut::endCutscene(RABBIT_RUN_9_END_X, RABBIT_RUN_9_END_Y);
activeCutscene = CUTSCENE_NONE;
// play.direction = 1 doesn't seem to do anything, so use play.keyRight once instead
play.keyRight = true;
break;
}
}
void processCutsceneOutro(jjPLAYER@ play) {
switch(uint(fioCut::getElapsedCutscene())) {
case CUTSCENE_SECOND * 2:
fioCut::createEventFade(DURATION_FADE_TOTAL, DURATION_FADE_BLACKOUT, true, true);
break;
case CUTSCENE_SECOND * 4:
isPlayerUnableToMove = false;
isPlayerHiddenAndUnableToMove = true;
initializeOutroAnimationChain();
break;
case CUTSCENE_SECOND * 9:
jjAddObject(OBJECT::TNT, TILE * 388, TILE * 31);
break;
case CUTSCENE_SECOND * 12:
play.xPos = OUTRO_X;
play.yPos = OUTRO_Y;
play.keyLeft = true;
fioUtils::releasePlayer();
fio::increaseCutscenesWatchedIfFastForwardWasNotUsed(fioCut::wasFastForwardUsed);
fio::handleLevelCycle(NEXT_LEVEL_FILENAME, true);
break;
}
}
void processTickEvents(jjPLAYER@ play) {
switch (activeCutscene) {
case CUTSCENE_INTRO:
processCutsceneIntro(play);
break;
case CUTSCENE_OUTRO:
processCutsceneOutro(play);
break;
}
}
Jazz2Online © 1999-INFINITY (Site Credits). We have a Privacy Policy. Jazz Jackrabbit, Jazz Jackrabbit 2, Jazz Jackrabbit Advance and all related trademarks and media are ™ and © Epic Games. Lori Jackrabbit is © Dean Dodrill. J2O development powered by Loops of Fury and Chemical Beats.
Eat your lima beans, Johnny.