Downloads containing DM-Rift.j2as

Downloads
Name Author Game Mode Rating
JJ2+ Only: Rift blurredd Battle N/A Download file

File preview

  1. #pragma require "Heaven.j2t"
  2. #pragma require "DM-Rift-Extra.j2l"
  3.  
  4. void onLevelLoad() {
  5.         loadExtraLayers();
  6.         loadRiftParts();
  7.  
  8.         for (int eventID = OBJECT::BLASTERBULLET; eventID <= OBJECT::BULLET; ++eventID) {
  9.                 jjObjectPresets[eventID].behavior = BulletWrapper(jjObjectPresets[eventID].behavior);
  10.         }
  11.  
  12.         Rift(jjObjectPresets[OBJECT::APPLE]);
  13. }
  14.  
  15. class BulletWrapper : jjBEHAVIORINTERFACE {
  16.         private jjBEHAVIOR nativeBehavior;
  17.         BulletWrapper(const jjBEHAVIOR &in nb) {
  18.                 nativeBehavior = nb;
  19.         }
  20.  
  21.         void onBehave(jjOBJ@ obj) {
  22.                 obj.behave(nativeBehavior);
  23.  
  24.                 float xPixelLimit = 1;
  25.                 if (obj.xPos > (jjLayers[4].width) * 32 - (xPixelLimit + 1) && obj.xSpeed > 0) {
  26.                         obj.xPos = xPixelLimit;
  27.                 } else if (obj.xPos < xPixelLimit && obj.xSpeed < 0) {
  28.                         obj.xPos = jjLayers[4].width * 32 + (xPixelLimit + 1);
  29.                 }
  30.         }
  31.         bool onIsRFBullet(jjOBJ@ obj) {
  32.                 return nativeBehavior == BEHAVIOR::RFBULLET;
  33.         }
  34. }
  35.  
  36. void loadExtraLayers() {
  37.         const int oldTileCount = jjTileCount;
  38.         if (!jjTilesFromTileset("Heaven.j2t", 520, 100)) { //first tileID
  39.                 jjAlert("|ERROR: Heaven.j2t not found!", false, STRING::MEDIUM);
  40.                 return;
  41.         }
  42.  
  43.         array<jjLAYER@> heavenLayers = jjLayersFromLevel(
  44.                 "DM-Rift-Extra.j2l",
  45.                 array<uint> = {6,7}, //Which (1-indexed) layers to copy
  46.                 oldTileCount - 520
  47.         );
  48.         if (heavenLayers.length == 0) {
  49.                 jjAlert("|ERROR: Heaven.j2l not found!", false, STRING::MEDIUM);
  50.                 return;
  51.         }
  52.  
  53.         // This loop edited in by SE to replace spriteMode usage for a major efficiency boost.
  54.         for (int tileID = 0; tileID < 100; tileID++) {
  55.                 jjTileType[oldTileCount + tileID] = 1;
  56.         }
  57.  
  58.         for (uint layerID = 0; layerID < heavenLayers.length; ++layerID) {
  59.                 heavenLayers[layerID].yOffset = 10 * 32;
  60.                 heavenLayers[layerID].limitVisibleRegion = false;
  61.                 //heavenLayers[layerID].spriteMode = SPRITE::TRANSLUCENTTILE;
  62.         }
  63.  
  64.         jjLAYER@ blackLayer = jjLAYER(4, jjLayers[6].height);
  65.         blackLayer.generateSettableTileArea();
  66.         blackLayer.xSpeed = jjLayers[6].xSpeed;
  67.         blackLayer.ySpeed = jjLayers[6].ySpeed;
  68.         blackLayer.tileWidth = true;
  69.         for (int y = 70; y < blackLayer.height; y++) {
  70.                 for (int x = 0; x < blackLayer.width; x++) {
  71.                         blackLayer.tileSet(x, y, 404); //black tile
  72.                 }
  73.         }
  74.  
  75.         array<jjLAYER@> extraBuildingLayers;
  76.         addBuilderLayers( 0, 4, 8, extraBuildingLayers);
  77.         addBuilderLayers(16, 4, 12, extraBuildingLayers);
  78.         addBuilderLayers(36, 4, 10, extraBuildingLayers);
  79.         addBuilderLayers(48, 4, 8, extraBuildingLayers);
  80.         addBuilderLayers(64, 4, 12, extraBuildingLayers);
  81.         addBuilderLayers(86, 4, 10, extraBuildingLayers);
  82.         addBuilderLayers(102, 4, 8, extraBuildingLayers);
  83.         //recreate first two to imitate tiled width
  84.         addBuilderLayers(120, 4, 8, extraBuildingLayers);
  85.         addBuilderLayers(136, 4, 12, extraBuildingLayers);
  86.         //recreate last to imitate tiled width
  87.         addBuilderLayers(-18, 4, 8, extraBuildingLayers);
  88.  
  89.         jjTexturedBGTexture = TEXTURE::WISETYNESS;
  90.         jjSetFadeColors(70, 64, 66); //above, but a bit darker
  91.         jjUseLayer8Speeds = true;
  92.         jjLayers[7].spriteMode = SPRITE::TRANSLUCENTTILE; //barely visible moon
  93.  
  94.         array<jjLAYER@> layers;
  95.         layers.insertLast(jjLayers[1]);
  96.         layers.insertLast(jjLayers[2]);
  97.         layers.insertLast(jjLayers[3]);
  98.         layers.insertLast(jjLayers[4]);
  99.         layers.insertLast(jjLayers[5]);
  100.         layers.insertLast(jjLayers[6]);
  101.         layers.insertLast(blackLayer);
  102.  
  103.         layers.insertAt(layers.length(), extraBuildingLayers);
  104.  
  105.         layers.insertLast(heavenLayers[0]);
  106.         layers.insertLast(heavenLayers[1]);
  107.         layers.insertLast(jjLayers[7]);
  108.         layers.insertLast(jjLayers[8]);
  109.         jjLayerOrderSet(layers);
  110. }
  111.  
  112. void addBuilderLayers(int xTile, int yStart, int buildingWidth, array<jjLAYER@>@ layers) {
  113.         int layerWidth = (buildingWidth + 3) & ~0x03;
  114.  
  115.         int xStart = 0;
  116.  
  117.         jjLAYER@ baseLayer = jjLAYER(layerWidth, 100);
  118.         baseLayer.generateSettableTileArea();
  119.         baseLayer.xSpeed = 0.75f;
  120.         baseLayer.ySpeed = 0.75f;
  121.         baseLayer.xOffset = 32 * (-1 - (xTile - buildingWidth / 2));
  122.         addBuilding(baseLayer, xStart, yStart, buildingWidth);
  123.  
  124.         layers.insertLast(baseLayer);
  125.  
  126.         int i = 10;
  127.         jjLAYER@ layer = jjLAYER(baseLayer);
  128.         layer.spriteMode = SPRITE::SINGLECOLOR;
  129.         layer.spriteParam = 200;
  130.         float speedOffset = (i + 1) / 256.0;
  131.         float offset = (i + 1) * ((5.375 * xTile) - (4 * buildingWidth) + 16) / 32;
  132.         layer.xSpeed -= speedOffset;
  133.         layer.xOffset += offset;
  134.         layers.insertLast(layer);
  135. }
  136.  
  137. void addBuilding(jjLAYER@ layer, int xStart, int yStart, int width) {
  138.         uint16 topLeft   = 640;
  139.         uint16 topMiddle = 641;
  140.         uint16 topRight  = 642;
  141.         uint16 left   = 650;
  142.         uint16 middle = 671; //light on
  143.         uint16 right  = 652;
  144.  
  145.         int xEnd = xStart + width;
  146.         int yEnd = layer.height;
  147.  
  148.         for (int x = xStart; x < xEnd; x++) {
  149.                 for (int y = yStart; y < yEnd; y++) {
  150.                         uint16 tileID;
  151.                         if (y == yStart) {
  152.                                 if (x == xStart) {
  153.                                         tileID = topLeft;
  154.                                 } else if (x == xEnd - 1) {
  155.                                         tileID = topRight;
  156.                                 } else {
  157.                                         tileID = topMiddle;
  158.                                 }
  159.                         } else if (x == xStart) {
  160.                                 tileID = left;
  161.                         } else if (x == xEnd - 1) {
  162.                                 tileID = right;
  163.                         } else {
  164.                                 tileID = middle;
  165.                         }
  166.                         layer.tileSet(x, y, tileID);
  167.                 }
  168.         }
  169. }
  170.  
  171. int min(int a, int b) {
  172.         return a < b ? a : b;
  173. }
  174.  
  175. void onPlayer(jjPLAYER@ player) {
  176.         float xPixelLimit = 1;
  177.         if (player.xPos > (jjLayers[4].width) * 32 - (xPixelLimit + 1) && player.xSpeed > 0) {
  178.                 player.offsetPosition(int(-(player.xPos - xPixelLimit)), 0);
  179.         } else if (player.xPos < xPixelLimit && player.xSpeed < 0) {
  180.                 player.offsetPosition(int(-(player.xPos - (jjLayers[4].width) * 32 - (xPixelLimit + 1))), 0);
  181.         }
  182. }
  183.  
  184. namespace math {
  185.         int mod(int a, int b) {
  186.                 int r = a % b;
  187.                 return r < 0 ? r + b : r;
  188.         }
  189.         int min(int a, int b) {
  190.                 return a < b ? a : b;
  191.         }
  192.         int max(int a, int b) {
  193.                 return a > b ? a : b;
  194.         }
  195. }
  196.  
  197. array<LineRiftPart@> parts;
  198.  
  199. void loadRiftParts() {
  200.         uint customAnimID = 0;
  201.         uint animCount = 4;
  202.  
  203.         uint frameCount = 64; //must be a power of 2
  204.         array<uint> frameCounts(animCount, frameCount);
  205.         jjANIMSET@ animset = jjAnimSets[ANIM::CUSTOM[customAnimID++]].allocate(frameCounts);
  206.  
  207.         uint curAnim = animset.firstAnim;
  208.  
  209.         //speed, type, amplitude, height
  210.         //{xOffset, segmentHeightShift, segmentMask}
  211.  
  212.         parts.insertLast(LineRiftPart(curAnim++, 1, 0, 4, 4 * 32,
  213.                 array<array<int>> = {
  214.                         {14, 4, 0x1FF},
  215.                         {15, 4, 0xC3},
  216.                         {16, 4, 0x1FF}
  217.                 }
  218.         ));
  219.  
  220.         parts.insertLast(LineRiftPart(curAnim++, 2, -1, 31, 4 * 32,
  221.                 array<array<int>> = {
  222.                         {0, 4, 0x3}
  223.                 }
  224.         ));
  225.  
  226.         parts.insertLast(LineRiftPart(curAnim++, 1, 1, 7, 8 * 32,
  227.                 array<array<int>> = {
  228.                         {2, 3, 0x1}
  229.                 }
  230.         ));
  231.  
  232.         parts.insertLast(LineRiftPart(curAnim++, 0, 0, 10, 8 * 32,
  233.                 array<array<int>> = {
  234.                         {5, 3, 0x1}
  235.                 }
  236.         ));
  237. }
  238.  
  239. class Rift : jjBEHAVIORINTERFACE {
  240.  
  241.         Rift(jjOBJ@ objectPreset) {
  242.                 objectPreset.behavior = this;
  243.                 objectPreset.scriptedCollisions = true;
  244.                 objectPreset.playerHandling = HANDLING::PARTICLE;
  245.                 objectPreset.bulletHandling = HANDLING::IGNOREBULLET;
  246.                 objectPreset.counterEnd = 100;
  247.                 objectPreset.isTarget = false;
  248.                 objectPreset.isFreezable = false;
  249.                 objectPreset.triggersTNT = false;
  250.                 objectPreset.deactivates = false;
  251.                 objectPreset.causesRicochet = false;
  252.                 objectPreset.energy = 0;
  253.                 objectPreset.points = 0;
  254.                 objectPreset.direction = 1;
  255.         }
  256.         void onBehave(jjOBJ@ obj) {
  257.                 switch (obj.state) {
  258.                         case STATE::START:
  259.                                 {
  260.                                         int xPos = int(obj.xPos);
  261.                                         int yStart = int(obj.yPos);
  262.                                         int yEnd = yStart;
  263.                                         while (!jjMaskedPixel(xPos, yStart - 1)) {
  264.                                                 yStart--;
  265.                                         }
  266.                                         while (!jjMaskedPixel(xPos, yEnd)) {
  267.                                                 yEnd++;
  268.                                         }
  269.  
  270.                                         if (yEnd == yStart) {
  271.                                                 yEnd = yStart + 32; //better than nothing
  272.                                         }
  273.  
  274.                                         //adjust one tile up and down:
  275.                                         yStart -= 32;
  276.                                         yEnd += 32;
  277.  
  278.                                         obj.var[0] = yStart;
  279.                                         obj.var[1] = yEnd;
  280.                                 }
  281.  
  282.                                 obj.state = STATE::SLEEP;
  283.                                 break;
  284.                 }
  285.         }
  286.         void onDraw(jjOBJ@ obj) {
  287.                 int yStart = obj.var[0];
  288.                 int yEnd = obj.var[1];
  289.                 for (uint i = 0; i < parts.length; i++) {
  290.                         parts[i].draw(yStart, yEnd);
  291.                 }
  292.         }
  293. }
  294.  
  295. class LineRiftPart {
  296.         uint curAnim;
  297.         uint frameCount;
  298.         int speed;
  299.         array<int> xStarts;
  300.         int height;
  301.  
  302.         LineRiftPart(uint curAnim, int speed, int type, int amplitude, int height, array<array<int>> values) {
  303.                 this.curAnim = curAnim;
  304.                 this.frameCount = jjAnimations[curAnim].frameCount;
  305.                 this.speed = speed;
  306.                 this.height = height;
  307.                 init(type, amplitude, values);
  308.         }
  309.  
  310.         void init(int type, int amplitude, array<array<int>> values) {
  311.                 int xCenter = 0; //could be customized if needed
  312.                 int height = this.height;
  313.  
  314.                 int colorCount = 16;
  315.  
  316.                 uint anim = jjAnimations[curAnim].firstFrame;
  317.  
  318.                 int xOffsetMax = 0;
  319.                 for (uint valuesIndex = 0; valuesIndex < values.length(); valuesIndex++) {
  320.                         array<int> value = values[valuesIndex];
  321.                         int xOffset = value[0];
  322.                         if (xOffset > xOffsetMax) {
  323.                                 xOffsetMax = xOffset;
  324.                         }
  325.                 }
  326.  
  327.                 float period = 1024.0f / height;
  328.                 //int amplitude = height / 16;
  329.                 int width = (amplitude + xOffsetMax) * 2 + 1;
  330.  
  331.                 int xCenterInImage = width / 2;
  332.                 int xStart = xCenter - xCenterInImage;
  333.                 this.xStarts.insertLast(xStart);
  334.                 this.xStarts.insertLast(math::mod(xStart - 1, jjLayerWidth[4] * 32) + 1);
  335.  
  336.                 int yEndInImage = height;
  337.                 int yStartInImage = 0;
  338.  
  339.                 for (uint frameID = 0; frameID < frameCount; frameID++) {
  340.                         jjPIXELMAP image(width, height);
  341.  
  342.                         int yFrameStart = frameID * height / frameCount;
  343.  
  344.                         for (uint valuesIndex = 0; valuesIndex < values.length(); valuesIndex++) {
  345.                                 array<int> value = values[valuesIndex];
  346.                                 int xOffset = value[0];
  347.                                 int segmentHeightShift = value[1];
  348.                                 int segmentHeight = 1 << segmentHeightShift;
  349.                                 uint segmentMask = value[2];
  350.  
  351.                                 for (int yOffset = 0; yOffset < height; yOffset++) {
  352.                                         int xBase = xCenterInImage + int(jjSin(uint(yOffset * period)) * amplitude);
  353.                                         int x1 = xBase - xOffset;
  354.                                         int x2 = xBase + xOffset;
  355.                                         int y1 = yStartInImage + yOffset;
  356.                                         int y2 = yEndInImage - yOffset - 1;
  357.  
  358.                                         int baseIndex = yFrameStart + yOffset;
  359.                                         int segmentIndex = baseIndex & (height - 1);
  360.                                         int colorIndex = (baseIndex >> segmentHeightShift) & ((height >> segmentHeightShift) - 1);
  361.  
  362.                                         if (colorIndex <= colorCount && (segmentMask >> (segmentIndex & (segmentHeight - 1))) & 1 != 0) {
  363.                                                 uint8 color;
  364.                                                 if (colorIndex == 0) {
  365.                                                         color = 15; //white
  366.                                                 } else {
  367.                                                         uint8 baseColor = 96; //very light yellowish orange
  368.                                                         color = baseColor + (colorIndex - 1); //gets darker
  369.                                                 }
  370.  
  371.                                                 if (type <= 0) {
  372.                                                         if (x1 < 0 || y1 < 0 || x1 >= width || y1 >= height) {
  373.                                                                 jjDebug("Invalid (x1, y1): (" + x1 + ", " + y1 + "), w: " + width + ", h: " + height);
  374.                                                                 continue;
  375.                                                         }
  376.                                                         image[x1, y1] = color;
  377.                                                 }
  378.  
  379.                                                 if (type >= 0) {
  380.                                                         if (x2 < 0 || y2 < 0 || x2 >= width || y2 >= height) {
  381.                                                                 jjDebug("Invalid (x2, y2): (" + x2 + ", " + y2 + "), w: " + width + ", h: " + height);
  382.                                                                 continue;
  383.                                                         }
  384.                                                         image[x2, y2] = color;
  385.                                                 }
  386.                                         }
  387.                                 }
  388.                         }
  389.  
  390.                         if (!image.save(jjAnimFrames[anim + frameID])) {
  391.                                 jjDebug("Could not save image: " + frameID);
  392.                                 return;
  393.                         }
  394.                 }
  395.         }
  396.  
  397.         void draw(int yStart, int yEnd) {
  398.                 uint frameID = (jjGameTicks >> this.speed) & (frameCount - 1);
  399.                 uint sprite = jjAnimations[curAnim].firstFrame + frameID;
  400.  
  401.                 int height = this.height;
  402.                 int yMid = yStart + ((yEnd - yStart) >> 1);
  403.  
  404.                 for (int y = yMid - height; y >= yStart - height; y -= height) {
  405.                         for (uint n = 0; n < xStarts.length(); n++) {
  406.                                 jjDrawSpriteFromCurFrame(xStarts[n], y, sprite);
  407.                         }
  408.                 }
  409.  
  410.                 for (int y = yMid; y < yEnd; y += height) {
  411.                         for (uint n = 0; n < xStarts.length(); n++) {
  412.                                 jjDrawSpriteFromCurFrame(xStarts[n], y, sprite);
  413.                         }
  414.                 }
  415.         }
  416. }
  417.