Downloads containing ab23btl12.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Anniversary Bash 23 levels Jazz2Online Multiple N/A Download file

File preview

  1. #include "MLLE-Include-1.5w.asc" ///@MLLE-Generated
  2. #pragma require "ab23btl12.j2l" ///@MLLE-Generated
  3. #include "SEfirework-mlle.asc" ///@MLLE-Generated
  4. #pragma require "SEfirework-mlle.asc" ///@MLLE-Generated
  5. class CustomWeaponHook : se::DefaultWeaponHook {
  6.         bool drawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) override {
  7.                 int x, y;
  8.                 STRING::Size font;
  9.                 string text;
  10.                 const jjWEAPON@ weapon = jjWeapons[player.currWeapon];
  11.                 if (jjSubscreenWidth > 400) {
  12.                         x = jjSubscreenWidth - 88;
  13.                         y = jjSubscreenHeight - 14;
  14.                         font = STRING::MEDIUM;
  15.                 } else {
  16.                         x = jjSubscreenWidth - 48;
  17.                         y = jjSubscreenHeight - 9;
  18.                         font = STRING::SMALL;
  19.                 }
  20.                 if (weapon.infinite || weapon.replacedByShield && player.shieldTime > 0) {
  21.                         text = "x^";
  22.                 } else {
  23.                         int ammo = player.ammo[WEAPON::CURRENT];
  24.                         text = "x" + (ammo > 0 ? ammo : 0);
  25.                 }
  26.                 drawAmmoSprite(canvas, x, y, getWeaponAnimation(player.currWeapon, player.powerup[WEAPON::CURRENT]));
  27.                 canvas.drawString(x + 8, y, text, font);
  28.                 return true;
  29.         }
  30. }
  31. array<int> lastFired(jjLocalPlayerCount);
  32. array<int> lenientLastFired(jjLocalPlayerCount);
  33. array<bool> missileFired(jjLocalPlayerCount);
  34. array<bool> selectPressed(jjLocalPlayerCount);
  35. array<bool> tongueUsed(jjLocalPlayerCount);
  36. bool canFire(const jjPLAYER@ player) {
  37.         switch (jjWeapons[player.currWeapon].style) {
  38.                 case WEAPON::MISSILE:
  39.                         return !missileFired[player.localPlayerID];
  40.                 case WEAPON::POPCORN:
  41.                         return jjGameTicks - lenientLastFired[player.localPlayerID] >= 6;
  42.                 case WEAPON::CAPPED:
  43.                         return jjGameTicks - lastFired[player.localPlayerID] >= player.fastfire;
  44.         }
  45.         return jjGameTicks - lenientLastFired[player.localPlayerID] >= player.fastfire;
  46. }
  47. void processFiring(const jjPLAYER@ player) {
  48.         if (jjWeapons[player.currWeapon].style == WEAPON::MISSILE)
  49.                 missileFired[player.localPlayerID] = true;
  50.         lastFired[player.localPlayerID] = jjGameTicks;
  51.         lenientLastFired[player.localPlayerID] = jjGameTicks;
  52. }
  53. void processNotFiring(const jjPLAYER@ player) {
  54.         missileFired[player.localPlayerID] = false;
  55.         lenientLastFired[player.localPlayerID] = -252000;
  56. }
  57. void cycleWeapon(jjPLAYER@ player) {
  58.         auto initial = player.currWeapon;
  59.         do {
  60.                 player.currWeapon = player.currWeapon % 9 + 1;
  61.         } while (player.currWeapon != initial && getRealAmmo(player, WEAPON::CURRENT) == 0);
  62. }
  63. jjANIMATION@ getWeaponAnimation(int weapon, bool powerup) {
  64.         int modifier = powerup ? 1 : 0;
  65.         switch (weapon) {
  66.                 case WEAPON::BLASTER:
  67.                         return jjAnimations[powerup ? jjAnimSets[ANIM::AMMO] + 18 : jjAnimSets[ANIM::PICKUPS] + 29];
  68.                 case WEAPON::BOUNCER:
  69.                         return jjAnimations[jjAnimSets[ANIM::AMMO] + 25 - modifier];
  70.                 case WEAPON::ICE:
  71.                         return jjAnimations[jjAnimSets[ANIM::CUSTOM[0]] + modifier];
  72.                 case WEAPON::SEEKER:
  73.                         return jjAnimations[jjAnimSets[ANIM::AMMO] + 34 - modifier];
  74.                 case WEAPON::RF:
  75.                         return jjAnimations[jjAnimSets[ANIM::AMMO] + 49 - modifier];
  76.                 case WEAPON::TOASTER:
  77.                         return jjAnimations[jjAnimSets[ANIM::AMMO] + 57 - modifier];
  78.                 case WEAPON::TNT:
  79.                         return jjAnimations[jjAnimSets[ANIM::AMMO] + 59];
  80.                 case WEAPON::GUN8:
  81.                         return jjAnimations[jjAnimSets[ANIM::AMMO] + 62 - modifier];
  82.                 case WEAPON::GUN9:
  83.                         return jjAnimations[jjAnimSets[ANIM::AMMO] + 68 - modifier];
  84.         }
  85.         return null;
  86. }
  87. int getWeaponEventID(int weapon, bool powerup, bool &out pepper) {
  88.         auto spread = jjWeapons[weapon].spread;
  89.         if (spread == SPREAD::PEPPERSPRAY || spread == SPREAD::GUN8 && !jjAllowsFireball) {
  90.                 pepper = true;
  91.                 return OBJECT::BULLET;
  92.         }
  93.         pepper = false;
  94.         int modifier = powerup ? 8 : 0;
  95.         switch (weapon) {
  96.                 case WEAPON::BLASTER:
  97.                         return OBJECT::BLASTERBULLET + modifier;
  98.                 case WEAPON::BOUNCER:
  99.                         return OBJECT::BOUNCERBULLET + modifier;
  100.                 case WEAPON::ICE:
  101.                         return OBJECT::ICEBULLET + modifier;
  102.                 case WEAPON::SEEKER:
  103.                         return OBJECT::SEEKERBULLET + modifier;
  104.                 case WEAPON::RF:
  105.                         return OBJECT::RFBULLET + modifier;
  106.                 case WEAPON::TOASTER:
  107.                         return OBJECT::TOASTERBULLET + modifier;
  108.                 case WEAPON::TNT:
  109.                         return OBJECT::TNT;
  110.                 case WEAPON::GUN8:
  111.                         return OBJECT::FIREBALLBULLET + modifier;
  112.                 case WEAPON::GUN9:
  113.                         return OBJECT::ELECTROBULLET + modifier;
  114.         }
  115.         return 0;
  116. }
  117. void drawAmmoSprite(jjCANVAS@ canvas, int x, int y, const jjANIMATION@ anim) {
  118.         if (anim !is null)
  119.                 canvas.drawSpriteFromCurFrame(x, y, anim + (::jjGameTicks >> 2) % anim.frameCount);
  120. }
  121. void fireBullet(const jjPLAYER@ player, int angle, float x, float y) {
  122.         bool pepper;
  123.         auto eventID = getWeaponEventID(player.currWeapon, player.powerup[WEAPON::CURRENT], pepper);
  124.         int id = jjAddObject(eventID, x, y, player.playerID, CREATOR::PLAYER, pepper ? BEHAVIOR::PEPPERBULLET : BEHAVIOR::DEFAULT);
  125.         if (id > 0) {
  126.                 auto@ obj = jjObjects[id];
  127.                 if (pepper) {
  128.                         bool powerup = jjStrongPowerups && player.powerup[WEAPON::CURRENT];
  129.                         obj.playerHandling = HANDLING::PLAYERBULLET;
  130.                         obj.determineCurAnim(ANIM::AMMO, powerup ? 10 : 9);
  131.                         obj.determineCurFrame();
  132.                         obj.animSpeed = player.powerup[WEAPON::CURRENT] ? 2 : 1;
  133.                         obj.var[3] = 8;
  134.                         obj.xSpeed = 4.f;
  135.                         if (powerup) {
  136.                                 obj.lightType = LIGHT::POINT2;
  137.                                 obj.state = STATE::FLY;
  138.                                 obj.var[6] = obj.var[6] | 8;
  139.                         }
  140.                 }
  141.                 float speed = obj.xSpeed;
  142.                 float acc = obj.xAcc;
  143.                 obj.xSpeed = jjCos(angle << 7) * speed;
  144.                 obj.ySpeed -= jjSin(angle << 7) * speed;
  145.                 obj.xAcc = jjCos(angle << 7) * acc;
  146.                 obj.yAcc -= jjSin(angle << 7) * acc;
  147.                 obj.direction = angle < 2 ? 1 : angle > 2 ? -1 : 0;
  148.         }
  149. }
  150. int getRealAmmo(const jjPLAYER@ player, int weapon) {
  151.         if (weapon == WEAPON::CURRENT)
  152.                 weapon = player.currWeapon;
  153.         auto@ preset = jjWeapons[weapon];
  154.         int multiplier = preset.multiplier;
  155.         preset.multiplier = 1;
  156.         int result = player.ammo[weapon];
  157.         preset.multiplier = multiplier;
  158.         return result;
  159. }
  160. void decrementRealAmmo(jjPLAYER@ player, int weapon) {
  161.         if (weapon == WEAPON::CURRENT)
  162.                 weapon = player.currWeapon;
  163.         auto@ preset = jjWeapons[weapon];
  164.         int multiplier = preset.multiplier;
  165.         preset.multiplier = 1;
  166.         player.ammo[weapon] = player.ammo[weapon] - 1;
  167.         preset.multiplier = multiplier;
  168. }
  169. void coinMorph(jjOBJ@ obj) {
  170.         if (obj.state == STATE::DEACTIVATE) {
  171.                 obj.deactivate();
  172.                 return;
  173.         }
  174.         if (obj.state == STATE::START) {
  175.                 int x = int(obj.xOrg) >>> 5;
  176.                 int y = int(obj.yOrg) >>> 5;
  177.                 if (jjParameterGet(x, y, 17, 1) == 0) {
  178.                         obj.delete();
  179.                         return;
  180.                 }
  181.                 obj.state = STATE::STILL;
  182.                 obj.var[0] = jjParameterGet(x, y, 8, 8);
  183.                 obj.var[1] = jjParameterGet(x, y, 0, 8);
  184.                 obj.var[2] = jjParameterGet(x, y, 16, 1);
  185.                 obj.var[3] = jjParameterGet(x, y, 18, 1);
  186.                 obj.xPos -= 16.f;
  187.                 obj.yPos -= 16.f;
  188.                 obj.putOnGround(true);
  189.                 return;
  190.         }
  191.         auto@ bunny = jjAnimations[obj.curAnim];
  192.         auto@ booth = jjAnimations[obj.special];
  193.         obj.counter++;
  194.         if (obj.counter & 7 == 0) {
  195.                 obj.frameID++;
  196.                 if (obj.frameID >= int(bunny.frameCount))
  197.                         obj.frameID = 0;
  198.                 obj.determineCurFrame();
  199.         }
  200.         jjDrawSpriteFromCurFrame(obj.xPos - 1.f, obj.yPos + 3.f, booth + (obj.counter >> 3) % booth.frameCount, obj.direction, SPRITE::PALSHIFT, 16);
  201.         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame + bunny.frameCount, obj.direction);
  202.         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 40);
  203.         if (obj.var[0] != 0) {
  204.                 jjTEXTAPPEARANCE style(STRING::BOUNCE);
  205.                 style.align = STRING::CENTER;
  206.                 jjDrawString(obj.xPos - 4.f, obj.yPos - 12.f, formatInt(obj.var[0]), STRING::SMALL, style, 0, SPRITE::PALSHIFT, 224);
  207.         }
  208.         for (int i = 0; i < jjLocalPlayerCount; i++) {
  209.                 auto@ player = jjLocalPlayers[i];
  210.                 float dx = player.xPos - obj.xPos;
  211.                 float dy = player.yPos - obj.yPos;
  212.                 if (dx * dx + dy * dy < 1024.f && player.charCurr != CHAR::BIRD && player.testForCoins(obj.var[0])) {
  213.                         player.morphTo(CHAR::BIRD);
  214.                         jjSample(player.xPos, player.yPos, SOUND::COMMON_BUBBLGN1);
  215.                 }
  216.         }
  217. }
  218. bool onDrawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) {
  219.         return MLLE::WeaponHook.drawAmmo(player, canvas);
  220. }
  221. void onLevelLoad() {
  222.         @MLLE::WeaponHook = CustomWeaponHook();
  223.         MLLE::Setup(array<MLLEWeaponApply@> = {null, null, se::FireworkMLLEWrapper(), null, null, null, null, null, null});
  224.         jjCharacters[CHAR::FROG].canHurt = true;
  225.         jjCharacters[CHAR::FROG].canRun = true;
  226.         jjCharacters[CHAR::BIRD].canHurt = true;
  227.         jjCharacters[CHAR::BIRD].canRun = true;
  228.         jjObjectPresets[OBJECT::WARP].behavior = coinMorph;
  229. }
  230. void onPlayerInput(jjPLAYER@ player) {
  231.         auto@ weapon = jjWeapons[player.currWeapon];
  232.         auto style = weapon.style;
  233.         if (player.charCurr == CHAR::FROG || player.charCurr == CHAR::BIRD) {
  234.                 if (player.keySelect) {
  235.                         if (!selectPressed[player.localPlayerID]) {
  236.                                 selectPressed[player.localPlayerID] = true;
  237.                                 cycleWeapon(player);
  238.                         }
  239.                 } else {
  240.                         selectPressed[player.localPlayerID] = false;
  241.                 }
  242.         }
  243.         if (player.charCurr == CHAR::BIRD) {
  244.                 if (player.keyFire) {
  245.                         player.keyFire = false;
  246.                         if (canFire(player) && player.currWeapon != WEAPON::BLASTER) {
  247.                                 int anim = player.curAnim - jjAnimSets[ANIM::BIRD];
  248.                                 if (anim >= 9 && anim != 10 && anim != 19) {
  249.                                         if (anim != 9)
  250.                                                 player.keyUp = true;
  251.                                         player.fireBullet();
  252.                                         processFiring(player);
  253.                                         if (getRealAmmo(player, WEAPON::CURRENT) == 0 && !weapon.infinite)
  254.                                                 cycleWeapon(player);
  255.                                 }
  256.                         }
  257.                 } else {
  258.                         processNotFiring(player);
  259.                 }
  260.                 if (player.keyJump) {
  261.                         player.keyFire = true;
  262.                         player.keyJump = false;
  263.                 }
  264.         }
  265. }
  266. void onPlayer(jjPLAYER@ player) {
  267.         if (player.xSpeed > 6.f)
  268.                 player.xSpeed = 6.f;
  269.         if (player.xSpeed < -6.f)
  270.                 player.xSpeed = -6.f;
  271.         if (player.charCurr == CHAR::FROG) {
  272.                 int anim = player.curAnim - jjAnimSets[ANIM::FROG] + (jjIsTSF ? 0 : 1);
  273.                 if (anim >= 8 && anim <= 10 && player.frameID == 6) {
  274.                         if (!tongueUsed[player.localPlayerID]) {
  275.                                 tongueUsed[player.localPlayerID] = true;
  276.                                 if (player.currWeapon != WEAPON::BLASTER) {
  277.                                         if (getRealAmmo(player, WEAPON::CURRENT) > 0) {
  278.                                                 decrementRealAmmo(player, WEAPON::CURRENT);
  279.                                                 int angle = anim == 10 ? 2 : player.direction < 0 ? anim - 5 : 9 - anim;
  280.                                                 float x = player.xPos + jjCos(angle << 7) * 76.f + (player.direction < 0 ? 4.f : -4.f);
  281.                                                 float y = player.yPos - jjSin(angle << 7) * 76.f + 8.f;
  282.                                                 jjSTREAM packet;
  283.                                                 packet.push(uint8(player.playerID));
  284.                                                 packet.push(uint8(player.currWeapon));
  285.                                                 packet.push(bool(player.powerup[WEAPON::CURRENT]));
  286.                                                 packet.push(uint(player.ammo[WEAPON::CURRENT]));
  287.                                                 packet.push(uint8(angle));
  288.                                                 packet.push(float(x));
  289.                                                 packet.push(float(y));
  290.                                                 jjSendPacket(packet);
  291.                                                 fireBullet(player, angle, x, y);
  292.                                         }
  293.                                         if (getRealAmmo(player, WEAPON::CURRENT) == 0 && !jjWeapons[player.currWeapon].infinite)
  294.                                                 cycleWeapon(player);
  295.                                 }
  296.                         }
  297.                 } else {
  298.                         tongueUsed[player.localPlayerID] = false;
  299.                 }
  300.         } else if (player.charCurr != CHAR::BIRD) {
  301.                 player.morphTo(CHAR::FROG);
  302.         }
  303. }
  304. void onReceive(jjSTREAM &in packet, int clientID) {
  305.         jjSTREAM backup = packet;
  306.         uint8 playerID, weapon, angle;
  307.         uint ammo;
  308.         bool powerup;
  309.         float x, y;
  310.         if (!packet.pop(playerID) || !packet.pop(weapon) || !packet.pop(powerup) || !packet.pop(ammo) || !packet.pop(angle) || !packet.pop(x) || !packet.pop(y))
  311.                 return;
  312.         if (playerID >= 32 || weapon <= 1 || weapon >= 10 || angle >= 5)
  313.                 return;
  314.         auto@ player = jjPlayers[playerID];
  315.         if (jjIsServer && player.clientID != clientID || player.isLocal)
  316.                 return;
  317.         if (jjIsServer)
  318.                 jjSendPacket(backup, -clientID);
  319.         player.currWeapon = weapon;
  320.         player.powerup[weapon] = powerup;
  321.         player.ammo[weapon] = ammo;
  322.         fireBullet(player, angle, x, y);
  323. }
  324.