Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Thunder Cliffs | Superjazz | Capture the flag | N/A |
const bool MLLESetupSuccessful = MLLE::Setup(); ///@MLLE-Generated
#include "MLLE-Include-1.6.asc" ///@MLLE-Generated
#pragma require "xlmthunder-MLLE-Data-2.j2l" ///@MLLE-Generated
#pragma require "xlmthunder-MLLE-Data-1.j2l" ///@MLLE-Generated
#pragma require "Carrot1.j2t" ///@MLLE-Generated
#pragma require "ICJungD.j2t" ///@MLLE-Generated
#pragma require "ICJungS.j2t" ///@MLLE-Generated
#pragma require "Aztec2.j2t" ///@MLLE-Generated
#pragma require "xlmthunder.j2l" ///@MLLE-Generated
#pragma require "lightning2.wav"
class BackgroundLightning {
bool isVisible;
int xPixelOnLayer;
BackgroundLightning(int xPixelOnLayer) {
this.xPixelOnLayer = xPixelOnLayer;
this.isVisible = false;
}
}
void CantBeBuried(jjOBJ@ obj) {
obj.behave(BEHAVIOR::PICKUP);
if (jjMaskedPixel(int(obj.xPos), int(obj.yPos) + 8)) {
obj.state = STATE::FLOAT;
}
}
const float BLUE_BASE_X = 30 << TILE_SHIFT;
const float BLUE_BASE_Y = 33 << TILE_SHIFT;
const float RED_BASE_X = 130 << TILE_SHIFT;
const float RED_BASE_Y = 33 << TILE_SHIFT;
const int BACKGROUND_LIGHTNING_INTERVAL = 490;
const int BACKGROUND_LIGHTNING_OFFSET_Y = -300;
const int BACKGROUND_THUNDER_SAMPLE_DELAY = 100;
const int RED_SIDE_X_ORIGIN = 80 << 5;
const int TILE_SHIFT = 5;
const uint BASE_LIGHTNING_SAMPLE_COOLDOWN = 70;
const uint BLUE_BASE_Y_TILE = 33;
const uint RED_BASE_Y_TILE = 33;
const array<BackgroundLightning@> BACKGROUND_LIGHTNINGS = {
BackgroundLightning(29 << TILE_SHIFT), // Layer 6 Lightning begin
BackgroundLightning(24 << TILE_SHIFT),
BackgroundLightning(9 << TILE_SHIFT),
BackgroundLightning(4 << TILE_SHIFT), // Layer 6 lightnings end
BackgroundLightning(0 << TILE_SHIFT), // Layer 7 Lightning begin
BackgroundLightning(17 << TILE_SHIFT),
BackgroundLightning(33 << TILE_SHIFT) // Layer 7 lightnings end
};
const array<uint16> LIGHTNING_FRAMES_ONE = { 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467 };
const array<uint16> LIGHTNING_FRAMES_TWO = { 3470, 3471, 3472, 3473, 3474, 3475, 3476, 3477 };
const array<uint16> LIGHTNING_FRAMES_THREE = { 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3487 };
bool isLightningVisibleBlue = false;
bool isLightningVisibleRed = false;
bool isThunderSoundDelayed = false;
int previousTeamScoreBlue = 0;
int previousTeamScoreRed = 0;
uint baseLightningSampleCooldown = 0;
uint lightningFrameCounterBlue = 0;
uint lightningFrameCounterGeneral = 0;
uint lightningFrameCounterRed = 0;
uint thunderSampleDelayCounter = 0;
void disableAllBackgroundLightnings() {
for (uint i = 0; i < BACKGROUND_LIGHTNINGS.length(); ++i) {
BACKGROUND_LIGHTNINGS[i].isVisible = false;
}
}
void drawLightningAtXPixel(jjCANVAS@ canvas, int xPixel) {
for (uint i = 0; i < 30; ++i) { // 30 tiles should be enough...
if (i % 3 == 2) {
canvas.drawTile(xPixel, int(i << TILE_SHIFT) + BACKGROUND_LIGHTNING_OFFSET_Y, LIGHTNING_FRAMES_THREE[lightningFrameCounterGeneral]);
} else if (i % 3 == 1) {
canvas.drawTile(xPixel, int(i << TILE_SHIFT) + BACKGROUND_LIGHTNING_OFFSET_Y, LIGHTNING_FRAMES_TWO[lightningFrameCounterGeneral]);
} else {
canvas.drawTile(xPixel, int(i << TILE_SHIFT) + BACKGROUND_LIGHTNING_OFFSET_Y, LIGHTNING_FRAMES_ONE[lightningFrameCounterGeneral]);
}
}
}
bool isAnyBackgroundLightningVisible() {
for (uint i = 0; i < BACKGROUND_LIGHTNINGS.length(); ++i) {
if (BACKGROUND_LIGHTNINGS[i].isVisible) {
return true;
}
}
return false;
}
void onDrawLayer4(jjPLAYER@ play, jjCANVAS@ canvas) {
if (isLightningVisibleBlue) {
for (uint i = 0; i < BLUE_BASE_Y_TILE; ++i) {
if (i % 3 == 2) {
canvas.drawTile(BLUE_BASE_X, i << TILE_SHIFT, LIGHTNING_FRAMES_THREE[lightningFrameCounterBlue]);
} else if (i % 3 == 1) {
canvas.drawTile(BLUE_BASE_X, i << TILE_SHIFT, LIGHTNING_FRAMES_TWO[lightningFrameCounterBlue]);
} else {
canvas.drawTile(BLUE_BASE_X, i << TILE_SHIFT, LIGHTNING_FRAMES_ONE[lightningFrameCounterBlue]);
}
}
}
if (isLightningVisibleRed) {
for (uint i = 0; i < RED_BASE_Y_TILE; ++i) {
if (i % 3 == 2) {
canvas.drawTile(RED_BASE_X, i << TILE_SHIFT, LIGHTNING_FRAMES_THREE[lightningFrameCounterRed]);
} else if (i % 3 == 1) {
canvas.drawTile(RED_BASE_X, i << TILE_SHIFT, LIGHTNING_FRAMES_TWO[lightningFrameCounterRed]);
} else {
canvas.drawTile(RED_BASE_X, i << TILE_SHIFT, LIGHTNING_FRAMES_ONE[lightningFrameCounterRed]);
}
}
}
}
// NOTE: The layer needs to have at least non-0 tile placed or else these hooks won't be called at all.
// Setting jjLayers[6].hasTiles = true; artifically does not work either, so just place a transparent tile somewhere on the layer in MLLE...
void onDrawLayer6(jjPLAYER@ play, jjCANVAS@ canvas) {
for (uint i = 0; i < 4; ++i) {
BackgroundLightning@ lightning = BACKGROUND_LIGHTNINGS[i];
if (lightning.isVisible) {
drawLightningAtXPixel(canvas, lightning.xPixelOnLayer);
}
}
}
void onDrawLayer7(jjPLAYER@ play, jjCANVAS@ canvas) {
for (uint i = 4; i < BACKGROUND_LIGHTNINGS.length(); ++i) {
BackgroundLightning@ lightning = BACKGROUND_LIGHTNINGS[i];
if (lightning.isVisible) {
drawLightningAtXPixel(canvas, lightning.xPixelOnLayer);
}
}
}
void onLevelBegin() {
jjAnimSets[ANIM::BILSBOSS].load();
jjSampleLoad(SOUND::BILSBOSS_SCARY3, "lightning2.wav");
array<uint8> bridgeRedColorMapping(256, 0);
bridgeRedColorMapping[15] = 48;
bridgeRedColorMapping[32] = 49;
bridgeRedColorMapping[33] = 50;
bridgeRedColorMapping[34] = 26;
bridgeRedColorMapping[35] = 27;
bridgeRedColorMapping[36] = 28;
bridgeRedColorMapping[37] = 29;
bridgeRedColorMapping[38] = 30;
bridgeRedColorMapping[39] = 31;
jjANIMSET@ bridgeAnimSet = jjAnimSets[ANIM::BRIDGE];
jjANIMFRAME@ diamondBridgeFrame = jjAnimFrames[jjAnimations[bridgeAnimSet.firstAnim + 5].firstFrame];
jjANIMFRAME@ sciFiBridgeFrame = jjAnimFrames[jjAnimations[bridgeAnimSet.firstAnim + 6].firstFrame];
jjPIXELMAP diamondBridgeSprite(diamondBridgeFrame);
diamondBridgeSprite.recolor(bridgeRedColorMapping);
diamondBridgeSprite.save(sciFiBridgeFrame); // Replace Sci-Fi bridge sprites with the re-colored Diamond sprites
jjAlert("NOTE: Powered up Electro-blaster (Gun9) always does |2 |||||||damage in this level!");
}
void onLevelLoad() {
jjUseLayer8Speeds = true;
jjObjectPresets[OBJECT::CARROT].behavior = CantBeBuried;
jjObjectPresets[OBJECT::FULLENERGY].behavior = CantBeBuried;
// For buffing powered up Electro bullets to do 2 dmg as with /strongpowerups on. No idea why it works, but thx PJ! xP
jjObjectPresets[OBJECT::ELECTROBULLETPU].eventID = OBJECT::ELECTROBULLET;
}
void onMain() {
array<jjLAYER@> layers = jjLayerOrderGet();
layers[5].xOffset += 6.20f;
processBackgroundLightningEffects();
processBaseLightningEffects();
}
void playDistantThunderSample() {
jjSamplePriority(SOUND::BILSBOSS_SCARY3);
}
// JATKA TÄSTÄ...GJ! Sait salamat renderöityä sopivasti taustalayereiden väliin ja sadettakin hieman luonnosteltua taustalle...
// Katso haluatko vielä muokata joitakin tausta-elementtejä hieman, kuten esim. vaihtaa etummaiset puut yms johonkin muuhun jne...
// Muuten alkaakin tausta näyttämään melko hyvältä, jotta voi aloittaa itse layoutia...
void playLightningSampleAt(float centerX, float centerY) {
const float fiveTiles = 5 << TILE_SHIFT;
const float endX = fiveTiles * 3 + centerX;
const float startY = centerY + fiveTiles;
for (float x = centerX - fiveTiles; x < endX; x += fiveTiles) {
for (float y = startY; y > 0; y -= fiveTiles) {
// Keep these for now for debugging purposes
//jjAlert("x: " + x + ", y: " + y);
//jjDrawTile(x, y, 1);
jjSample(x, y, SOUND::BILSBOSS_THUNDER);
}
}
}
void processBackgroundLightningEffects() {
if (isThunderSoundDelayed) {
if (thunderSampleDelayCounter > 0) {
--thunderSampleDelayCounter;
} else {
playDistantThunderSample();
isThunderSoundDelayed = false;
}
}
if (jjGameTicks % 7 == 0 && isAnyBackgroundLightningVisible()) {
if (lightningFrameCounterGeneral < LIGHTNING_FRAMES_ONE.length() - 1) {
++lightningFrameCounterGeneral;
} else {
disableAllBackgroundLightnings();
}
}
if (jjGameTicks % BACKGROUND_LIGHTNING_INTERVAL == 0) {
int randomIndex = jjRandom() % BACKGROUND_LIGHTNINGS.length();
BACKGROUND_LIGHTNINGS[randomIndex].isVisible = true;
lightningFrameCounterGeneral = 0;
thunderSampleDelayCounter = BACKGROUND_THUNDER_SAMPLE_DELAY;
isThunderSoundDelayed = true;
}
}
void processBaseLightningEffects() {
// These will also trigger for a client who joins during an ongoing game where the respective team's score is higher than 0,
// but that should not be a problem as it happens only once and works as a nice welcome effect I guess
if (jjTeamScore[TEAM::BLUE] > previousTeamScoreBlue) {
playLightningSampleAt(BLUE_BASE_X, BLUE_BASE_Y);
lightningFrameCounterBlue = 0;
isLightningVisibleBlue = true;
previousTeamScoreBlue = jjTeamScore[TEAM::BLUE];
} else if (jjTeamScore[TEAM::BLUE] < previousTeamScoreBlue) { // As set by /bluescore x etc
previousTeamScoreBlue = jjTeamScore[TEAM::BLUE];
}
if (jjTeamScore[TEAM::RED] > previousTeamScoreRed) {
playLightningSampleAt(RED_BASE_X, RED_BASE_Y);
lightningFrameCounterRed = 0;
isLightningVisibleRed = true;
previousTeamScoreRed = jjTeamScore[TEAM::RED];
} else if (jjTeamScore[TEAM::RED] < previousTeamScoreRed) { // As set by /redscore x etc
previousTeamScoreRed = jjTeamScore[TEAM::RED];
}
if (jjGameTicks % 7 == 0 && isLightningVisibleBlue) {
if (lightningFrameCounterBlue < LIGHTNING_FRAMES_ONE.length() - 1) {
++lightningFrameCounterBlue;
} else {
isLightningVisibleBlue = false;
}
}
if (jjGameTicks % 7 == 0 && isLightningVisibleRed) {
if (lightningFrameCounterRed < LIGHTNING_FRAMES_ONE.length() - 1) {
++lightningFrameCounterRed;
} else {
isLightningVisibleRed = false;
}
}
}
void onLevelReload() {
MLLE::ReapplyPalette();
}
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.