Downloads containing ab19btl20.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Anniversary Bash 19 Levels Jazz2Online Multiple N/A Download file

File preview

#pragma require "Heaven.j2t"
#pragma require "ab19btl20ex.j2l"

void onLevelLoad() {
	loadExtraLayers();

	jjTilesFromTileset("Desolation03.j2t", 0, 0); //hack to restore current tileset's CRC32

	for (int eventID = OBJECT::BLASTERBULLET; eventID <= OBJECT::BULLET; ++eventID) {
		jjObjectPresets[eventID].behavior = BulletWrapper(jjObjectPresets[eventID].behavior);
	}
}

class BulletWrapper : jjBEHAVIORINTERFACE {
	private jjBEHAVIOR nativeBehavior;
	BulletWrapper(const jjBEHAVIOR &in nb) {
		nativeBehavior = nb;
	}

	void onBehave(jjOBJ@ obj) {
		obj.behave(nativeBehavior);

		float xPixelLimit = 1;
		if (obj.xPos > (jjLayers[4].width) * 32 - (xPixelLimit + 1) && obj.xSpeed > 0) {
			obj.xPos = xPixelLimit;
		} else if (obj.xPos < xPixelLimit && obj.xSpeed < 0) {
			obj.xPos = jjLayers[4].width * 32 + (xPixelLimit + 1);
		}
	}
	bool onIsRFBullet(jjOBJ@ obj) {
		return nativeBehavior == BEHAVIOR::RFBULLET;
	}
}

void loadExtraLayers() {
	const int oldTileCount = jjTileCount;
	if (!jjTilesFromTileset("Heaven.j2t", 520, 100)) { //first tileID
		jjAlert("|ERROR: Heaven.j2t not found!", false, STRING::MEDIUM);
		return;
	}

	array<jjLAYER@> heavenLayers = jjLayersFromLevel(
		"ab19btl20ex.j2l",
		array<uint> = {6,7}, //Which (1-indexed) layers to copy
		oldTileCount - 520
	);
	if (heavenLayers.length == 0) {
		jjAlert("|ERROR: Heaven.j2l not found!", false, STRING::MEDIUM);
		return;
	}

	// This loop edited in by SE to replace spriteMode usage for a major efficiency boost.
	for (int tileID = 0; tileID < 100; tileID++) {
		jjTileType[oldTileCount + tileID] = 1;
	}

	for (uint layerID = 0; layerID < heavenLayers.length; ++layerID) {
		heavenLayers[layerID].yOffset = 10 * 32;
		heavenLayers[layerID].limitVisibleRegion = false;
		//heavenLayers[layerID].spriteMode = SPRITE::TRANSLUCENTTILE;
	}

	jjLAYER@ blackLayer = jjLAYER(4, jjLayers[6].height);
	blackLayer.generateSettableTileArea();
	blackLayer.xSpeed = jjLayers[6].xSpeed;
	blackLayer.ySpeed = jjLayers[6].ySpeed;
	blackLayer.tileWidth = true;
	for (int y = 70; y < blackLayer.height; y++) {
		for (int x = 0; x < blackLayer.width; x++) {
			blackLayer.tileSet(x, y, 404); //black tile
		}
	}

	array<jjLAYER@> extraBuildingLayers;
	addBuilderLayers( 0, 4, 8, extraBuildingLayers);
	addBuilderLayers(16, 4, 12, extraBuildingLayers);
	addBuilderLayers(36, 4, 10, extraBuildingLayers);
	addBuilderLayers(48, 4, 8, extraBuildingLayers);
	addBuilderLayers(64, 4, 12, extraBuildingLayers);
	addBuilderLayers(86, 4, 10, extraBuildingLayers);
	addBuilderLayers(102, 4, 8, extraBuildingLayers);
	//recreate first two to imitate tiled width
	addBuilderLayers(120, 4, 8, extraBuildingLayers);
	addBuilderLayers(136, 4, 12, extraBuildingLayers);
	//recreate last to imitate tiled width
	addBuilderLayers(-18, 4, 8, extraBuildingLayers);

	jjTexturedBGTexture = TEXTURE::WISETYNESS;
	jjSetFadeColors(70, 64, 66); //above, but a bit darker
	jjUseLayer8Speeds = true;
	jjLayers[7].spriteMode = SPRITE::TRANSLUCENTTILE; //barely visible moon

	array<jjLAYER@> layers;
	layers.insertLast(jjLayers[1]);
	layers.insertLast(jjLayers[2]);
	layers.insertLast(jjLayers[3]);
	layers.insertLast(jjLayers[4]);
	layers.insertLast(jjLayers[5]);
	layers.insertLast(jjLayers[6]);
	layers.insertLast(blackLayer);

	layers.insertAt(layers.length(), extraBuildingLayers);

	layers.insertLast(heavenLayers[0]);
	layers.insertLast(heavenLayers[1]);
	layers.insertLast(jjLayers[7]);
	layers.insertLast(jjLayers[8]);
	jjLayerOrderSet(layers);
}

void addBuilderLayers(int xTile, int yStart, int buildingWidth, array<jjLAYER@>@ layers) {
	int layerWidth = (buildingWidth + 3) & ~0x03;

	int xStart = 0;

	jjLAYER@ baseLayer = jjLAYER(layerWidth, 100);
	baseLayer.generateSettableTileArea();
	baseLayer.xSpeed = 0.75f;
	baseLayer.ySpeed = 0.75f;
	baseLayer.xOffset = 32 * (-1 - (xTile - buildingWidth / 2));
	addBuilding(baseLayer, xStart, yStart, buildingWidth);

	layers.insertLast(baseLayer);

	int i = 10;
	jjLAYER@ layer = jjLAYER(baseLayer);
	layer.spriteMode = SPRITE::SINGLECOLOR;
	layer.spriteParam = 200;
	float speedOffset = (i + 1) / 256.0;
	float offset = (i + 1) * ((5.375 * xTile) - (4 * buildingWidth) + 16) / 32;
	layer.xSpeed -= speedOffset;
	layer.xOffset += offset;
	layers.insertLast(layer);
}

void addBuilding(jjLAYER@ layer, int xStart, int yStart, int width) {
	uint16 topLeft   = 640;
	uint16 topMiddle = 641;
	uint16 topRight  = 642;
	uint16 left   = 650;
	uint16 middle = 671; //light on
	uint16 right  = 652;

	int xEnd = xStart + width;
	int yEnd = layer.height;

	for (int x = xStart; x < xEnd; x++) {
		for (int y = yStart; y < yEnd; y++) {
			uint16 tileID;
			if (y == yStart) {
				if (x == xStart) {
					tileID = topLeft;
				} else if (x == xEnd - 1) {
					tileID = topRight;
				} else {
					tileID = topMiddle;
				}
			} else if (x == xStart) {
				tileID = left;
			} else if (x == xEnd - 1) {
				tileID = right;
			} else {
				tileID = middle;
			}
			layer.tileSet(x, y, tileID);
		}
	}
}

int min(int a, int b) {
	return a < b ? a : b;
}

void onPlayer(jjPLAYER@ player) {
	float xPixelLimit = 1;
	if (player.xPos > (jjLayers[4].width) * 32 - (xPixelLimit + 1) && player.xSpeed > 0) {
		player.offsetPosition(int(-(player.xPos - xPixelLimit)), 0);
	} else if (player.xPos < xPixelLimit && player.xSpeed < 0) {
		player.offsetPosition(int(-(player.xPos - (jjLayers[4].width) * 32 - (xPixelLimit + 1))), 0);
	}
}