Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Anniversary Bash 19 Levels | Jazz2Online | Multiple | N/A |
#pragma require "BubbleGun.j2a"
class Point {
int x, y;
Point() {}
Point(int X, int Y) {
x = X;
y = Y;
}
}
funcdef jjPALCOLOR ColorFunction(jjPALCOLOR);
void darkenLayer(jjLAYER@ layer, array<uint8>& freePaletteIndices, ColorFunction@ func) {
array<int> tileIDs, uniqueTileIDs;
for (int i = 0; i < layer.height; i++) {
for (int j = 0; j < layer.width; j++) {
int tileID = layer.tileGet(j, i);
if (tileID != 0)
tileIDs.insertLast(tileID);
}
}
int prev = 0;
tileIDs.sortAsc();
for (uint i = 0; i < tileIDs.length(); i++) {
if (tileIDs[i] != prev)
uniqueTileIDs.insertLast(prev = tileIDs[i]);
}
uint firstNewTile = jjTileCount;
jjTilesFromTileset(jjTilesetFileName, 1, uniqueTileIDs.length());
array<uint8> mapping(256);
for (uint i = 0; i < uniqueTileIDs.length(); i++) {
jjPIXELMAP tile(uniqueTileIDs[i]);
for (int j = 0; j < 32; j++) {
for (int k = 0; k < 32; k++) {
uint8 pixel = tile[k, j];
if (pixel != 0) {
if (mapping[pixel] == 0) {
jjPALCOLOR color = func(jjPalette.color[pixel]);
uint8 bestMatch = jjPalette.findNearestColor(color);
if (!freePaletteIndices.isEmpty()) {
jjPALCOLOR other = jjPalette.color[bestMatch];
int red = other.red - color.red;
int green = other.green - color.green;
int blue = other.blue - color.blue;
int distance = red * red + green * green + blue * blue;
if (distance > 16) {
bestMatch = freePaletteIndices[freePaletteIndices.length() - 1];
jjPalette.color[bestMatch] = color;
freePaletteIndices.removeLast();
}
}
mapping[pixel] = bestMatch;
}
tile[k, j] = mapping[pixel];
}
}
}
tile.save(firstNewTile + i);
}
layer.generateSettableTileArea();
for (int i = 0; i < layer.height; i++) {
for (int j = 0; j < layer.widthReal; j++) {
int tileID = layer.tileGet(j, i);
if (tileID != 0)
layer.tileSet(j, i, firstNewTile + uniqueTileIDs.find(tileID));
}
}
}
/*void turnTilesOrange(jjLAYER@ layer) {
array<int> tileIDs, uniqueTileIDs;
for (int i = 0; i < layer.height; i++) {
for (int j = 0; j < layer.width; j++) {
int tileID = layer.tileGet(j, i);
if (tileID != 0)
tileIDs.insertLast(tileID);
}
}
int prev = 0;
tileIDs.sortAsc();
for (uint i = 0; i < tileIDs.length(); i++) {
if (tileIDs[i] != prev)
uniqueTileIDs.insertLast(prev = tileIDs[i]);
}
uint firstNewTile = jjTileCount;
jjTilesFromTileset(jjTilesetFileName, 1, uniqueTileIDs.length());
array<uint8> mapping(256);
for (uint i = 0; i < uniqueTileIDs.length(); i++) {
jjPIXELMAP tile(uniqueTileIDs[i]);
for (int j = 0; j < 32; j++) {
for (int k = 0; k < 32; k++) {
uint8 pixel = tile[k, j];
if (pixel != 0) {
if (mapping[pixel] == 0) {
jjPALCOLOR color = jjPalette.color[pixel];
color.red = color.red * 2 / 3;
color.green = color.green * 2 / 3;
color.blue = color.blue * 2 / 3;
mapping[pixel] = jjPalette.findNearestColor(color);
}
tile[k, j] = mapping[pixel];
}
}
}
tile.save(firstNewTile + i);
}
layer.generateSettableTileArea();
for (int i = 0; i < layer.height; i++) {
for (int j = 0; j < layer.widthReal; j++) {
int tileID = layer.tileGet(j, i);
if (tileID != 0)
layer.tileSet(j, i, firstNewTile + uniqueTileIDs.find(tileID));
}
}
}*/
bool generateCustomSpringSprites(jjANIMSET@ anim, const array<uint> &in colors) {
int length = colors.length();
bool success = (@customSpringSprite = anim).allocate(array<uint>(length * 3, 5)) !is null;
if (success) {
uint srcSet = jjAnimSets[ANIM::SPRING];
for (int i = 0; i < length; i++) {
uint color = colors[i];
uint destAnimOffset = anim + i * 3;
for (int j = 0; j < 3; j++) {
uint srcAnim = jjAnimations[srcSet + j];
uint destAnim = jjAnimations[destAnimOffset + j];
for (int k = 0; k < 5; k++) {
jjPIXELMAP image(jjAnimFrames[destAnim + k] = jjAnimFrames[srcAnim + k]);
int width = image.width;
int height = image.height;
for (int l = 0; l < height; l++) {
for (int m = 0; m < width; m++) {
int pixel = image[m, l];
if (pixel >= 32 && pixel < 40)
image[m, l] = color + (pixel & 7);
}
}
if (!image.save(jjAnimFrames[destAnim + k]))
return false;
}
}
}
}
return success;
}
void initializeCustomSpring(jjOBJ@ obj) {
int anim = obj.curAnim;
obj.behave(obj.behavior = BEHAVIOR::SPRING, false);
if (obj.curAnim != anim) {
obj.curAnim = anim + 2;
obj.determineCurFrame();
}
obj.draw();
}
void turnIntoCustomSpring(jjOBJ@ obj, uint color, float power, bool horizontal) {
if (horizontal) {
obj.xSpeed = power;
obj.ySpeed = 0.f;
} else {
obj.xSpeed = 0.f;
obj.ySpeed = -power;
if (obj.state == STATE::START && obj.creatorType == CREATOR::LEVEL) {
int x = int(obj.xPos) >> 5;
int y = int(obj.yPos) >> 5;
if (jjParameterGet(x, y, 0, 1) != 0) {
jjParameterSet(x, y, 0, 1, 0);
obj.yPos -= 4.f;
obj.ySpeed = power;
}
}
}
obj.behavior = initializeCustomSpring;
obj.curAnim = customSpringSprite + color * 3 + (horizontal ? 1 : 0);
obj.energy = obj.frameID = obj.freeze = obj.justHit = obj.light = obj.points = 0;
obj.causesRicochet = obj.isBlastable = obj.isTarget = obj.scriptedCollisions = obj.triggersTNT = false;
obj.deactivates = obj.isFreezable = true;
obj.bulletHandling = HANDLING::IGNOREBULLET;
obj.playerHandling = HANDLING::SPECIAL;
obj.lightType = LIGHT::NORMAL;
obj.determineCurFrame();
}
void bubbleGun(jjOBJ@ bubble) {
if (bubble.state == STATE::START) {
bubble.state = STATE::FLY;
if (jjLocalPlayers[0].isLocal) jjSample(bubble.xPos, bubble.yPos, SOUND::COMMON_PLOP2, 0, 0);
}
if (jjMaskedPixel(int(bubble.xPos) + int(bubble.xSpeed), int(bubble.yPos)) || jjMaskedPixel(int(bubble.xPos) - int(bubble.xSpeed), int(bubble.yPos)) || jjMaskedPixel(int(bubble.xPos), int(bubble.yPos) + int(bubble.ySpeed)) || jjMaskedPixel(int(bubble.xPos), int(bubble.yPos) - int(bubble.ySpeed))) {
jjSample(bubble.xPos, bubble.yPos, SOUND::P2_SPLOUT, 0, 0);
}
bubble.behave(BEHAVIOR::WATERSHIELDBULLET);
bubble.killAnim = jjObjectPresets[OBJECT::WATERSHIELDBULLET].killAnim;
}
void bubbleGunPU(jjOBJ@ bubble) {
if (bubble.state == STATE::START) {
bubble.state = STATE::FLY;
if (jjLocalPlayers[0].isLocal) jjSample(bubble.xPos, bubble.yPos, SOUND::COMMON_PLOP2, 0, 0);
}
if (jjMaskedPixel(int(bubble.xPos) + int(bubble.xSpeed), int(bubble.yPos)) || jjMaskedPixel(int(bubble.xPos) - int(bubble.xSpeed), int(bubble.yPos)) || jjMaskedPixel(int(bubble.xPos), int(bubble.yPos) + int(bubble.ySpeed)) || jjMaskedPixel(int(bubble.xPos), int(bubble.yPos) - int(bubble.ySpeed))) {
jjSample(bubble.xPos, bubble.yPos, SOUND::P2_SPLOUT, 0, 0);
}
bubble.behave(BEHAVIOR::WATERSHIELDBULLET);
if (bubble.state == STATE::FLY && bubble.counter > 0) {
switch (bubble.direction) {
case 1: bubble.xSpeed = bubble.xSpeed - 0.1; bubble.ySpeed = bubble.ySpeed - 0.08; break;
case -1: bubble.xSpeed = bubble.xSpeed + 0.1; bubble.ySpeed = bubble.ySpeed - 0.08; break;
}
}
bubble.killAnim = jjObjectPresets[OBJECT::WATERSHIELDBULLET].killAnim;
bubble.var[6] = 8;
}
jjANIMSET@ customSpringSprite;
jjLAYER@ layer7Backup;
int layer7Row = 0;
array<Point> oneWays;
array<bool> specialMove(jjLocalPlayerCount);
//array<uint16> tilesToTurnOrange = {102, 101, 114, 115, 116};
//array<uint16> tilesToReplace = {556, 563, 564, 565, 566};
void onLevelLoad() {
jjDelayGeneratedCrateOrigins = true;
jjMASKMAP poleMask(133);
poleMask.save(146);
poleMask.save(153);
poleMask.save(156);
for (int i = 0; i < 14; i++) {
for (int j = 0; j < 32; j++) {
poleMask[j, i] = false;
}
}
poleMask.save(163);
jjMASKMAP vineMask(87);
for (int i = 0; i < 32; i++) {
vineMask[i, 5] = true;
}
vineMask.save(63);
vineMask.save(64);
vineMask.save(87);
vineMask.save(89);
vineMask.save(533);
vineMask.save(534);
vineMask.save(535);
jjPIXELMAP(163 | TILE::VFLIPPED).save(153);
for (int i = 146; i <= 156; i += 10) {
jjPIXELMAP poleTile(i);
for (int j = 0; j < 32; j++) {
poleTile[23, j] = poleTile[22, j];
}
poleTile.save(i);
}
jjPalette.color[176] = jjPALCOLOR(69, 88, 143);
jjPIXELMAP fog0, fog50, fog100;
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 32; j++) {
fog0[j, i] = i << 2;
fog50[j, i] = i + 32 << 2;
fog100[j, i] = 176;
}
}
fog0.save(660);
jjTileType[660] = 0;
fog50.save(661);
jjTileType[661] = 0;
fog100.save(679);
jjTileType[679] = 0;
jjLAYER fogLayer(jjLayers[6]);
fogLayer.generateSettableTileArea();
fogLayer.spriteMode = SPRITE::ALPHAMAP;
fogLayer.spriteParam = 176;
int top = -1, bottom = -1;
for (int i = 0; i < fogLayer.height; i++) {
for (int j = 0; j < fogLayer.widthReal; j++) {
if (fogLayer.tileGet(j, i) != 0) {
if (top < 0)
top = i;
bottom = i;
fogLayer.tileSet(j, i, 0);
}
}
}
for (int i = 0; i < fogLayer.widthReal; i++) {
fogLayer.tileSet(i, top - 2, 660);
fogLayer.tileSet(i, top - 1, 661);
fogLayer.tileSet(i, bottom + 1, 661 | TILE::VFLIPPED);
fogLayer.tileSet(i, bottom + 2, 660 | TILE::VFLIPPED);
}
array<uint8> freePaletteIndices = {113, 118, 120, 160};
for (int i = 177; i < 208; i++) {
freePaletteIndices.insertLast(i);
}
if (jjLayers[8].hasTileMap)
darkenLayer(jjLayers[8], freePaletteIndices, function(color) {
color.setHSL(color.getHue(), color.getSat() / 2, color.getLight());
return color;
});
if (jjLayers[1].hasTileMap)
darkenLayer(jjLayers[1], freePaletteIndices, function(color) {
color.setHSL(color.getHue(), color.getSat() * 4 / 5, color.getLight() * 2 / 5);
return color;
});
jjLayerOrderSet(array<jjLAYER@> = {jjLayers[2], jjLayers[3], jjLayers[4], jjLayers[1], jjLayers[5], jjLayers[6], fogLayer, jjLayers[7], jjLayers[8]});
for (int i = 0; i < jjLayers[4].height; i++) {
for (int j = 0; j < jjLayers[4].width; j++) {
if (jjEventGet(j, i) == AREA::ONEWAY)
oneWays.insertLast(Point(j, i));
}
}
int tileOffset = jjTileCount;
jjTilesFromTileset(jjTilesetFileName, 1, 128);
for (int i = 0; i < 128; i++) {
jjPIXELMAP tile;
for (int j = 0; j < 32; j++) {
for (int k = 0; k < 32; k++) {
tile[k, j] = 58;
}
}
for (int j = jjRandom() & 3; j >= 0; j--) {
tile[jjRandom() & 31, jjRandom() & 31] = (jjRandom() & 15 == 0 ? 48 + (jjRandom() & 127) : 144 + (jjRandom() & 15));
}
tile.save(tileOffset + i);
}
jjLayers[7].generateSettableTileArea();
for (int i = 0; i < jjLayers[7].height; i++) {
for (int j = 0; j < jjLayers[7].widthReal; j++) {
if (jjLayers[7].tileGet(j, i) != 0)
jjLayers[7].tileSet(j, i, tileOffset + (jjRandom() & 127));
}
}
layer7Row = jjLayers[7].height / 2;
@layer7Backup = jjLAYER(jjLayers[7]);
layer7Backup.generateSettableTileArea();
/*array<uint8> mapping(256);
for (uint i = 0; i < tilesToTurnOrange.length(); i++) {
jjPIXELMAP tile(tilesToTurnOrange[i]);
for (int j = 0; j < 32; j++) {
for (int k = 0; k < 32; k++) {
uint8 pixel = tile[k, j];
if (pixel != 0) {
if (mapping[pixel] == 0) {
jjPALCOLOR color = jjPalette.color[pixel];
int hue = color.getHue();
int sat = color.getSat();
int light = color.getLight();
if (i > 2 && k <= 16) color.setHSL(hue + 100, sat, light + 10);
else if (i < 2) color.setHSL(hue + 100, sat, light + 10);
mapping[pixel] = jjPalette.findNearestColor(color);
}
tile[k, j] = mapping[pixel];
}
}
}
tile.save(tilesToReplace[i]);
jjMASKMAP(tilesToTurnOrange[i]).save(tilesToReplace[i], true);
}*/
generateCustomSpringSprites(jjAnimSets[ANIM::CUSTOM[3]], array<uint> = {40});
turnIntoCustomSpring(jjObjectPresets[OBJECT::FROZENSPRING], 0, 21.f, false);
jjAnimSets[ANIM::CUSTOM[0]].load(0, "BubbleGun.j2a");
jjAnimSets[ANIM::CUSTOM[1]].load(1, "BubbleGun.j2a");
jjAnimSets[ANIM::CUSTOM[2]].load(2, "BubbleGun.j2a");
jjAnimations[jjAnimSets[ANIM::AMMO] + 29] = jjAnimations[jjAnimSets[ANIM::AMMO] + 8];
jjAnimations[jjAnimSets[ANIM::AMMO] + 28] = jjAnimations[jjAnimSets[ANIM::CUSTOM[0]] + 0];
jjAnimations[jjAnimSets[ANIM::PICKUPS] + 62] = jjAnimations[jjAnimSets[ANIM::CUSTOM[1]] + 0];
jjAnimations[jjAnimSets[ANIM::PICKUPS] + 55] = jjAnimations[jjAnimSets[ANIM::CUSTOM[2]] + 0];
jjObjectPresets[OBJECT::ICEBULLET].behavior = bubbleGun;
jjObjectPresets[OBJECT::ICEBULLET].counterEnd = 105;
jjObjectPresets[OBJECT::ICEBULLET].freeze = 0;
jjObjectPresets[OBJECT::ICEBULLET].special = jjObjectPresets[OBJECT::ICEBULLET].determineCurAnim(ANIM::AMMO, 8);
jjObjectPresets[OBJECT::ICEBULLET].xSpeed = 1.25;
jjObjectPresets[OBJECT::ICEBULLET].determineCurFrame();
jjObjectPresets[OBJECT::ICEBULLETPU].behavior = bubbleGunPU;
jjObjectPresets[OBJECT::ICEBULLETPU].counterEnd = 105;
jjObjectPresets[OBJECT::ICEBULLETPU].freeze = 0;
jjObjectPresets[OBJECT::ICEBULLETPU].special = jjObjectPresets[OBJECT::ICEBULLETPU].determineCurAnim(ANIM::CUSTOM[0], 0);
jjObjectPresets[OBJECT::ICEBULLETPU].xSpeed = 1.5;
jjObjectPresets[OBJECT::ICEBULLETPU].determineCurFrame();
jjObjectPresets[OBJECT::ICEAMMO3].determineCurFrame();
jjObjectPresets[OBJECT::ICEAMMO15].determineCurFrame();
jjObjectPresets[OBJECT::ICEPOWERUP].determineCurFrame();
jjWeapons[WEAPON::ICE].spread = SPREAD::NORMAL;
jjWeapons[WEAPON::ICE].defaultSample = false;
}
void onLevelBegin() {
for (int i = 0; i < jjObjectCount; i++) {
jjOBJ@ obj = jjObjects[i];
if (obj.eventID == OBJECT::GENERATOR) {
int x = int(obj.xOrg) >> 5;
int y = (int(obj.yOrg) >> 5) - 1;
if (x >= 0 && y >= 0 && x < jjLayers[4].width && y < jjLayers[4].height && jjEventGet(x, y) == AREA::PATH)
obj.xPos += 14.f;
}
}
}
void onPlayer(jjPLAYER@ player) {
if (jjEventGet(int(player.xPos) >> 5, int(player.yPos) >> 5) == AREA::SUCKERTUBE)
player.alreadyDoubleJumped = false;
bool previousSpecialMove = specialMove[player.localPlayerID];
bool currentSpecialMove = player.specialMove != 0 && jjCharacters[player.charCurr].groundJump != GROUND::JAZZ;
if (currentSpecialMove ^^ previousSpecialMove) {
for (uint i = 0; i < oneWays.length(); i++) {
const Point@ tile = oneWays[i];
jjEventSet(tile.x, tile.y, currentSpecialMove ? 0 : AREA::ONEWAY);
}
specialMove[player.localPlayerID] = currentSpecialMove;
}
}
void onDrawLayer8(jjPLAYER@ player, jjCANVAS@) {
int y = 30 - int(player.cameraY * jjLayers[6].ySpeed / 32.f);
if (layer7Row != y) {
while (layer7Row > y) {
layer7Row--;
for (int i = 0; i < jjLayers[7].widthReal; i++) {
int realRow = (layer7Row + jjLayers[7].height) % jjLayers[7].height;
jjLayers[7].tileSet(i, realRow, 0);
}
}
while (layer7Row < y) {
for (int i = 0; i < jjLayers[7].widthReal; i++) {
int realRow = (layer7Row + jjLayers[7].height) % jjLayers[7].height;
jjLayers[7].tileSet(i, realRow, layer7Backup.tileGet(i, realRow));
}
layer7Row++;
}
}
}
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.