Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Blast Concussion | Violet CLM | Capture the flag | 9.7 |
const bool MLLESetupSuccessful = MLLE::Setup(array<MLLEWeaponApply@> = {null, null, null, null, null, null, null, SmokeWopens::PhoenixGun::Wopen(), ArcaneWeapons::FusionCannon::Weapon()}); ///@MLLE-Generated
#include "MLLE-Include-1.6w.asc" ///@MLLE-Generated
#pragma require "blcon-MLLE-Data-1.j2l" ///@MLLE-Generated
#pragma require "blcon.j2l" ///@MLLE-Generated
#include "ArcaneWeapon9.asc" ///@MLLE-Generated
#pragma require "ArcaneWeapon9.asc" ///@MLLE-Generated
#include "PhoenixGun.asc" ///@MLLE-Generated
#pragma require "PhoenixGun.asc" ///@MLLE-Generated
///@SaveAndRunArgs -server -capture ///@MLLE-Generated
#include "ArcaneWeapon4.asc"
#pragma require "ArcaneWeapon4.asc"
ArcaneWeapons::MortarLauncher::Weapon Mortar;
#pragma offer "spelunky_ignite.wav"
bool igniteLoaded = false;
#pragma offer "blastFirewall.png" //https://opengameart.org/content/animated-sprites-and-textures
bool FirewallLoaded;
array<jjLAYER@> FirewallAnimation(64, null);
jjPAL FirewallPalette;
bool onDrawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) {
return MLLE::WeaponHook.drawAmmo(player, canvas);
}
void onReceive(jjSTREAM&in packet, int fromClientID) {
bool powerup; packet.pop(powerup);
uint16 xPos; packet.pop(xPos);
launchMortar(xPos, powerup, jjIsServer, -fromClientID);
}
void launchMortar(uint16 xPos, bool powerup, bool send, int toClientID) {
jjOBJ@ obj = jjObjects[Mortar.FireBullet(xPos, 16, 256, powerup, 0, CREATOR::OBJECT, WEAPON::SEEKER)[0]];
obj.creator = CREATOR::OBJECT;
obj.var[7] = 0;
obj.var[0] = int(obj.yPos) + jjMaskedTopVLine(int(obj.xPos), int(obj.yPos), 36*32);
obj.behavior = MortarWrapper;
obj.yAcc = abs(obj.yAcc);
obj.animSpeed = powerup ? 2 : 1;
obj.deactivates = false;
if (send) {
jjSTREAM packet;
packet.push(powerup);
packet.push(xPos);
jjSendPacket(packet, toClientID);
}
}
void onLevelLoad() {
Mortar.LoadResources();
if (jjAnimSets[ANIM::PINBALL] == 0)
jjAnimSets[ANIM::PINBALL].load();
jjObjectPresets[OBJECT::ONEUP].behavior = jjObjectPresets[OBJECT::GUN9AMMO3].behavior;
jjObjectPresets[OBJECT::ONEUP].var[3] = WEAPON::GUN9 - 1;
jjObjectPresets[OBJECT::ONEUP].eventID = OBJECT::GUN9AMMO3;
jjPIXELMAP(0,0, 32,64, 5).trim().save(jjAnimFrames[jjObjectPresets[OBJECT::ONEUPBARREL].curFrame]);
jjLAYER@ slime = MLLE::GetLayer("Slime");
slime.yOffset = (jjLayerHeight[4] - slime.height) * -32;
jjLAYER slime2(slime);
slime2.warpHorizon.fadePositionY = 0;
slime2.yOffset += slime2.height * 32;
slime2.generateSettableTileArea();
for (int x = slime2.widthReal; --x >= 0;)
for (int y = slime2.height; --y >= 0;)
slime2.tileSet(x,y, 392);
auto layers = jjLayerOrderGet();
layers.insertAt(5, slime2);
const array<int> animIDs = {1,2,5,6};
for (uint i = 0; i < animIDs.length; ++i) {
jjANIMATION@ anim = jjAnimations[jjAnimSets[ANIM::FLAG] + animIDs[i]];
for (uint j = 0; j < anim.frameCount; ++j)
jjAnimFrames[anim + j].hotSpotY += 5;
}
jjObjectPresets[OBJECT::CUCUMB].behavior = Toob;
jjObjectPresets[OBJECT::CUCUMB].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::CUCUMB].bulletHandling = HANDLING::DESTROYBULLET;
for (int i = 0; i < 2; ++i) {
jjANIMFRAME@ toobFrame = jjAnimFrames[jjObjectPresets[OBJECT::CUCUMB].curFrame + i];
jjPIXELMAP(32,2*32*i, 6*32,2*32, 5).save(toobFrame);
toobFrame.hotSpotX = int(toobFrame.width) / -2;
toobFrame.hotSpotY = -5;
}
array<uint8> keepSlime(256);
for (uint i = 0; i < 256; ++i)
keepSlime[i] = i;
keepSlime[183] = 0;
for (uint animID = 0; animID < 2; ++animID) {
auto frames = jjAnimatedTiles[animID + 1].getFrames();
for (uint frameID = 0; frameID < frames.length(); ++frameID) {
const uint16 tileID = frames[frameID];
jjPIXELMAP(tileID).recolor(keepSlime).save(tileID);
}
}
igniteLoaded = jjSampleLoad(SOUND::P2_OPEN, "spelunky_ignite.wav");
jjObjectPresets[OBJECT::LIGHTNINGSHIELD].behavior =
jjObjectPresets[OBJECT::BOUNCERPOWERUP].behavior =
jjObjectPresets[OBJECT::GUN8POWERUP].behavior =
NoFallMonitor;
if (FirewallPalette.load("blastFirewall.png")) {
const jjPIXELMAP firewallSheet("blastFirewall.png");
if (firewallSheet.height == 224*64) {
FirewallLoaded = true;
jjLAYER fireBase(1,7);
fireBase.textureSurface = SURFACE::INNERLAYER;
fireBase.textureStyle = TEXTURE::WAVE;
fireBase.ySpeed = 1;
fireBase.xInnerSpeed = 0.9;
fireBase.tileWidth = true;
fireBase.yOffset = -28 * 32 - 28;
fireBase.hasTiles = false;
fireBase.wave.amplitudeX = 0.125;
fireBase.wave.wavelengthX = 255;
fireBase.wave.waveSpeed = 3;
for (uint frameID = 0; frameID < 64; ++frameID) {
jjLAYER fire(fireBase);
fire.spriteMode = SPRITE::BLEND_SCREEN;
fire.spriteParam = 255;
jjPIXELMAP copy(256,256);
for (uint x = 0; x < 256; ++x) {
uint yy = frameID * 224;
for (uint y = 0; y < 224; ++y, ++yy)
copy[x,y] = firewallSheet[x,yy];
}
copy.makeTexture(fire);
@FirewallAnimation[frameID] = @fire;
layers.insertAt(10, fire);
}
jjLAYER alienCylinder(jjLayers[6]);
jjLayers[6].spriteMode = SPRITE::INVISIBLE;
layers.insertAt(9, alienCylinder);
}
}
if (jjLocalPlayerCount != 1)
MLLE::GetLayer("cooba").hasTiles = false;
jjLayerOrderSet(layers);
}
void onLevelBegin() {
jjWeapons[WEAPON::RF].replacedByShield = true;
}
void MortarWrapper(jjOBJ@ obj) {
if (obj.yPos >= 36*32) //don't fall into the caverns
obj.state = STATE::EXPLODE;
if (obj.state == STATE::EXPLODE) {
if (obj.playerHandling != HANDLING::EXPLOSION) { //skip doBlast
obj.playerHandling = HANDLING::EXPLOSION;
obj.frameID = 0;
obj.counter = 0;
obj.curAnim = obj.killAnim;
for (int i = 1; i < jjObjectCount; i++) {
jjOBJ@ target = jjObjects[i];
if (target.behavior == BEHAVIOR::DESTRUCTSCENERY && target.state != STATE::KILL && target.state != STATE::DONE && target.state != STATE::EXPLODE && abs(target.xPos - obj.xPos) < 80)
target.state = STATE::KILL;
}
}
} else
obj.counter = 5; //don't explode early
obj.behave(ArcaneWeapons::MortarLauncher::Behavior);
if (obj.state != STATE::EXPLODE) {
const int distance = obj.var[0] - int(obj.yPos);
if (distance > 31)
jjDrawRectangle(obj.xPos - distance/64, obj.yPos, distance / 32, distance, 15, SPRITE::TRANSLUCENT);
}
}
array<uint> MortarCountdowns(jjLocalPlayerCount, 70 * 3);
void onPlayer(jjPLAYER@ player) {
jjIsSnowing = jjLocalPlayerCount == 1 && player.yPos > 36*32;
if (jjGameState == GAME::STARTED || jjGameState == GAME::OVERTIME) {
if (MortarCountdowns[player.localPlayerID] > 0)
MortarCountdowns[player.localPlayerID] -= 1;
if (player.yPos < 36*32 && player.xPos > 9*32 && player.yPos < 144*32 + 16) {
if (MortarCountdowns[player.localPlayerID] == 0) {
launchMortar(uint16(player.xPos), player.flag != 0 || jjGameState == GAME::OVERTIME, true, 0);
MortarCountdowns[player.localPlayerID] = jjGameState == GAME::OVERTIME ? 55 : 125;
}
}
}
}
void onFunction0(jjPLAYER@ player, uint8 eventID) {
if (player.fly == FLIGHT::AIRBOARD || jjLocalPlayerCount != 1)
eventID = AREA::ONEWAY;
for (uint x = 33; x <= 37; ++x)
jjEventSet(x,24, eventID);
}
void onFunction1(jjPLAYER@ player, uint8 eventID) {
if (player.fly == FLIGHT::AIRBOARD || jjLocalPlayerCount != 1)
eventID = AREA::ONEWAY;
for (uint x = 116; x <= 120; ++x)
jjEventSet(x,24, eventID);
}
void Toob(jjOBJ@ obj) {
if (obj.state == STATE::START) {
if (obj.creatorType == CREATOR::LEVEL)
jjAddObject(obj.eventID, obj.xPos, obj.yPos + 56);
obj.state = STATE::IDLE;
}
const auto lastY = obj.yPos;
if (obj.creatorType == CREATOR::LEVEL)
for (uint i = 0; i < 2; ++i)
jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame + i, layerZ: 3 + i);
obj.yPos = obj.yOrg + jjSin(jjGameTicks << 2) * 4;
obj.bePlatform(obj.xPos, lastY);
}
void onFunction2() {
if (jjGameConnection != GAME::LOCAL)
for (int x = jjLayerWidth[4]; --x >= 0;)
for (int y = jjLayerHeight[4]; --y >= 0;)
if (jjParameterGet(x,y, -12, 20) == OBJECT::GENERATOR | (1 << 11) | (OBJECT::TNTDESTRUCTSCENERY << 12))
jjEventSet(x,y, AREA::ONEWAY);
}
uint8 Layer2OpacityTarget = 255;
void onFunction3(bool on) {
if (jjLocalPlayerCount != 1)
return;
if (on && Layer2OpacityTarget == 255 && igniteLoaded)
jjSamplePriority(SOUND::P2_OPEN);
Layer2OpacityTarget = on ? 63 : 255;
jjLayers[2].spriteMode = SPRITE::BLEND_NORMAL;
}
void onMain() {
jjLAYER@ layer2 = jjLayers[2];
if (layer2.spriteParam > Layer2OpacityTarget)
layer2.spriteParam -= 8;
else if (layer2.spriteParam < Layer2OpacityTarget) {
layer2.spriteParam += 8;
if (layer2.spriteParam == 255)
layer2.spriteMode = SPRITE::NORMAL;
}
}
void NoFallMonitor(jjOBJ@ obj) {
obj.direction = SPRITE::FLIPV;
obj.behavior = BEHAVIOR::MONITOR;
obj.behave();
obj.direction = (jjRandom() & 1) == 1 ? SPRITE::FLIPV : SPRITE::FLIPHV;
}
uint8 firewallFrameID;
void onDrawLayer7(jjPLAYER@, jjCANVAS@) {
if (FirewallLoaded) {
if (jjColorDepth == 16 && !jjLowDetail) {
jjPalette = FirewallPalette;
FirewallAnimation[firewallFrameID & 63].hasTiles = true;
}
FirewallAnimation[(firewallFrameID - 1) & 63].hasTiles = false;
++firewallFrameID;
}
}
void onDrawLayer6(jjPLAYER@, jjCANVAS@) {
if (FirewallLoaded && jjColorDepth == 16 && !jjLowDetail)
jjPalette = MLLE::Palette; //https://www.everypixel.com/image-9344540279828670815
}
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.