Downloads containing MLLE-Include-1.6.asc

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: The Town Pack Slaz Single player 7.7 Download file
TSF with JJ2+ Only: Several asymmetrical... Rysice Multiple N/A Download file
TSF with JJ2+ Only: Jingle JumbleFeatured Download Primpy Single player 9.3 Download file
TSF with JJ2+ Only: Asteroid Armada PurpleJazz Battle N/A Download file
TSF with JJ2+ Only: Lori FortressFeatured Download Primpy Single player 8.7 Download file
TSF with JJ2+ Only: Weed Jungle Dragusela Battle N/A Download file
TSF with JJ2+ Only: Inside the Freezer Dragusela Battle 6 Download file
TSF with JJ2+ Only: Carrot FarmFeatured Download Loon Capture the flag 9.3 Download file

File preview

  1. //199024013
  2. //This is a standard library created by MLLE to read some JJ2+ properties from a level file whose script includes this library. DO NOT MANUALLY MODIFY THIS FILE.
  3.  
  4.  
  5.  
  6.  
  7.  
  8. #pragma require 'MLLE-Include-1.6.asc'
  9. namespace MLLE {
  10.     jjPAL@ Palette;
  11.     dictionary@ _layers, _palettes;
  12.     array<_offgridObject>@ _offGridObjects;
  13.  
  14.     bool Setup() {
  15.         jjPAL palette = jjBackupPalette;
  16.         @Palette = @palette;
  17.         dictionary layers;
  18.         @_layers = @layers;
  19.         dictionary palettes;
  20.         @_palettes = @palettes;
  21.  
  22.         jjSTREAM crcCheck('MLLE-Include-1.6.asc');
  23.         string crcLine;
  24.         if (crcCheck.isEmpty() || !crcCheck.getLine(crcLine)) {
  25.             jjDebug('MLLE::Setup: Include file has been renamed!');
  26.             return false;
  27.         }
  28.         array<string> regexResults;
  29.         if (!jjRegexMatch(crcLine, '\\/\\/(\\d+)\\r?', regexResults)) {
  30.             jjDebug('MLLE::Setup: Include file is improperly formatted!');
  31.             return false;
  32.         }
  33.         if (parseUInt(regexResults[1]) != jjCRC32(crcCheck)) {
  34.             jjDebug('MLLE::Setup: Include file has been damaged!');
  35.             return false;
  36.         }
  37.        
  38.         jjSTREAM level(jjLevelFileName);
  39.         if (level.isEmpty()) {
  40.             jjDebug('MLLE::Setup: Error reading "' + jjLevelFileName + '"!');
  41.             return false;
  42.         }
  43.         level.discard(230);
  44.         array<uint> CompressedDataSizes(4, 0);
  45.         for (uint i = 0; i < CompressedDataSizes.length; ++i) {
  46.             level.pop(CompressedDataSizes[i]);
  47.             level.discard(4);
  48.         }
  49.         for (uint i = 0; i < CompressedDataSizes.length; ++i)
  50.             level.discard(CompressedDataSizes[i]);
  51.  
  52.         if (level.getSize() < 20) {
  53.             jjDebug('MLLE::Setup: Level file does not contain any additional data!');
  54.             return false;
  55.         }
  56.         string magic;
  57.         level.get(magic, 'MLLE'.length);
  58.         if (magic != 'MLLE') {
  59.             jjDebug('MLLE::Setup: Level was not saved by MLLE!');
  60.             return false;
  61.         }
  62.         uint levelDataVersion;
  63.         level.pop(levelDataVersion);
  64.         if (levelDataVersion != 0x106) {
  65.             jjDebug('MLLE::Setup: Level\'s Data5 section was saved in a different version of MLLE than this script!');
  66.             return false;
  67.         }
  68.  
  69.         uint csize, usize;
  70.         level.pop(csize); level.pop(usize);
  71.         jjSTREAM data5;
  72.         if (!jjZlibUncompress(level, data5, usize)) {
  73.             jjDebug('MLLE::Setup: Error during ZLIB uncompression!');
  74.             return false;
  75.         }
  76.  
  77.         bool pbool; uint8 pbyte; int8 pchar; int16 pshort; float pfloat; int pint; uint puint, puint2;
  78.         data5.pop(pbool); jjIsSnowing = pbool;
  79.         data5.pop(pbool); jjIsSnowingOutdoorsOnly = pbool;
  80.         data5.pop(pbyte); jjSnowingIntensity = pbyte;
  81.         data5.pop(pbyte); jjSnowingType = SNOWING::Type(pbyte);
  82.  
  83.         if (jjIsSnowing) {
  84.             if (jjSnowingType == SNOWING::SNOW && jjAnimSets[ANIM::SNOW] == 0)
  85.                 jjAnimSets[ANIM::SNOW].load();
  86.             else if (jjSnowingType == SNOWING::LEAF && jjAnimSets[ANIM::PLUS_SCENERY] == 0)
  87.                 jjAnimSets[ANIM::PLUS_SCENERY].load();
  88.         }
  89.  
  90.         data5.pop(pbool); jjWarpsTransmuteCoins = pbool;
  91.         data5.pop(pbool); jjDelayGeneratedCrateOrigins = pbool;
  92.         data5.pop(pint);  jjEcho = pint;
  93.         data5.pop(puint); jjSetDarknessColor(_colorFromArgb(puint));
  94.         data5.pop(pfloat);jjWaterChangeSpeed = pfloat;
  95.         data5.pop(pbyte); jjWaterInteraction = WATERINTERACTION::WaterInteraction(pbyte);
  96.         data5.pop(pint);  jjWaterLayer = pint;
  97.         data5.pop(pbyte); jjWaterLighting = WATERLIGHT::wl(pbyte);
  98.         data5.pop(pfloat); if (int(pfloat) < jjLayerHeight[4] * 32) jjSetWaterLevel(pfloat, true);
  99.         data5.pop(puint); data5.pop(puint2); jjSetWaterGradient(_colorFromArgb(puint), _colorFromArgb(puint2));
  100.  
  101.         data5.pop(pbool); if (pbool) {
  102.             _readPalette(data5, palette);
  103.             palette.apply();
  104.             data5.pop(pbool);
  105.         }
  106.  
  107.         data5.pop(pbyte);
  108.         array<uint8> mappingIndices(pbyte);
  109.         puint = 0;
  110.         while (pbyte-- != 0) {
  111.             jjPAL extra;
  112.             string paletteName = _read7BitEncodedStringFromStream(data5);
  113.             _readPalette(data5, extra);
  114.             int index = jjSpriteModeFirstFreeMapping();
  115.             if (index < 0) {
  116.                 jjDebug('MLLE::Setup: Not enough room for additional palette ' + paletteName);
  117.             } else {
  118.                 mappingIndices[puint++] = uint8(index);
  119.                 _palettes.set(paletteName, uint8(index));
  120.                 array<uint8> indexMapping(256);
  121.                 for (uint i = 0; i < 256; ++i)
  122.                     indexMapping[i] = jjPalette.findNearestColor(extra.color[i]);
  123.                 jjSpriteModeSetMapping(index, indexMapping, extra);
  124.             }
  125.         }
  126.  
  127.         _recolorAnimationIf(data5, ANIM::PINBALL, 0, 4);
  128.         _recolorAnimationIf(data5, ANIM::PINBALL, 2, 4);
  129.         _recolorAnimationIf(data5, ANIM::CARROTPOLE, 0, 1);
  130.         _recolorAnimationIf(data5, ANIM::DIAMPOLE, 0, 1);
  131.         _recolorAnimationIf(data5, ANIM::PINBALL, 4, 8);
  132.         _recolorAnimationIf(data5, ANIM::JUNGLEPOLE, 0, 1);
  133.         _recolorAnimationIf(data5, ANIM::PLUS_SCENERY, 0, 17);
  134.         _recolorAnimationIf(data5, ANIM::PSYCHPOLE, 0, 1);
  135.         _recolorAnimationIf(data5, ANIM::SMALTREE, 0, 1);
  136.         _recolorAnimationIf(data5, ANIM::SNOW, 0, 8);
  137.         _recolorAnimationIf(data5, ANIM::COMMON, 2, 18);
  138.         _recolorAnimationIf(data5, ANIM::BOLLPLAT, 0, 2);
  139.         _recolorAnimationIf(data5, ANIM::FRUITPLAT, 0, 2);
  140.         _recolorAnimationIf(data5, ANIM::GRASSPLAT, 0, 2);
  141.         _recolorAnimationIf(data5, ANIM::PINKPLAT, 0, 2);
  142.         _recolorAnimationIf(data5, ANIM::SONICPLAT, 0, 2);
  143.         _recolorAnimationIf(data5, ANIM::SPIKEPLAT, 0, 2);
  144.         _recolorAnimationIf(data5, ANIM::SPIKEBOLL, 0, 2);
  145.         _recolorAnimationIf(data5, ANIM::SPIKEBOLL3D, 0, 2);
  146.         _recolorAnimationIf(data5, ANIM::VINE, 1, 1);
  147.  
  148.         data5.pop(pbyte);
  149.         for (uint i = 0; i < pbyte; ++i) {
  150.             string tilesetFilename = _read7BitEncodedStringFromStream(data5);
  151.             uint16 tileStart, tileCount;
  152.             data5.pop(tileStart); data5.pop(tileCount);
  153.             array<uint8>@ colors = null;
  154.             data5.pop(pbool); if (pbool) {
  155.                 @colors = array<uint8>(256);
  156.                 for (uint j = 0; j < 256; ++j)
  157.                     data5.pop(colors[j]);
  158.             }
  159.             if (!jjTilesFromTileset(tilesetFilename, tileStart, tileCount, colors)) {
  160.                 jjDebug('MLLE::Setup: Error reading "' + tilesetFilename + '"!');
  161.                 return false;
  162.             }
  163.         }
  164.         if (pbyte != 0) {
  165.             array<uint> layersIDsWithTileMaps;
  166.             for (uint i = 1; i <= 8; ++i)
  167.                 if (jjLayers[i].hasTileMap)
  168.                     layersIDsWithTileMaps.insertLast(i);
  169.             if (jjLayersFromLevel(jjLevelFileName, layersIDsWithTileMaps).length == 0) {
  170.                 jjDebug('MLLE::Setup: Error reading "' + jjLevelFileName + '"!');
  171.             }
  172.         }
  173.  
  174.         array<jjLAYER@> newLayerOrder, nonDefaultLayers;
  175.         data5.pop(puint);
  176.         for (uint i = 8; i < puint; i += 8) {
  177.             array<uint> layerIDsToGrab;
  178.             for (uint j = i; j < puint && j < i + 8; ++j) {
  179.                 layerIDsToGrab.insertLast((j & 7) + 1);
  180.             }
  181.             const string extraLayersFilename = jjLevelFileName.substr(0, jjLevelFileName.length() - 4) + '-MLLE-Data-' + (i/8) + '.j2l';
  182.             array<jjLAYER@> extraLayers = jjLayersFromLevel(extraLayersFilename, layerIDsToGrab);
  183.             if (extraLayers.length == 0) {
  184.                 jjDebug('MLLE::Setup: Error reading "' + extraLayersFilename + '"!');
  185.                 return false;
  186.             }
  187.             for (uint j = 0; j < extraLayers.length(); ++j)
  188.                 nonDefaultLayers.insertLast(extraLayers[j]);
  189.         }
  190.         uint nextNonDefaultLayerID = 0;
  191.         for (uint i = 0; i < puint; ++i) {
  192.             data5.pop(pchar);
  193.             jjLAYER@ layer;
  194.             if (pchar >= 0)
  195.                 @layer = jjLayers[pchar + 1];
  196.             else
  197.                 @layer = nonDefaultLayers[nextNonDefaultLayerID++];
  198.             string layerName = _read7BitEncodedStringFromStream(data5);
  199.             _layers.set(layerName, @layer);
  200.             data5.pop(pbool);
  201.             if (layer.hasTileMap)
  202.                 layer.hasTiles = !pbool;
  203.             data5.pop(pbyte);
  204.             layer.spriteMode = SPRITE::Mode(pbyte);
  205.             data5.pop(pbyte);
  206.             layer.spriteParam = (layer.spriteMode == SPRITE::MAPPING || layer.spriteMode == SPRITE::TRANSLUCENTMAPPING) ? mappingIndices[pbyte] : pbyte;
  207.             data5.pop(pint);
  208.             layer.rotationAngle = pint;
  209.             data5.pop(pint);
  210.             layer.rotationRadiusMultiplier = pint;
  211.             data5.pop(pbyte);
  212.             layer.xSpeedModel = LAYERSPEEDMODEL::LayerSpeedModel(pbyte);
  213.             data5.pop(pbyte);
  214.             layer.ySpeedModel = LAYERSPEEDMODEL::LayerSpeedModel(pbyte);
  215.             data5.pop(pbyte);
  216.             layer.textureSurface = SURFACE::Surface(pbyte);
  217.             data5.pop(pbyte);
  218.             layer.reflection.tintColor = pbyte;
  219.             data5.pop(pfloat);
  220.             layer.reflection.fadePositionX = pfloat;
  221.             data5.pop(pfloat);
  222.             layer.reflection.top = pfloat;
  223.             data5.pop(pfloat);
  224.             layer.xInnerSpeed = pfloat;
  225.             data5.pop(pfloat);
  226.             layer.yInnerSpeed = pfloat;
  227.             data5.pop(pfloat);
  228.             layer.xInnerAutoSpeed = pfloat;
  229.             data5.pop(pfloat);
  230.             layer.yInnerAutoSpeed = pfloat;
  231.             data5.pop(pchar);
  232.             if (pchar >= 0)
  233.                 layer.texture = TEXTURE::Texture(pchar);
  234.             else {
  235.                 jjPIXELMAP texture(256, 256);
  236.                 for (uint y = 0; y < 256; ++y)
  237.                     for (uint x = 0; x < 256; ++x)
  238.                         data5.pop(texture[x,y]);
  239.                 texture.makeTexture(layer);
  240.             }
  241.             newLayerOrder.insertLast(layer);
  242.         }
  243.         jjLayerOrderSet(newLayerOrder);
  244.  
  245.         uint16 numberOfObjects; data5.pop(numberOfObjects);
  246.         while (numberOfObjects-- != 0) {
  247.             uint16 tileID; data5.pop(tileID);
  248.             jjPIXELMAP tile(32, 32);
  249.             for (int y = 0; y < 32; ++y)
  250.                 for (int x = 0; x < 32; ++x)
  251.                     data5.pop(tile[x,y]);
  252.             tile.save(tileID, true);
  253.         }
  254.         data5.pop(numberOfObjects);
  255.         while (numberOfObjects-- != 0) {
  256.             uint16 tileID; data5.pop(tileID);
  257.             jjMASKMAP tile;
  258.             for (int y = 0; y < 32; ++y)
  259.                 for (int x = 0; x < 32; ++x)
  260.                     data5.pop(tile[x,y]);
  261.             tile.save(tileID, true);
  262.         }
  263.  
  264.         data5.pop(pshort);
  265.         for (uint i = 1; i <= 9; ++i) {
  266.             jjWEAPON@ weapon = jjWeapons[i];
  267.             data5.pop(pbool);
  268.             data5.pop(pint); weapon.maximum = pint;
  269.             data5.pop(pbyte); weapon.comesFromBirds = pbyte != 0; weapon.comesFromBirdsPowerup = pbyte == 2;
  270.             data5.pop(pbyte); weapon.comesFromGunCrates = pbyte != 0;
  271.             data5.pop(pbyte); weapon.gemsLost = pbyte;
  272.             data5.pop(pbyte); weapon.gemsLostPowerup = pbyte;
  273.             data5.pop(pbyte); weapon.infinite = pbyte & 1 == 1; weapon.replenishes = pbyte & 2 == 2;
  274.             uint8 ammoCrateEventID = 0;
  275.             if (i >= 7) {
  276.                 data5.pop(ammoCrateEventID);
  277.                 if (ammoCrateEventID > 32) {
  278.                     jjOBJ@ preset = jjObjectPresets[ammoCrateEventID];
  279.                     preset.behavior = AmmoCrate(ammoCrateEventID);
  280.                     preset.playerHandling = HANDLING::SPECIAL;
  281.                     preset.scriptedCollisions = false;
  282.                     preset.direction = 1;
  283.                     preset.energy = 1;
  284.                     preset.curFrame = jjAnimations[preset.curAnim = (i == 7) ? (jjAnimSets[ANIM::PICKUPS] + 59) : (jjAnimSets[ANIM::PLUS_COMMON] + i - 8)] + (preset.frameID = 0);
  285.                     preset.killAnim = jjAnimSets[ANIM::AMMO] + 71;
  286.                     preset.eventID = OBJECT::ICEAMMO15;
  287.                     preset.var[2] = 31 + i;
  288.                     preset.var[3] = i - 1;
  289.                     preset.points = 300;
  290.                 }
  291.             }
  292.             if (i == 8) {
  293.                 data5.pop(pbyte);
  294.                 if (pbyte == 0)
  295.                     weapon.spread = SPREAD::GUN8;
  296.                 else if (pbyte == 1)
  297.                     weapon.spread = SPREAD::PEPPERSPRAY;
  298.                 else if (pbyte >= 2)
  299.                     weapon.spread = SPREAD::NORMAL;
  300.                 if (pbyte == 2)
  301.                     weapon.gradualAim = false;
  302.             }
  303.         }
  304.  
  305.         data5.pop(numberOfObjects);
  306.         if (numberOfObjects != 0) {
  307.             if (jjGameConnection != GAME::LOCAL)
  308.                 jjObjectPresets[254].behavior = _replaceMe;
  309.             else
  310.                 jjObjectPresets[254].behavior = BEHAVIOR::INACTIVE;
  311.             @_offGridObjects = array<_offgridObject>();
  312.             array<uint8> animSetsToLoad(256, 0);
  313.             animSetsToLoad[OBJECT::BONUSPOST] = ANIM::BONUS;
  314.             animSetsToLoad[OBJECT::SWINGINGVINE] = ANIM::VINE;
  315.             animSetsToLoad[OBJECT::TUFTURT] = ANIM::TUFTUR;
  316.             animSetsToLoad[OBJECT::LABRAT] = ANIM::LABRAT;
  317.             animSetsToLoad[OBJECT::LIZARD] = ANIM::LIZARD;
  318.             animSetsToLoad[OBJECT::FLOATLIZARD] = ANIM::LIZARD;
  319.             animSetsToLoad[OBJECT::SUCKER] = ANIM::SUCKER;
  320.             animSetsToLoad[OBJECT::CATERPILLAR] = ANIM::CATERPIL;
  321.             animSetsToLoad[OBJECT::SMOKERING] = ANIM::CATERPIL;
  322.             animSetsToLoad[OBJECT::CHESHIRE1] = ANIM::CAT;
  323.             animSetsToLoad[OBJECT::CHESHIRE2] = ANIM::CAT2;
  324.             animSetsToLoad[OBJECT::HATTER] = ANIM::HATTER;
  325.             animSetsToLoad[OBJECT::SKELETON] = ANIM::SKELETON;
  326.             animSetsToLoad[OBJECT::DOGGYDOGG] = ANIM::DOG;
  327.             animSetsToLoad[OBJECT::NORMTURTLE] = ANIM::TURTLE;
  328.             animSetsToLoad[OBJECT::TURTLESHELL] = ANIM::TURTLE;
  329.             animSetsToLoad[OBJECT::DEMON] = ANIM::DEMON;
  330.             animSetsToLoad[OBJECT::STEAM] = ANIM::STEAM;
  331.             animSetsToLoad[OBJECT::ROTATINGROCK] = ANIM::ROCK;
  332.             animSetsToLoad[OBJECT::HELMUT] = ANIM::HELMUT;
  333.             animSetsToLoad[OBJECT::BILSY] = ANIM::BILSBOSS;
  334.             animSetsToLoad[OBJECT::BAT] = ANIM::BAT;
  335.             animSetsToLoad[OBJECT::BEE] = ANIM::BUMBEE;
  336.             animSetsToLoad[OBJECT::DRAGONFLY] = ANIM::DRAGFLY;
  337.             animSetsToLoad[OBJECT::FATCHICK] = ANIM::FATCHK;
  338.             animSetsToLoad[OBJECT::FENCER] = ANIM::FENCER;
  339.             animSetsToLoad[OBJECT::FISH] = ANIM::FISH;
  340.             animSetsToLoad[OBJECT::MOTH] = ANIM::MOTH;
  341.             animSetsToLoad[OBJECT::RAPIER] = ANIM::RAPIER;
  342.             animSetsToLoad[OBJECT::SPARK] = ANIM::SPARK;
  343.             animSetsToLoad[OBJECT::LEFTPADDLE] = ANIM::PINBALL;
  344.             animSetsToLoad[OBJECT::RIGHTPADDLE] = ANIM::PINBALL;
  345.             animSetsToLoad[OBJECT::FIVEHUNDREDBUMP] = ANIM::PINBALL;
  346.             animSetsToLoad[OBJECT::CARROTBUMP] = ANIM::PINBALL;
  347.             animSetsToLoad[OBJECT::QUEEN] = ANIM::QUEEN;
  348.             animSetsToLoad[OBJECT::FLOATSUCKER] = ANIM::SUCKER;
  349.             animSetsToLoad[OBJECT::BRIDGE] = ANIM::BRIDGE;
  350.             animSetsToLoad[OBJECT::MONKEY] = ANIM::MONKEY;
  351.             animSetsToLoad[OBJECT::STANDMONKEY] = ANIM::MONKEY;
  352.             animSetsToLoad[OBJECT::RAVEN] = ANIM::RAVEN;
  353.             animSetsToLoad[OBJECT::TUBETURTLE] = ANIM::TUBETURT;
  354.             animSetsToLoad[OBJECT::SMALLTREE] = ANIM::SMALTREE;
  355.             animSetsToLoad[OBJECT::DIAMONDUSPOLE] = ANIM::DIAMPOLE;
  356.             animSetsToLoad[OBJECT::PSYCHPOLE] = ANIM::PSYCHPOLE;
  357.             animSetsToLoad[OBJECT::CARROTUSPOLE] = ANIM::CARROTPOLE;
  358.             animSetsToLoad[OBJECT::JUNGLEPOLE] = ANIM::JUNGLEPOLE;
  359.             animSetsToLoad[OBJECT::UTERUS] = ANIM::UTERUS;
  360.             animSetsToLoad[OBJECT::UTERUSSPIKEBALL] = ANIM::UTERUS;
  361.             animSetsToLoad[OBJECT::CRAB] = ANIM::UTERUS;
  362.             animSetsToLoad[OBJECT::ROBOT] = ANIM::ROBOT;
  363.             animSetsToLoad[OBJECT::DEVANROBOT] = ANIM::DEVAN;
  364.             animSetsToLoad[OBJECT::FRUITPLATFORM] = ANIM::FRUITPLAT;
  365.             animSetsToLoad[OBJECT::BOLLPLATFORM] = ANIM::BOLLPLAT;
  366.             animSetsToLoad[OBJECT::GRASSPLATFORM] = ANIM::GRASSPLAT;
  367.             animSetsToLoad[OBJECT::PINKPLATFORM] = ANIM::PINKPLAT;
  368.             animSetsToLoad[OBJECT::SONICPLATFORM] = ANIM::SONICPLAT;
  369.             animSetsToLoad[OBJECT::SPIKEPLATFORM] = ANIM::SPIKEPLAT;
  370.             animSetsToLoad[OBJECT::SPIKEBOLL] = ANIM::SPIKEBOLL;
  371.             animSetsToLoad[OBJECT::SPIKEBOLL3D] = ANIM::SPIKEBOLL3D;
  372.             animSetsToLoad[OBJECT::EVA] = ANIM::EVA;
  373.             animSetsToLoad[OBJECT::WITCH] = ANIM::WITCH;
  374.             animSetsToLoad[OBJECT::ROCKETTURTLE] = ANIM::ROCKTURT;
  375.             animSetsToLoad[OBJECT::BUBBA] = ANIM::BUBBA;
  376.             animSetsToLoad[OBJECT::DEVILDEVAN] = ANIM::DEVILDEVAN;
  377.             animSetsToLoad[OBJECT::TUFBOSS] = ANIM::TUFBOSS;
  378.             animSetsToLoad[OBJECT::BIGROCK] = ANIM::BIGROCK;
  379.             animSetsToLoad[OBJECT::BIGBOX] = ANIM::BIGBOX;
  380.             animSetsToLoad[OBJECT::BOLLY] = ANIM::SONCSHIP;
  381.             animSetsToLoad[OBJECT::BUTTERFLY] = ANIM::BUTTERFLY;
  382.             animSetsToLoad[OBJECT::BEEBOY] = ANIM::BEEBOY;
  383.             animSetsToLoad[OBJECT::XMASNORMTURTLE] = ANIM::XTURTLE;
  384.             animSetsToLoad[OBJECT::XMASLIZARD] = ANIM::XLIZARD;
  385.             animSetsToLoad[OBJECT::XMASFLOATLIZARD] = ANIM::XLIZARD;
  386.             animSetsToLoad[OBJECT::XMASBILSY] = ANIM::XBILSY;
  387.             animSetsToLoad[OBJECT::CAT] = ANIM::ZDOG;
  388.             animSetsToLoad[OBJECT::PACMANGHOST] = ANIM::ZSPARK;
  389.             do {
  390.                 uint16 xPos; data5.pop(xPos);
  391.                 uint16 yPos; data5.pop(yPos);
  392.                 int32 params; data5.pop(params);
  393.                 _offGridObjects.insertLast(_offgridObject(xPos, yPos, params));
  394.                 uint8 eventID = params;
  395.                 if (eventID == OBJECT::GENERATOR) eventID = params >> 12;
  396.                 if (animSetsToLoad[eventID] != 0) {
  397.                     jjOBJ@ preset = jjObjectPresets[eventID];
  398.                     if (preset.curAnim < 100) {
  399.                         preset.curFrame = jjAnimations[preset.determineCurAnim(animSetsToLoad[eventID], preset.curAnim)] + preset.frameID;
  400.                         if ((eventID >= OBJECT::FRUITPLATFORM && eventID <= OBJECT::SPIKEBOLL3D) || eventID == OBJECT::WITCH)
  401.                             preset.killAnim += jjAnimSets[animSetsToLoad[eventID]];
  402.                         else if (eventID == OBJECT::CATERPILLAR && jjObjectPresets[OBJECT::SMOKERING].curAnim < 100)
  403.                             jjObjectPresets[OBJECT::SMOKERING].determineCurAnim(ANIM::CATERPIL, jjObjectPresets[OBJECT::SMOKERING].curAnim);
  404.                     }
  405.                     animSetsToLoad[eventID] = 0;
  406.                 }
  407.             } while (--numberOfObjects != 0);
  408.         }
  409.  
  410.         if (!data5.isEmpty()) {
  411.             jjDebug('MLLE::Setup: Warning, Data5 longer than expected');
  412.         }
  413.        
  414.         return true;
  415.     }
  416.  
  417.     jjLAYER@ GetLayer(const string &in name) {
  418.         jjLAYER@ handle = null;
  419.         _layers.get(name, @handle);
  420.         return handle;
  421.     }
  422.     uint8 GetPaletteMappingID(const string &in name) {
  423.         uint8 mappingID;
  424.         _palettes.get(name, mappingID);
  425.         return mappingID;
  426.     }
  427.     jjPAL@ GetPalette(const string &in name) {
  428.         if (name == 'Level Palette')
  429.             return Palette;
  430.         return jjSpriteModeGetColorMapping(GetPaletteMappingID(name));
  431.     }
  432.  
  433.     void ReapplyPalette() {
  434.         Palette.apply();
  435.     }
  436.  
  437.     class AmmoCrate : jjBEHAVIORINTERFACE {
  438.         uint8 realEventID;
  439.         AmmoCrate(uint8 r) { realEventID = r; }
  440.         bool onIsSolid(jjOBJ@) { return true; }
  441.         void onBehave(jjOBJ@ obj) {
  442.             if (obj.state == STATE::DEACTIVATE)
  443.                 obj.eventID = realEventID;
  444.             obj.behave(BEHAVIOR::AMMO15);
  445.         }
  446.     }
  447.  
  448.     void SpawnOffgrids() {
  449.         if (jjGameConnection == GAME::LOCAL) {
  450.             SpawnOffgridsLocal();
  451.             for (int y = 0; y < jjLayerHeight[4]; ++y)
  452.             for (int x = 0; x < jjLayerWidth[4]; ++x) {
  453.                 const int ev = jjParameterGet(x,y, -12,32);
  454.                 if (ev == 0)
  455.                     return;
  456.                 else if (ev == int(0xFFFFF3FE))
  457.                     jjParameterSet(x,y, -12,32, 0);
  458.             }
  459.         }
  460.     }
  461.     void SpawnOffgridsLocal() {
  462.         for (uint i = 0; i < _offGridObjects.length; ++i)
  463.             _spawnOffgrid(i);
  464.     }
  465.     class _offgridObject {
  466.         float xPos, yPos;
  467.         int32 params;
  468.         _offgridObject() {}
  469.         _offgridObject(uint16 x, uint16 y, int32 p) { xPos = x; yPos = y; params = p; }
  470.     }
  471.     void _spawnOffgrid(uint i) {
  472.         const _offgridObject@ og = _offGridObjects[i];
  473.         const int difficulty = og.params & 0x300;
  474.         if (difficulty != 0 && (jjGameMode == GAME::SP || jjGameMode == GAME::COOP || jjGameConnection == GAME::LOCAL)) {
  475.             if (difficulty == 0x100) {
  476.                 if (jjDifficulty > 0)
  477.                     return;
  478.             } else if (difficulty == 0x200) {
  479.                 if (jjDifficulty < 2)
  480.                     return;
  481.             } else {
  482.                 if (jjGameConnection == GAME::LOCAL && jjLocalPlayerCount == 1)
  483.                     return;
  484.             }
  485.         }
  486.         const uint xTile = uint(og.xPos) >> 5, yTile = uint(og.yPos) >> 5;
  487.         const int realEvent = jjParameterGet(xTile,yTile, -12,32);
  488.         jjParameterSet(xTile,yTile, -12,32, og.params);
  489.         jjOBJ@ obj = jjObjects[jjAddObject(og.params, og.xPos, og.yPos, 0, CREATOR::LEVEL)];
  490.         jjParameterSet(xTile,yTile, -12,32, realEvent);
  491.         if (jjGameConnection == GAME::LOCAL) {
  492.             obj.deactivates = false;
  493.             obj.creatorID = 1;
  494.         }
  495.     }
  496.     uint _replaceMeIndex = 0;
  497.     void _replaceMe(jjOBJ@ obj) {
  498.         jjParameterSet(uint(obj.xOrg)>>5, uint(obj.yOrg)>>5, -12,32, 0);
  499.         obj.delete();
  500.         _spawnOffgrid(_replaceMeIndex++);
  501.     }
  502.  
  503.     jjPALCOLOR _colorFromArgb(uint Argb) {
  504.         return jjPALCOLOR(Argb >> 16, Argb >> 8, Argb >> 0);
  505.     }
  506.  
  507.     void _readPalette(jjSTREAM& stream, jjPAL& palette) {
  508.         for (uint i = 0; i < 256; ++i) {
  509.             stream.pop(palette.color[i].red);
  510.             stream.pop(palette.color[i].green);
  511.             stream.pop(palette.color[i].blue);
  512.         }
  513.     }
  514.  
  515.     uint _read7BitEncodedUintFromStream(jjSTREAM& stream) {
  516.         uint result = 0;
  517.         while (true) {
  518.             uint8 byteRead; stream.pop(byteRead);
  519.             result |= (byteRead & 0x7F);
  520.             if (byteRead >= 0x80)
  521.                 result <<= 7;
  522.             else
  523.                 break;
  524.         }
  525.         return result;
  526.     }
  527.     string _read7BitEncodedStringFromStream(jjSTREAM& stream) {
  528.         string result;
  529.         stream.get(result, _read7BitEncodedUintFromStream(stream));
  530.         return result;
  531.     }
  532.  
  533.     void _recolorAnimationIf(jjSTREAM& stream, ANIM::Set set, uint animID, uint frameCount) {
  534.         bool pbool; stream.pop(pbool); if (!pbool) return;
  535.  
  536.         if (jjAnimSets[set] == 0)
  537.             jjAnimSets[set].load();
  538.         const uint firstFrameID = jjAnimations[jjAnimSets[set] + animID];
  539.         array<uint8> colors(256);
  540.         for (uint i = 0; i < 256; ++i)
  541.             stream.pop(colors[i]);
  542.         for (uint i = 0; i < frameCount; ++i) {
  543.             jjANIMFRAME@ frame = jjAnimFrames[firstFrameID + i];
  544.             jjPIXELMAP(frame).recolor(colors).save(frame);
  545.         }
  546.     }
  547. }