Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Malice in Wonderland | Loon | Battle | 9.9 |
const bool MLLESetupSuccessful = MLLE::Setup(array<MLLEWeaponApply@> = {null, null, BubbleGun::Weapon(), null, null, null, WeaponVMega::GravityWell::Weapon(), null, null}); ///@MLLE-Generated
#include "MLLE-Include-1.6w.asc" ///@MLLE-Generated
#pragma require "xlmmalice-MLLE-Data-4.j2l" ///@MLLE-Generated
#pragma require "xlmmalice-MLLE-Data-3.j2l" ///@MLLE-Generated
#pragma require "xlmmalice-MLLE-Data-2.j2l" ///@MLLE-Generated
#pragma require "xlmmalice-MLLE-Data-1.j2l" ///@MLLE-Generated
#pragma require "xlmmalice.j2l" ///@MLLE-Generated
#include "WeaponVMega7.asc" ///@MLLE-Generated
#pragma require "WeaponVMega7.asc" ///@MLLE-Generated
#include "BubbleGun.asc" ///@MLLE-Generated
#pragma require "BubbleGun.asc" ///@MLLE-Generated
#pragma require "spelunky_ignite.wav"
#pragma require "Loonejjjjxdddd3.pal"
array<bool> canJump(jjLocalPlayerCount, true);
array<bool> canJumpTwo(jjLocalPlayerCount, true);
jjPAL PsychPal;
bool palCycle = true;
const string filename = "badlsdtrip.asdat";
void onLevelLoad() {
PsychPal.load("Loonejjjjxdddd3.pal");
PsychPal.color[255].red = PsychPal.color[255].green = PsychPal.color[255].blue = 0;
PsychPal.apply();
jjObjectPresets[OBJECT::BRIDGE].behavior = MyBridge;
jjLayers[1].spriteMode = SPRITE::BLEND_NORMAL;
jjLayers[1].spriteParam = 255;
jjTexturedBGFadePositionY = 0.30;
jjSampleLoad(SOUND::P2_POEP, "spelunky_ignite.wav");
jjTexturedBGTexture = TEXTURE::PSYCH;
jjUseLayer8Speeds = true;
jjWaterLayer = 28;
jjSetWaterGradient(0,22,44, 0,44,22);
jjWaterLighting = (WATERLIGHT::GLOBAL);
generateCustomSpringSprites(jjAnimSets[ANIM::CUSTOM[9]], array<uint> = {40, 16, 64, 88});
turnIntoCustomSpring(jjObjectPresets[OBJECT::FROZENSPRING], 0, 19.75f, false);
turnIntoCustomSpring(jjObjectPresets[OBJECT::HORREDSPRING], 1, 26.55f, false);
turnIntoCustomSpring(jjObjectPresets[OBJECT::HORGREENSPRING], 2, 17.75f, false);
turnIntoCustomSpring(jjObjectPresets[OBJECT::HORBLUESPRING], 3, 33.3f, false);
jjObjectPresets[OBJECT::HORREDSPRING].causesRicochet = jjObjectPresets[OBJECT::HORBLUESPRING].causesRicochet = jjObjectPresets[OBJECT::HORGREENSPRING].causesRicochet = false;
jjObjectPresets[OBJECT::GUNCRATE].behavior = ColoredCrate();
jjObjectPresets[OBJECT::SHARD].behavior = ColoredCrate();
// jjDelayGeneratedCrateOrigins = true;
jjWeapons[WEAPON::GUN8].spread = SPREAD::NORMAL;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].var[6] = 8 + 16;
jjObjectPresets[OBJECT::BOUNCERPOWERUP].direction = -1;
jjObjectPresets[OBJECT::GUN9POWERUP].direction = -1;
jjObjectPresets[OBJECT::TOASTERPOWERUP].direction = 0;
jjObjectPresets[OBJECT::CARROT].direction = SPRITE::FLIPV;
jjObjectPresets[OBJECT::ICEPOWERUP].direction = SPRITE::FLIPV;
// jjObjectPresets[OBJECT::ICEAMMO15].direction = SPRITE::FLIPH;
jjObjectPresets[OBJECT::SMALLTREE].direction = SPRITE::FLIPV;
jjObjectPresets[OBJECT::SWINGINGVINE].behavior = SyncedVine;
jjANIMATION@ anim = jjAnimations[jjAnimSets[ANIM::BRIDGE] + 2];
for (uint j = 0; j < anim.frameCount; j++) {
jjANIMFRAME@ frame = jjAnimFrames[anim + j];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 16 && sprite[x,y] <= 23) sprite[x,y] = 128 + (sprite[x,y]&7)*2;
}
}
sprite.save(frame);
}
jjSTREAM savedSettings(filename);
while (!savedSettings.isEmpty()) {
savedSettings.pop(palCycle);
}
}
void onLevelBegin() {
for (int i = 1; i < jjObjectCount; i++) {
if (jjObjects[i].eventID == OBJECT::BRIDGE){
jjObjects[i].yOrg += 7;
jjObjects[i].yPos += 7;
}
}
for (int x = 0; x < jjLayerWidth[4]; x++) {
for (int y = 0; y < jjLayerHeight[4]; y++) {
if ((jjEventGet(x, y) == OBJECT::GENERATOR && jjParameterGet(x, y, 0, 8) == 255) || jjEventGet(x, y) == 255) {
jjEventSet(x, y, AREA::ONEWAY);
}
}
}
/* jjObjectPresets[OBJECT::TOASTERBULLETPU].lightType = LIGHT::BRIGHT;
jjObjectPresets[OBJECT::TOASTERBULLETPU].light = 8;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].lightType = LIGHT::BRIGHT;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].light = 8;
jjObjectPresets[OBJECT::RFBULLET].lightType = LIGHT::BRIGHT;
jjObjectPresets[OBJECT::RFBULLET].light = 8;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].lightType = LIGHT::BRIGHT;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].light = 8;
jjObjectPresets[OBJECT::ICEBULLETPU].lightType = LIGHT::BRIGHT;
jjObjectPresets[OBJECT::ICEBULLETPU].light = 8;
jjObjectPresets[OBJECT::ELECTROBULLETPU].lightType = LIGHT::BRIGHT;
jjObjectPresets[OBJECT::ELECTROBULLETPU].light = 8;
jjObjectPresets[OBJECT::SEEKERBULLETPU].lightType = LIGHT::BRIGHT;
jjObjectPresets[OBJECT::SEEKERBULLETPU].light = 8; */
}
void onMain() {
jjWeapons[WEAPON::GUN8].comesFromGunCrates = true;
jjWeapons[WEAPON::GUN9].comesFromGunCrates = true;
for (int i = 1; i < jjObjectCount; i++) {
jjOBJ@ obj = jjObjects[i];
if (obj.eventID == OBJECT::ICEBULLETPU && obj.xSpeed > -0.5 && obj.xSpeed < 0.5) {
obj.xSpeed = 0;
}
if (jjObjects[i].eventID == OBJECT::CHESHIRE1){
jjObjects[i].yPos = jjObjects[i].yOrg - 15;
if (jjObjects[i].xPos>118*32 && jjObjects[i].yPos>48*32 && jjObjects[i].xPos<122*32 && jjObjects[i].yPos<52) {
jjObjectPresets[OBJECT::CHESHIRE1].direction = SPRITE::FLIPHV;
}
}
if (jjObjects[i].eventID == OBJECT::BOUNCERPOWERUP) {
jjObjects[i].yPos = 58.5*32;
jjObjects[i].ySpeed = 0;
}
if (jjObjects[i].eventID == OBJECT::BLASTERPOWERUP) {
jjObjects[i].yPos = 109.68*32;
jjObjects[i].ySpeed = 0;
}
if (obj.eventID == OBJECT::TOASTERPOWERUP){
obj.xPos = obj.xOrg + 16;
}
}
if (jjGameTicks % 4 == 0 && palCycle) {
for (int i = 128; i <= 143; i++) {
jjPalette.color[i].setHSL(PsychPal.color[i].getHue() + jjGameTicks / 6, PsychPal.color[i].getSat(), PsychPal.color[i].getLight());
}
jjPalette.apply();
}
if (jjGameTicks == 210)
jjConsole("|You can use the following command to pause the color changing foliage:||!palette");
}
void onPlayer(jjPLAYER@ player){
player.lightType = LIGHT::NONE;
handleFastCustomSpringSpeeds(player);
if (player.yPos >= 0) {
//Wherein "skill 3" means "MP Only"
int skill = jjParameterGet(uint16(player.xPos/32), uint16(player.yPos/32), -4, 2);
if (skill == 2) {
if (jjLayers[1].spriteParam > 96) {
if (jjLayers[1].spriteParam == 255) jjSamplePriority(SOUND::P2_POEP);
jjLayers[1].spriteParam = jjLayers[1].spriteParam - 10;
}
}
else if (jjLayers[1].spriteParam != 255) {
jjLayers[1].spriteParam = jjLayers[1].spriteParam + 10;
}
}
for (int i = 1; i < jjObjectCount; i++) {
if (jjObjects[i].isActive && jjObjects[i].eventID == OBJECT::COPTER && jjObjects[i].state == STATE::FLY) {
//Only set the counter if it's available to take
jjObjects[i].counter = 0;
if (jjObjects[i].var[4] == 0)
jjObjects[i].state = STATE::DONE;
}
}
if (!canJump[player.localPlayerID]) {
player.keyJump = player.keyDown = player.keyFire = player.keyLeft = player.keyRight = false;
}
if (!canJumpTwo[player.localPlayerID]) {
player.keyJump = player.keyDown = player.keyFire = false;
}
if (player.health == 0 || jjGameTicks == 1){
canJump[player.localPlayerID] = true;
canJumpTwo[player.localPlayerID] = true;
// player.yOrg += 32;
}
}
jjANIMSET@ customSpringSprite;
array<int> fastCustomSpringSpeeds(jjLocalPlayerCount);
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.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 handleFastCustomSpringSpeeds(jjPLAYER@ play) {
if (play.ySpeed < -32.f) {
fastCustomSpringSpeeds[play.localPlayerID] = int(ceil((play.ySpeed + 32.f) / -0.125f));
} else if (fastCustomSpringSpeeds[play.localPlayerID] != 0) {
if (play.ySpeed < -31.f) {
fastCustomSpringSpeeds[play.localPlayerID]--;
play.ySpeed = -32.f;
} else {
fastCustomSpringSpeeds[play.localPlayerID] = 0;
}
}
}
void onDrawLayer7(jjPLAYER@ play, jjCANVAS@ screen) {
jjSetWaterLevel((play.cameraY - jjLayers[15].getYPosition(play)) + 320, true);
}
void onDrawLayer4(jjPLAYER@ play, jjCANVAS@ screen) {
jjSetWaterLevel(16000, true);
}
class ColoredCrate : jjBEHAVIORINTERFACE {
int color;
void onBehave(jjOBJ@ obj) {
obj.behave(obj.eventID == OBJECT::GUNCRATE? BEHAVIOR::CRATE : BEHAVIOR::SHARD);
if (obj.state == STATE::KILL) {
obj.delete();
}
}
void onDraw(jjOBJ@ obj) {
color = jjParameterGet(int(obj.xOrg/32), int(obj.yOrg/32)+ (jjEventGet(int(obj.xOrg/32), int(obj.yOrg/32)) == 255? 0:1), 0, 8);
jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, color == 0? SPRITE::NORMAL : SPRITE::SINGLEHUE, color);
}
}
void onFunction3(jjPLAYER@ play, bool preventJump) {
canJump[play.localPlayerID] = preventJump;
}
void onFunction4(jjPLAYER@ play, bool preventJump) {
canJumpTwo[play.localPlayerID] = preventJump;
}
bool onDrawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) {
return MLLE::WeaponHook.drawAmmo(player, canvas);
}
/* array<string> Areas = {
"a", "b", "ยง2Loon is so awesome, so is PJ for helping me with this script!", "d", "e", "f", "g", "h"
};
string currArea = Areas[0];
void onFunction0(jjPLAYER@ play, int8 id) {
currArea = Areas[id];
}
bool onDrawHealth(jjPLAYER@ play, jjCANVAS@ canvas) {
canvas.drawString(jjSubscreenWidth - 16 - (currArea.length()*8), 64, currArea, STRING::SMALL, STRING::NORMAL);
return false;
} */
//violet's witchcraft bridges
enum BridgeVariables { PhysicalWidth, MaximumSagDistance, VisualWidth, FirstObjectIDOfPlatformForSplitscreenPlayers, Angle = FirstObjectIDOfPlatformForSplitscreenPlayers + 3 };
void MyBridge(jjOBJ@ obj) {
//first, check collision with bridge
if (obj.state==STATE::START) {
obj.state=STATE::STILL;
const uint xTile = uint(obj.xOrg) >> 5, yTile = uint(obj.yOrg) >> 5;
obj.var[BridgeVariables::PhysicalWidth] = 32 * jjParameterGet(xTile,yTile, 0,4);
obj.curAnim = jjAnimSets[ANIM::BRIDGE].firstAnim + (jjParameterGet(xTile,yTile, 4,3) % 7); //"Type" parameter... % 7 because there are only seven bridge types for some reason.
int toughness = jjParameterGet(xTile,yTile, 7,4);
if (toughness == 0) toughness = 4; //default toughness of 4, to avoid dividing by zero
obj.var[BridgeVariables::MaximumSagDistance] = obj.var[BridgeVariables::PhysicalWidth] / toughness;
//int heightInTiles = jjParameterGet(xTile,yTile, 11,-5);
int heightInTiles = jjParameterGet(xTile, yTile-1, 0, -8);
obj.var[BridgeVariables::Angle] = int(atan2(heightInTiles, obj.var[BridgeVariables::PhysicalWidth] / 32) * 162.974662f);
obj.xAcc = jjCos(obj.var[BridgeVariables::Angle]);
obj.yAcc = jjSin(obj.var[BridgeVariables::Angle]);
{ //determine how wide the bridge is, in drawn pixels (will always be >= how wide it is in mask pixels)
int frameID = 0;
int bridge_len = 0;
const int numberOfFramesUsedByAnimation = jjAnimations[obj.curAnim].frameCount;
const uint firstBridgeFrameID = jjAnimations[obj.curAnim].firstFrame;
while (true) {
if ((bridge_len += jjAnimFrames[firstBridgeFrameID + frameID].width) >= obj.var[BridgeVariables::PhysicalWidth])
break;
if (++frameID >= numberOfFramesUsedByAnimation)
frameID = 0;
}
obj.var[BridgeVariables::VisualWidth] = bridge_len;
}
obj.xOrg -= 16; //start at left edge of tile, not center
obj.yOrg -= 6; //worth noting that bridges are never deactivated, so we don't need to worry about where this gets moved to at all
for (int i = 1; i < jjLocalPlayerCount; ++i) { //this portion has no native JJ2 counterpart, because the API for platforms is still pretty limited
const int platformObjectID = jjAddObject(OBJECT::BRIDGE, 0,0, obj.objectID,CREATOR::OBJECT, BEHAVIOR::BEES);
jjOBJ@ platform = jjObjects[platformObjectID];
platform.deactivates = false;
platform.curFrame = jjAnimations[obj.curAnim].firstFrame;
obj.var[BridgeVariables::FirstObjectIDOfPlatformForSplitscreenPlayers - 1 + i] = platformObjectID;
}
}
obj.clearPlatform();
for (int i = 1; i < jjLocalPlayerCount; ++i)
jjObjects[obj.var[BridgeVariables::FirstObjectIDOfPlatformForSplitscreenPlayers - 1 + i]].clearPlatform();
array<int> pressXPosition;
array<jjPLAYER@> pressPlayer;
for (int playerID = 0; playerID < 32; ++playerID) {
jjPLAYER@ play = jjPlayers[playerID];
if (play.isActive && play.shieldType != SHIELD::LASER && jjObjects[play.platform].eventID != OBJECT::BURGER) { //all active players are valid, even if isLocal is false
const int tx = int(play.xPos-obj.xOrg);
const int ty = int(play.yPos-obj.yOrg - obj.yAcc / obj.xAcc * tx);
if ((tx >= 0) && (tx <= obj.var[BridgeVariables::PhysicalWidth]) && //player is within bridge area (horizontal)
(ty > -32) && (ty < obj.var[BridgeVariables::MaximumSagDistance]) && //(and vertical) //-32 was -24
(play.ySpeed > -1.f)) //not jumping, using a spring, etc.
{
pressXPosition.insertLast(tx);
pressPlayer.insertLast(play);
}
}
}
float max, amp, leftamp, rightamp;
int leftmostPressedX, rightmostPressedX;
if (pressPlayer.length != 0) {
if (pressPlayer.length > 1) {
leftmostPressedX=12312312;
rightmostPressedX=0;
uint t = 0;
do {
const int pressedX = pressXPosition[t];
if (pressedX < leftmostPressedX)
leftmostPressedX = pressedX;
if (pressedX > rightmostPressedX)
rightmostPressedX = pressedX;
} while (++t < pressPlayer.length);
leftamp = obj.var[BridgeVariables::MaximumSagDistance]*jjSin((512* leftmostPressedX)/obj.var[BridgeVariables::PhysicalWidth]);
rightamp = obj.var[BridgeVariables::MaximumSagDistance]*jjSin((512*rightmostPressedX)/obj.var[BridgeVariables::PhysicalWidth]);
}
uint t = 0;
uint numberOfLocalPlayersNeedingPlatforms = 0;
do {
const auto pressedPosition = pressXPosition[t];
if (pressPlayer.length == 1)
max = obj.var[BridgeVariables::MaximumSagDistance] * jjSin((512 * pressedPosition) / obj.var[BridgeVariables::PhysicalWidth]); //same formula as side amps above, but for single player bridges
else if ((pressedPosition>leftmostPressedX) && (pressedPosition<rightmostPressedX))
max = leftamp+(rightamp-leftamp)*(pressedPosition-leftmostPressedX)/(rightmostPressedX-leftmostPressedX);
else
max = obj.var[BridgeVariables::MaximumSagDistance]*jjSin((512 * pressedPosition)/obj.var[BridgeVariables::PhysicalWidth]);
jjPLAYER@ play = pressPlayer[t];
play.yPos = obj.yOrg + obj.yAcc / obj.xAcc * pressedPosition + max - 24;
if (play.isLocal) {
jjOBJ@ platform = (numberOfLocalPlayersNeedingPlatforms == 0) ? obj : jjObjects[obj.var[BridgeVariables::FirstObjectIDOfPlatformForSplitscreenPlayers - 1 + numberOfLocalPlayersNeedingPlatforms]];
platform.bePlatform(
platform.xPos = play.xPos,
platform.yPos = play.yPos + 24
);
//platform.draw();
if (play.buttstomp < 120)
play.buttstomp = 120;
numberOfLocalPlayersNeedingPlatforms += 1;
}
} while (++t < pressPlayer.length);
}
//draw
float bridge_len_x = 0, bridge_len_y = 0;
int frameID = 0;
const int numberOfFramesUsedByAnimation = jjAnimations[obj.curAnim].frameCount;
while (true) { //cooba - change specifically for mlfingers.j2l conditions
obj.curFrame = jjAnimations[obj.curAnim].firstFrame + frameID;
const jjANIMFRAME@ frame = jjAnimFrames[obj.curFrame];
float plankOffset = 0; //"straight bridge, or terugveren"
if (pressPlayer.length == 1) {
const auto pressedPosition = pressXPosition[0];
plankOffset = ((bridge_len_x<pressedPosition) ?
(max*jjSin(int(256*bridge_len_x)/pressedPosition)) : //left
(max*jjCos(int(256*(bridge_len_x-pressedPosition))/(obj.var[BridgeVariables::VisualWidth]-pressedPosition) ))
);
} else if (pressPlayer.length > 1) {
if (bridge_len_x < leftmostPressedX)
plankOffset = (leftamp*jjSin(int(256*bridge_len_x)/leftmostPressedX));
else if (bridge_len_x > rightmostPressedX)
plankOffset = (rightamp*jjCos(int(256*(bridge_len_x-rightmostPressedX))/(obj.var[BridgeVariables::VisualWidth]-rightmostPressedX) ));
else
plankOffset = leftamp+(rightamp-leftamp)*(bridge_len_x-leftmostPressedX)/(rightmostPressedX-leftmostPressedX);
}
jjDrawRotatedSpriteFromCurFrame(
obj.xOrg + bridge_len_x - frame.hotSpotX,
obj.yOrg + bridge_len_y + plankOffset,
obj.curFrame,
-obj.var[BridgeVariables::Angle],
1,
1,
jjLocalPlayers[0].shieldType == SHIELD::LASER? SPRITE::TRANSLUCENTPALSHIFT : SPRITE::NORMAL,
96
);
if (int(bridge_len_x += obj.xAcc * frame.width) >= obj.var[BridgeVariables::PhysicalWidth])
break;
bridge_len_y += obj.yAcc * frame.width;
if (++frameID >= numberOfFramesUsedByAnimation)
frameID = 0;
}
}
const uint NumberOfBitsDevotedToSyncParameter = 2; //this should correspond to the number of bits you assign to the Sync parameter in your JCS.ini (or MLLE equivalent) entry for Swinging Vine. So for example if you give it a parameter Sync:2, this variable should ALSO equal 2.
void SyncedVine(jjOBJ@ obj) {
obj.var[1] = 128; //vine length--set this in whatever way appeals to you, but a constant 128 is the value that normal swinging vines use.
if (lastSwingingVineLUTLength != obj.var[1]) { //need to generate LUT (LookUp Table) by doing the same math swinging vine objects do
lastSwingingVineLUTLength = obj.var[1];
PossibleVineVariableConfigurations = array<array<int>> = {{obj.var[1] * 256, 0}};
while (true) {
const array<int>@ oldConfiguration = @PossibleVineVariableConfigurations[PossibleVineVariableConfigurations.length-1];
array<int> newConfiguration(2);
newConfiguration[1] = oldConfiguration[1] + ((oldConfiguration[0] > 0) ? -32 : 32);
newConfiguration[0] = oldConfiguration[0] + newConfiguration[1];
if (newConfiguration[1] == 0 && newConfiguration[0] == obj.var[1] * 256) //gone full circle
break;
PossibleVineVariableConfigurations.insertLast(newConfiguration);
}
}
const array<int>@ syncedConfiguration = PossibleVineVariableConfigurations[(jjGameTicks + (jjParameterGet(uint(obj.xOrg) >> 5, uint(obj.yOrg) >> 5, 0, NumberOfBitsDevotedToSyncParameter) * (PossibleVineVariableConfigurations.length / (1 << NumberOfBitsDevotedToSyncParameter)))) % PossibleVineVariableConfigurations.length];
for (uint i = 0; i < 2; ++i)
obj.var[2 + i] = syncedConfiguration[i];
//clean up:
obj.state = STATE::ACTION;
obj.behavior = BEHAVIOR::SWINGINGVINE;
obj.behave();
}
int lastSwingingVineLUTLength = -1;
array<array<int>> PossibleVineVariableConfigurations;
bool onLocalChat(string &in text, CHAT::Type type) {
if (jjRegexMatch(text, "!palette", true)) {
if (palCycle) {
jjConsole("Palette cycling disabled!");
palCycle = false;
jjSTREAM stream;
stream.push(palCycle);
stream.save(filename);
}
else {
jjConsole("Palette cycling enabled!");
palCycle = true;
jjSTREAM stream;
stream.push(palCycle);
stream.save(filename);
}
return true;
}
else return false;
}
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.