Downloads containing cleanSE.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Anniversary Bash 22 levels Jazz2Online Multiple N/A Download file
TSF with JJ2+ Only: Anniversary Bash 21 Levels Jazz2Online Multiple N/A Download file
JJ2+ Only: CleanseFeatured Download Seren Capture the flag 8.7 Download file

File preview

  1. #pragma require "Buildsit.j2t"
  2. #pragma require "cleanSE.j2a"
  3. #pragma require "cleanSE.pal"
  4. #pragma require "SEenergyblast.asc"
  5. #include "SEenergyblast.asc"
  6. class float2 {
  7.         float x, y;
  8.         float2() {}
  9.         float2(const float2& other) {
  10.                 this = other;
  11.         }
  12.         float2(float x, float y) {
  13.                 this.x = x;
  14.                 this.y = y;
  15.         }
  16.         float& opIndex(uint index) {
  17.                 return index == 0 ? x : y;
  18.         }
  19.         const float& opIndex(uint index) const {
  20.                 return index == 0 ? x : y;
  21.         }
  22.         float2& opAddAssign(const float2& rhs) {
  23.                 x += rhs.x;
  24.                 y += rhs.y;
  25.                 return this;
  26.         }
  27.         float2& opSubAssign(const float2& rhs) {
  28.                 x -= rhs.x;
  29.                 y -= rhs.y;
  30.                 return this;
  31.         }
  32.         float2& opMulAssign(float rhs) {
  33.                 x *= rhs;
  34.                 y *= rhs;
  35.                 return this;
  36.         }
  37.         float2& opDivAssign(float rhs) {
  38.                 x /= rhs;
  39.                 y /= rhs;
  40.                 return this;
  41.         }
  42.         bool opEquals(const float2& rhs) const {
  43.                 return x == rhs.x && y == rhs.y;
  44.         }
  45.         float2 opNeg() const {
  46.                 return float2(-x, -y);
  47.         }
  48.         float2 opAdd(const float2& rhs) const {
  49.                 return float2(x + rhs.x, y + rhs.y);
  50.         }
  51.         float2 opSub(const float2& rhs) const {
  52.                 return float2(x - rhs.x, y - rhs.y);
  53.         }
  54.         float2 opMul(float rhs) const {
  55.                 return float2(x * rhs, y * rhs);
  56.         }
  57.         float2 opMul_r(float lhs) const {
  58.                 return float2(lhs * x, lhs * y);
  59.         }
  60.         float2 opDiv(float rhs) const {
  61.                 return float2(x / rhs, y / rhs);
  62.         }
  63. }
  64. float dot(const float2& lhs, const float2& rhs) {
  65.         return lhs.x * rhs.x + lhs.y * rhs.y;
  66. }
  67. float abs(const float2& vec) {
  68.         return ::sqrt(dot(vec, vec));
  69. }
  70. class BuzzSaw : jjBEHAVIORINTERFACE {
  71.         void onBehave(jjOBJ@ obj) override {
  72.                 if (obj.state == STATE::START) {
  73.                         obj.state = STATE::TURN;
  74.                         obj.special = 3 + 2 * jjParameterGet(int(obj.xOrg) >>> 5, int(obj.yOrg) >>> 5, 0, 1);
  75.                         bool prev = false;
  76.                         for (int i = 0; i <= 1024; i += 2) {
  77.                                 float sine = jjSin(i);
  78.                                 float cosine = jjCos(i);
  79.                                 float x = floor(obj.xPos + sine * 56.f + 0.5f);
  80.                                 float y = floor(obj.yPos + cosine * 56.f + 0.5f);
  81.                                 bool cur = jjMaskedPixel(int(x), int(y));
  82.                                 if (prev && !cur) {
  83.                                         obj.state = STATE::ROTATE;
  84.                                         obj.xAcc = x;
  85.                                         obj.yAcc = y;
  86.                                         obj.xSpeed = cosine * 4.f;
  87.                                         obj.ySpeed = -sine * 4.f;
  88.                                         break;
  89.                                 }
  90.                                 prev = cur;
  91.                         }
  92.                 }
  93.                 bool makeParticles = false;
  94.                 for (int i = 0; i < jjLocalPlayerCount; i++) {
  95.                         const jjPLAYER@ player = jjLocalPlayers[i];
  96.                         float camRight = player.cameraX + jjSubscreenWidth;
  97.                         float camBottom = player.cameraY + jjSubscreenHeight;
  98.                         if (player.cameraX <= obj.xPos + 128.f && camRight >= obj.xPos - 128.f && camBottom >= obj.yPos - 64.f) {
  99.                                 makeParticles = obj.state == STATE::ROTATE;
  100.                                 if (player.cameraY <= obj.yPos + 64.f) {
  101.                                         const auto@ anim = jjAnimations[obj.animSpeed];
  102.                                         int frame = anim + jjGameTicks % anim.frameCount;
  103.                                         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, frame, 0, SPRITE::NORMAL, 0, obj.special, 4, player.playerID);
  104.                                 }
  105.                         }
  106.                 }
  107.                 if (makeParticles) {
  108.                         uint rand = jjRandom();
  109.                         if (rand & 3 == 0) {
  110.                                 rand >>= 2;
  111.                                 float xSpeed = obj.xSpeed + ((rand & 255) - 127.5f) * 4e-3f;
  112.                                 rand >>= 8;
  113.                                 float ySpeed = obj.ySpeed + ((rand & 255) - 127.5f) * 4e-3f;
  114.                                 rand >>= 8;
  115.                                 const auto@ anim = jjAnimations[obj.killAnim];
  116.                                 int frame = anim + rand % anim.frameCount;
  117.                                 addParticle(obj.xAcc, obj.yAcc, xSpeed, ySpeed, frame);
  118.                         }
  119.                 }
  120.         }
  121.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int) {
  122.                 if (bullet is null) {
  123.                         int invincibility = player.invincibility;
  124.                         player.invincibility = 0;
  125.                         player.hurt(2);
  126.                         player.invincibility = invincibility;
  127.                 }
  128.                 return true;
  129.         }
  130. }
  131. class Particle {
  132.         bool active;
  133.         float xPos;
  134.         float yPos;
  135.         float xSpeed;
  136.         float ySpeed;
  137.         int frame;
  138.         int age;
  139.         void process() {
  140.                 if (active) {
  141.                         ySpeed += 0.125f;
  142.                         xPos += xSpeed;
  143.                         yPos += ySpeed;
  144.                         age++;
  145.                         if (age == 4) {
  146.                                 age = 0;
  147.                                 active = !jjMaskedPixel(int(xPos), int(yPos));
  148.                         }
  149.                 }
  150.         }
  151.         void draw(jjCANVAS@ canvas) {
  152.                 if (active)
  153.                         canvas.drawSpriteFromCurFrame(int(xPos), int(yPos), frame, 0, SPRITE::SINGLECOLOR, 0);
  154.         }
  155. }
  156. void addParticle(float xPos, float yPos, float xSpeed, float ySpeed, int frame) {
  157.         auto@ part = particles[jjRandom() & particlesMask];
  158.         part.active = true;
  159.         part.xPos = xPos;
  160.         part.yPos = yPos;
  161.         part.xSpeed = xSpeed;
  162.         part.ySpeed = ySpeed;
  163.         part.frame = frame;
  164.         part.age = 0;
  165. }
  166. array<uint8>@ makeTintedMapping(bool strong) {
  167.         array<uint8> mapping(256);
  168.         for (int i = 0; i < 256; i++) {
  169.                 mapping[i] = i;
  170.         }
  171.         for (int i = 96; i < 112; i++) {
  172.                 mapping[i] = strong ? (i << 1) - 16 : (i >> 1) + 112;
  173.         }
  174.         for (int i = 112; i < 120; i++) {
  175.                 mapping[i] = strong ? (i << 2) - 272 : i + 48;
  176.         }
  177.         for (int i = 128; i < 144; i++) {
  178.                 mapping[i] = strong ? (i << 1) - 80 : i + 96;
  179.         }
  180.         for (int i = 143; i < 148; i++) {
  181.                 mapping[i] = strong ? 207 : 125;
  182.         }
  183.         for (int i = 148; i < 154; i++) {
  184.                 mapping[i] = strong ? (i << 1) - 99 : i - 28;
  185.         }
  186.         for (int i = 170; i < 172; i++) {
  187.                 mapping[i] = i - 44;
  188.         }
  189.         for (int i = 172; i < 177; i++) {
  190.                 mapping[i] = (i >> 1) + 82;
  191.         }
  192.         return mapping;
  193. }
  194. array<uint8>@ makeSingleColorMapping(uint8 color) {
  195.         array<uint8> result(256, color);
  196.         result[0] = 0;
  197.         return result;
  198. }
  199. void shiftLayer(jjLAYER@ layer, int shift) {
  200.         layer.generateSettableTileArea();
  201.         for (int i = 0; i < layer.height; i++) {
  202.                 for (int j = 0; j < layer.widthReal; j++) {
  203.                         int tile = layer.tileGet(j, i);
  204.                         if (tile != 0)
  205.                                 layer.tileSet(j, i, tile + shift);
  206.                 }
  207.         }
  208. }
  209. const float2@ findNearestBuzzSaw(const float2& pos, float maxDistance) {
  210.         const auto@ layer = jjLayers[4];
  211.         int left = (int(pos.x - maxDistance) + 15) >>> 5;
  212.         if (left < 0)
  213.                 left = 0;
  214.         int right = (int(pos.x + maxDistance) + 16) >>> 5;
  215.         if (right > layer.width)
  216.                 right = layer.width;
  217.         int top = (int(pos.y - maxDistance) + 15) >>> 5;
  218.         if (top < 0)
  219.                 top = 0;
  220.         int bottom = (int(pos.y + maxDistance) + 16) >>> 5;
  221.         if (bottom > layer.height)
  222.                 bottom = layer.height;
  223.         const float2@ result;
  224.         for (int i = top; i < bottom; i++) {
  225.                 for (int j = left; j < right; j++) {
  226.                         if (jjEventGet(j, i) == OBJECT::SPIKEBOLL3D) {
  227.                                 float2 other(j << 5 | 16, i << 5 | 16);
  228.                                 float distance = abs(other - pos);
  229.                                 if (distance < maxDistance) {
  230.                                         @result = other;
  231.                                         maxDistance = distance;
  232.                                 }
  233.                         }
  234.                 }
  235.         }
  236.         return result;
  237. }
  238. const uint particlesMask = 511;
  239. const float flameX = 119 << 5 | 16;
  240. const float flameY = 99 << 5 | 23;
  241. se::DefaultWeaponHook weaponHook(69);
  242. array<Particle> particles(particlesMask + 1);
  243. array<float2> pickupsToDelete;
  244. jjPAL palette = jjPalette;
  245. bool onDrawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) {
  246.         return weaponHook.drawAmmo(player, canvas);
  247. }
  248. void onDrawLayer4(jjPLAYER@, jjCANVAS@ canvas) {
  249.         for (int i = particles.length(); i-- != 0;) {
  250.                 particles[i].draw(canvas);
  251.         }
  252. }
  253. void onMain() {
  254.         weaponHook.processMain();
  255.         const auto@ buzzSawFrame = jjAnimFrames[jjAnimations[jjAnimSets[ANIM::CUSTOM[0]]]];
  256.         for (int i = 1; i < jjObjectCount; i++) {
  257.                 jjOBJ@ obj = jjObjects[i];
  258.                 if (obj.isActive) {
  259.                         if (obj.playerHandling == HANDLING::PICKUP) {
  260.                                 float2 org(obj.xOrg, obj.yOrg);
  261.                                 float2 pos(obj.xPos, obj.yPos);
  262.                                 const float2@ buzzSaw = findNearestBuzzSaw(pos, 80.f);
  263.                                 if (buzzSaw !is null && jjAnimFrames[obj.curFrame].doesCollide(int(pos.x), int(pos.y), obj.direction, buzzSawFrame, int(buzzSaw.x), int(buzzSaw.y), 0, true)) {
  264.                                         obj.particlePixelExplosion(0);
  265.                                         if (obj.counterEnd++ >= 16) {
  266.                                                 if (obj.creatorType != CREATOR::OBJECT || jjObjects[obj.creatorID].eventID == OBJECT::GENERATOR) {
  267.                                                         jjSTREAM packet;
  268.                                                         packet.push(uint8(0));
  269.                                                         packet.push(float(obj.xOrg));
  270.                                                         packet.push(float(obj.yOrg));
  271.                                                         jjSendPacket(packet);
  272.                                                 }
  273.                                                 obj.delete();
  274.                                         } else if (pickupsToDelete.find(org) >= 0) {
  275.                                                 obj.delete();
  276.                                         }
  277.                                 } else if (pickupsToDelete.find(org) >= 0) {
  278.                                         obj.behavior = BEHAVIOR::EXPLOSION2;
  279.                                 }
  280.                         } else if (obj.eventID == OBJECT::LASERSHIELD) {
  281.                                 jjDrawSprite(flameX, flameY, ANIM::PLUS_SCENERY, 1, jjGameTicks / 7, 0, SPRITE::PALSHIFT, 32);
  282.                         }
  283.                 }
  284.         }
  285.         pickupsToDelete.resize(0);
  286.         for (int i = particles.length(); i-- != 0;) {
  287.                 particles[i].process();
  288.         }
  289. }
  290. void onPlayer(jjPLAYER@ player) {
  291.         if (player.shieldTime > 0 && player.blink == -210)
  292.                 player.shieldTime -= 700;
  293.         weaponHook.processPlayer(player);
  294. }
  295. void onPlayerInput(jjPLAYER@ player) {
  296.         weaponHook.processPlayerInput(player);
  297. }
  298. void onReceive(jjSTREAM &in packet, int clientID) {
  299.         if (!weaponHook.processPacket(packet, clientID)) {
  300.                 jjSTREAM copy = packet;
  301.                 float2 pos;
  302.                 if (packet.discard(1) && packet.pop(pos.x) && packet.pop(pos.y)) {
  303.                         pickupsToDelete.insertLast(pos);
  304.                         if (jjIsServer)
  305.                                 jjSendPacket(copy, -clientID);
  306.                 }
  307.         }
  308. }
  309. void onLevelLoad() {
  310.         jjDelayGeneratedCrateOrigins = true;
  311.         jjUseLayer8Speeds = true;
  312.         jjTexturedBGTexture = TEXTURE::WINDSTORMFORTRESS;
  313.         const uint tileCount = jjTileCount;
  314.         if (jjTilesFromTileset(jjTilesetFileName, 0, tileCount, makeTintedMapping(false)))
  315.                 shiftLayer(jjLayers[6], tileCount);
  316.         if (jjTilesFromTileset(jjTilesetFileName, 0, tileCount, makeTintedMapping(true)))
  317.                 shiftLayer(jjLayers[7], tileCount * 2);
  318.         if (jjTilesFromTileset("Buildsit.j2t", 20, 60, makeSingleColorMapping(207))) {
  319.                 shiftLayer(jjLayers[1], tileCount * 3);
  320.                 shiftLayer(jjLayers[2], tileCount * 3 + 39);
  321.         }
  322.         for (uint i = tileCount * 3 + 60; i-- != tileCount * 2;) {
  323.                 jjTileType[i] = 1;
  324.         }
  325.         auto@ order = jjLayerOrderGet();
  326.         for (int i = 0; i < 2; i++) {
  327.                 order.insertAt(6, order[0]);
  328.                 order.removeAt(0);
  329.         }
  330.         jjLayerOrderSet(order);
  331.         jjAnimSets[ANIM::PLUS_SCENERY].load();
  332.         jjAnimSets[ANIM::CUSTOM[0]].load(0, "cleanSE.j2a");
  333.         if (palette.load("cleanSE.pal"))
  334.                 palette.apply();
  335.         auto@ saw = jjObjectPresets[OBJECT::SPIKEBOLL3D];
  336.         saw.behavior = BuzzSaw();
  337.         saw.bulletHandling = HANDLING::IGNOREBULLET;
  338.         saw.scriptedCollisions = true;
  339.         saw.curAnim = jjAnimSets[ANIM::CUSTOM[0]];
  340.         saw.animSpeed = saw.curAnim + 1;
  341.         saw.killAnim = saw.curAnim + 2;
  342.         saw.determineCurFrame();
  343.         se::energyBlast.loadAnims(jjAnimSets[ANIM::CUSTOM[1]]);
  344.         se::energyBlast.loadSamples(array<SOUND::Sample> = {SOUND::INTRO_BLOW});
  345.         se::energyBlast.setAsWeapon(3, weaponHook);
  346. }
  347. void onLevelReload() {
  348.         palette.apply();
  349. }
  350.