Downloads containing mo4a_4-3.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Mystery of the Four... chandie Single player 6.6 Download file

File preview

  1. const bool MLLESetupSuccessful = MLLE::Setup(array<MLLEWeaponApply@> = {null, null, WeaponVMega::IceCloud::Weapon(), WeaponVMega::Voranj::Weapon(), WeaponVMega::Backfire::Weapon(), null, ArcaneWeapons::FusionCannon::Weapon(), null, ArcaneWeapons::MortarLauncher::Weapon()}); ///@MLLE-Generated
  2. #include "MLLE-Include-1.5w.asc" ///@MLLE-Generated
  3. #pragma require "mo4a_4-3.j2l" ///@MLLE-Generated
  4. #include "ArcaneWeapon4.asc" ///@MLLE-Generated
  5. #pragma require "ArcaneWeapon4.asc" ///@MLLE-Generated
  6. #include "ArcaneWeapon9.asc" ///@MLLE-Generated
  7. #pragma require "ArcaneWeapon9.asc" ///@MLLE-Generated
  8. #include "WeaponVMega5.asc" ///@MLLE-Generated
  9. #pragma require "WeaponVMega5.asc" ///@MLLE-Generated
  10. #include "WeaponVMega8.asc" ///@MLLE-Generated
  11. #pragma require "WeaponVMega8.asc" ///@MLLE-Generated
  12. #include "WeaponVMega3.asc" ///@MLLE-Generated
  13. #pragma require "WeaponVMega3.asc" ///@MLLE-Generated
  14. #include "HH18savegems.asc"
  15. #include "Jazz1Enemies v05.asc"
  16. #include "Resize v11.asc"
  17. #include "TrueColor v13.asc"
  18. bool jump = false, coinchange = false, coinready = false;
  19. int FireflyRed = 0, FireflyGreen = 0, FireflyBlu = 0, exit = 0;
  20.  
  21. bool onDrawHealth(jjPLAYER@ player, jjCANVAS@ canvas) {
  22.         if(jump == true)
  23.     {canvas.drawSprite(100, 582, ANIM::PICKUPS, 33, jjGameTicks>>2, -1, SPRITE::PALSHIFT, 24);}
  24.         if(coinchange == true && coinready == false)
  25.     {canvas.drawSprite(150, 582, ANIM::PICKUPS, 37, jjGameTicks>>2, -1, SPRITE::BRIGHTNESS, 52);}
  26.     canvas.drawSprite(20, 578, ANIM::PICKUPS, 0, jjGameTicks>>2, -1, SPRITE::NORMAL);
  27.     canvas.drawString(30, 585, formatInt(exit%4, "1") + "/3", STRING::SMALL, STRING::NORMAL);
  28.     return false;
  29. }
  30.  
  31. bool onDrawLives(jjPLAYER@ player, jjCANVAS@ canvas) {return true;}
  32.  
  33.  
  34. void onLevelLoad() {
  35.         gem::restorePlayerGems();
  36.         jjObjectPresets[OBJECT::TUFTURT].behavior = Yeti;
  37.         jjObjectPresets[OBJECT::TUFTURT].determineCurAnim(ANIM::TUFBOSS, 4);
  38.         jjObjectPresets[OBJECT::TUFTURT].playerHandling = HANDLING::ENEMY;
  39.         jjObjectPresets[OBJECT::TUFTURT].bulletHandling = HANDLING::HURTBYBULLET;
  40.         jjObjectPresets[OBJECT::TUFTURT].energy = 3;
  41.         jjWaterLighting = WATERLIGHT::GLOBAL;
  42.         jjLevelName = ("@@@@@@@@@Mt. Everest");
  43.         jjObjectPresets[OBJECT::SAVEPOST].behavior = CheckpointWrapper;
  44.         jjObjectPresets[OBJECT::SAVEPOST].deactivates = false;
  45.  
  46.         jjObjectPresets[OBJECT::FATCHICK].behavior = DemonGhost();
  47.         jjObjectPresets[OBJECT::FATCHICK].scriptedCollisions = true;
  48.  
  49.         jjObjectPresets[OBJECT::GRASSPLATFORM].xSpeed = 5;
  50.         jjObjectPresets[OBJECT::GRASSPLATFORM].scriptedCollisions = true;
  51.         jjObjectPresets[OBJECT::GRASSPLATFORM].behavior = PlatformH;
  52.  
  53.         jjObjectPresets[OBJECT::SONICPLATFORM].xSpeed = 5;
  54.         jjObjectPresets[OBJECT::SONICPLATFORM].scriptedCollisions = true;
  55.         jjObjectPresets[OBJECT::SONICPLATFORM].behavior = FlyingSpring();      
  56.         jjObjectPresets[OBJECT::SONICPLATFORM].determineCurAnim(ANIM::SPRING,6);       
  57.  
  58.         jjObjectPresets[OBJECT::STOPWATCH].behavior = GreenSw();
  59.         jjObjectPresets[OBJECT::STOPWATCH].scriptedCollisions = true;
  60.  
  61.         jjObjectPresets[OBJECT::PURPLEGEM].behavior = MovingPurpleGem();
  62.         jjObjectPresets[OBJECT::PURPLEGEM].scriptedCollisions = true;
  63.  
  64.         jjObjectPresets[OBJECT::GOLDCOIN].behavior = PlatinCoin();
  65.         jjObjectPresets[OBJECT::GOLDCOIN].scriptedCollisions = true;
  66.  
  67.         Jazz1::MakeEnemy(OBJECT::SUCKER, Jazz1::Enemies::Holidaius_HandVertical).SetDirection(Jazz1::Directions::Right);
  68.         Jazz1::MakeEnemy(OBJECT::RAVEN, Jazz1::Enemies::Holidaius_Devil).SetUsesJJ2StyleDeathAnimation(true).SetDeathSound(SOUND::BILSBOSS_THUNDER);
  69.         Jazz1::MakeEnemy(OBJECT::FLOATSUCKER, Jazz1::Enemies::Holidaius_HandVertical).SetDirection(Jazz1::Directions::Left);
  70.         Jazz1::MakeEnemy(OBJECT::SKELETON, Jazz1::Enemies::Megairbase_Doofusguard).SetUsesJJ2StyleDeathAnimation(true).SetBulletFireSound(SOUND::INTRO_SHOTGRN).SetBulletExplosionSound(SOUND::COMMON_GUNSM1);
  71.  
  72.         jjObjectPresets[OBJECT::AIRBOARD].behavior = RedSw();
  73.         jjObjectPresets[OBJECT::AIRBOARD].scriptedCollisions = true;
  74.  
  75.         jjObjectPresets[OBJECT::WEENIE].behavior = BluSw();
  76.         jjObjectPresets[OBJECT::WEENIE].scriptedCollisions = true;
  77.  
  78.         jjObjectPresets[OBJECT::LEMON].behavior = RedFF;
  79.         jjObjectPresets[OBJECT::LEMON].scriptedCollisions = true;
  80.  
  81.         jjObjectPresets[OBJECT::BANANA].behavior = BluFF;
  82.         jjObjectPresets[OBJECT::BANANA].scriptedCollisions = true;
  83.  
  84.         jjObjectPresets[OBJECT::TURTLESHELL].behavior = GreenFF;
  85.         jjObjectPresets[OBJECT::TURTLESHELL].scriptedCollisions = true;
  86.  
  87.         jjObjectPresets[OBJECT::FASTFEET].behavior = FakeCoin();
  88.         jjObjectPresets[OBJECT::FASTFEET].scriptedCollisions = true;
  89.  
  90.         jjObjectPresets[OBJECT::CHICKENLEG].behavior = WallJump();
  91.         jjObjectPresets[OBJECT::CHICKENLEG].scriptedCollisions = true;
  92.  
  93.         jjObjectPresets[OBJECT::BOLLPLATFORM].behavior = Ice();
  94.         jjObjectPresets[OBJECT::BOLLPLATFORM].scriptedCollisions = true;
  95.  
  96.         jjObjectPresets[OBJECT::FRUITPLATFORM].behavior = IceR();      
  97.         jjObjectPresets[OBJECT::FRUITPLATFORM].scriptedCollisions = true;
  98.  
  99.         jjObjectPresets[OBJECT::BURGER].playerHandling = HANDLING::SPECIAL;
  100.         jjObjectPresets[OBJECT::BURGER].scriptedCollisions = true;     
  101.         jjObjectPresets[OBJECT::BURGER].behavior = FreezeJazz();
  102.  
  103.         jjObjectPresets[OBJECT::HAM].determineCurAnim(ANIM::PICKUPS, 78);
  104.         jjObjectPresets[OBJECT::HAM].scriptedCollisions = true;
  105.         jjObjectPresets[OBJECT::HAM].playerHandling = HANDLING::PLAYERBULLET;  
  106.  
  107.         jjObjectPresets[OBJECT::MILK].energy = 100;
  108.         jjObjectPresets[OBJECT::MILK].behavior = SpittingBubba;
  109.         jjObjectPresets[OBJECT::MILK].points = 1000;
  110.         jjObjectPresets[OBJECT::MILK].xSpeed = 1;
  111.         jjObjectPresets[OBJECT::MILK].state = STATE::WALK;
  112.         jjObjectPresets[OBJECT::MILK].deactivates = false;
  113.         jjObjectPresets[OBJECT::MILK].scriptedCollisions = true;
  114.         jjObjectPresets[OBJECT::MILK].isTarget = true;
  115.         jjObjectPresets[OBJECT::MILK].playerHandling = HANDLING::ENEMY;
  116.  
  117.         jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::LETTUCE].curAnim];
  118.         anim.frameCount = 1;
  119.         jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  120.         jjPIXELMAP fruit(0, 36*32, 1*32, 1*32, 5);
  121.         fruit.save(frame);
  122.  
  123. }
  124.  
  125. // Credit: from Stone Abbys by Bloody_Body
  126.         jjOBJ@ spawnedObject;
  127. void SpittingBubba(jjOBJ@ enemy) {
  128.                                         if ( enemy.energy == 0)
  129.                                         {enemy.state = STATE::KILL;
  130.                                                         p.activateBoss(false);}
  131.         switch (enemy.state) {
  132.                 case STATE::WALK:
  133.                 enemy.behave(BEHAVIOR::WALKINGENEMY);
  134.                 enemy.determineCurAnim(ANIM::BUBBA, 5);
  135.                                                                                
  136.                          if (enemy.findNearestPlayer(64*800) > -1 && ++enemy.counter > 36) enemy.state = STATE::IDLE;
  137.                                 if (enemy.energy == 0)
  138.                                         enemy.state = STATE::KILL;
  139.                         break;
  140.                         case STATE::IDLE:
  141.                         enemy.frameID = enemy.counter/5;
  142.                         enemy.determineCurFrame();
  143.                        
  144.                         switch (jjRandom() & 3) {
  145.                                
  146.                                 case 0:  
  147.                                 case 1:
  148.                                
  149.                                         enemy.state = STATE::ACTION;
  150.                                         enemy.determineCurAnim(ANIM::BUBBA, 0);
  151.                                         enemy.counter = 0;
  152.                                         break;
  153.                                        
  154.                                 case 2:
  155.                                
  156.                                         enemy.state = STATE::WALK;
  157.                                         enemy.determineCurAnim(ANIM::BUBBA, 5);
  158.                                         enemy.counter = 0;
  159.                                        
  160.                                         break;
  161.                                        
  162.                                         }
  163.                         break;
  164.                        
  165.                        
  166.                 case STATE::ACTION:
  167.                 if (++enemy.counter < 36) {
  168.                         enemy.frameID = enemy.counter/5;
  169.                         enemy.determineCurFrame();
  170.                         enemy.direction = (jjLocalPlayers[0].xPos < enemy.xPos) ? -1 : 1;
  171.                                    if (enemy.justHit == 0)
  172.                         if (enemy.counter == 25 ) {
  173.                         //if difficulty is easy Bubba spits once per every "state::action", if normal- twice, it hard or turbo- three times.
  174.                 jjOBJ@ bullet = jjObjects[enemy.fireBullet(OBJECT::LIGHTNINGSHIELDBULLET)];
  175.                                 bullet.determineCurAnim(ANIM::DEVAN, 0);
  176.                                 bullet.killAnim = bullet.determineCurAnim(ANIM::AMMO, 3, false);
  177.                                 bullet.playerHandling = HANDLING::ENEMYBULLET;
  178.                                 bullet.state = STATE::FLY;
  179.                                 bullet.xPos = enemy.xPos;
  180.                                 bullet.yPos = bullet.yPos - 16;
  181.                                 if (p.curAnim - jjAnimSets[p.setID].firstAnim == RABBIT::HURT)
  182.                                 {p.freeze(true);}
  183.                                 bullet.animSpeed = 2;
  184.                                 jjSample(enemy.xPos, enemy.yPos, SOUND::BUBBA_SNEEZE2);
  185.                 }
  186.  
  187.                
  188.  
  189.                 } else {
  190.                         enemy.frameID = enemy.counter = 0;
  191.                         enemy.determineCurAnim(ANIM::BUBBA, 5);
  192.                         enemy.state = STATE::IDLE;
  193.                 }
  194.                 break;
  195.        
  196.                        
  197.                 case STATE::FREEZE:
  198.                         if (enemy.freeze > 0) {
  199.                                 enemy.draw();
  200.                                 enemy.freeze -= 4;
  201.                         }
  202.                         if (enemy.freeze < 4) {
  203.                                 enemy.unfreeze(0);
  204.                                 enemy.state = enemy.oldState;
  205.                         }
  206.                         break;
  207.        
  208.                        
  209.                 case STATE::KILL:
  210.                         jjAddObject(OBJECT::CHICKENLEG, 4586, 1802);
  211.                         enemy.delete();
  212.                         break;
  213.                         }
  214.                                    if (enemy.justHit == 0)
  215.                 {    jjDrawSpriteFromCurFrame(enemy.xPos, enemy.yPos, enemy.curFrame, enemy.direction, SPRITE::PALSHIFT, 40);}
  216. else
  217.     jjDrawSpriteFromCurFrame(enemy.xPos, enemy.yPos, enemy.curFrame, enemy.direction, SPRITE::BRIGHTNESS, 255);
  218.                
  219.                
  220.         }
  221.  
  222. class DemonGhost: jjBEHAVIORINTERFACE {
  223.  
  224.         void onBehave(jjOBJ@ obj) {
  225.  
  226.                         obj.behave(BEHAVIOR::WALKINGENEMY, false);
  227.                         obj.bulletHandling = HANDLING::IGNOREBULLET;
  228.                         obj.playerHandling = HANDLING::SPECIAL;
  229.                         obj.determineCurAnim(ANIM::DEMON, 2);
  230.                         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::TRANSLUCENTSINGLEHUE, 72);
  231.                         obj.xSpeed = 3*obj.direction;
  232.                         if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1))
  233.                         {obj.direction = obj.xSpeed = -obj.xSpeed;}
  234.         }
  235.  
  236.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ p, int force) {          
  237.                 if(p !is null && force >= -1)
  238.                         p.hurt();
  239.                 return true;
  240.         }
  241. }
  242.  
  243.  
  244. class MovingPurpleGem : jjBEHAVIORINTERFACE {
  245.  
  246.         void onBehave(jjOBJ@ obj) {
  247.                 obj.behave(BEHAVIOR::PICKUP, false);
  248.                 obj.lightType = LIGHT::LASER;
  249.                 obj.light = 200;
  250.                 ++obj.counter;
  251.                 obj.deactivates = false;
  252.                 if(obj.xPos < 110*32 && obj.findNearestPlayer(300*300) > -1)
  253.                 {obj.xPos = obj.xPos + 8;}
  254.                 if((obj.xPos > 110*32 && obj.findNearestPlayer(300*300) > -1) || p.xPos > 116*32)
  255.                 {obj.xPos = 360; obj.yPos = 46*32;}
  256.                 obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
  257.                 obj.draw();
  258. }
  259.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  260.                 p.gems[GEM::PURPLE] = 1;
  261.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  262.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_PICKUP1, 1000);
  263.  
  264.                 return true;
  265.         }
  266. }
  267.  
  268. class PlatinCoin : jjBEHAVIORINTERFACE {
  269.  
  270.         void onBehave(jjOBJ@ obj) {
  271.                 if(p.coins >= 3)
  272.                 {obj.delete();}
  273.                 obj.behave(BEHAVIOR::PICKUP, false);
  274.                 ++obj.counter;
  275.                 obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
  276.                 obj.determineCurAnim(ANIM::PICKUPS, 84);  
  277.                 obj.light = 100;
  278.                 obj.lightType = LIGHT::LASER;
  279.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -8);
  280. }
  281.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  282.                 p.coins += 1;
  283.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  284.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_COIN, 1000);
  285.                 jump = false;
  286.                 jjAddObject(OBJECT::CHICKENLEG, 6154, 1834);
  287.                 return true;
  288.         }
  289. }
  290.  
  291. class FreezeJazz: jjBEHAVIORINTERFACE {
  292.  
  293.         void onBehave(jjOBJ@ obj) {
  294.                 obj.determineCurAnim(ANIM::AMMO, 8);
  295.  
  296.                 obj.behave(BEHAVIOR::PICKUP, false);
  297.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::INVISIBLE);  
  298.         }
  299.  
  300.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) {
  301.         if(bullet is null) {
  302.                 play.freeze(true);
  303.                 play.hurt();
  304.                 obj.behave(BEHAVIOR::EXPLOSION2);
  305.                 obj.delete();
  306.         }      
  307.         return true;
  308.         }
  309. }
  310.  
  311.  
  312. class Ice: jjBEHAVIORINTERFACE {
  313.  
  314.         void onBehave(jjOBJ@ obj) {
  315.                 obj.behave(BEHAVIOR::INACTIVE, true);
  316.                 obj.draw();
  317.                 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::BOLLPLATFORM].curAnim];
  318.                 anim.frameCount = 1;
  319.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  320.                 jjPIXELMAP plat(0, 62*32, 1*32, 2*32, 5);
  321.                 plat.save(frame);
  322.                 frame.hotSpotX = -12;
  323.                 frame.hotSpotY = -17;
  324.         }      
  325.        
  326.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  327.                 if (bullet is null && (force == -1 || force == 1)) {
  328.                         jjAddObject(OBJECT::ICEAMMO3, obj.xPos, obj.yPos-40);
  329.                         jjSample(obj.xPos, obj.yPos, SOUND::COMMON_ICECRUSH, 1000);
  330.                         obj.delete();
  331.                         }
  332.                 if(bullet !is null)
  333.                         {obj.bulletHandling == HANDLING::DETECTBULLET;
  334.                         obj.causesRicochet = true;}
  335.                 return true;
  336.         }
  337. }
  338.  
  339. class IceR: jjBEHAVIORINTERFACE {
  340.  
  341.         void onBehave(jjOBJ@ obj) {
  342.                 obj.behave(BEHAVIOR::INACTIVE, true);
  343.                 obj.draw();
  344.                 obj.beSolid();
  345.                 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::FRUITPLATFORM].curAnim];
  346.                 anim.frameCount = 1;
  347.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  348.                 jjPIXELMAP plat(0, 60*32, 1*32, 2*32, 5);
  349.                 plat.save(frame);
  350.                 frame.hotSpotX = -12;
  351.                 frame.hotSpotY = -17;
  352.                
  353.         }
  354.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  355.                 if (bullet is null && (force == -1 || force == 1)) {
  356.                         jjSample(obj.xPos, obj.yPos, SOUND::COMMON_ICECRUSH, 1000);
  357.                         jjAddObject(OBJECT::ICEAMMO3, obj.xPos+40, obj.yPos+40);
  358.                         obj.behavior = BEHAVIOR::BURNING;
  359.                         }
  360.                 if(bullet !is null)
  361.                         {obj.bulletHandling == HANDLING::DETECTBULLET;
  362.                         obj.causesRicochet = true;}
  363.                 return true;
  364.         }
  365. }
  366.  
  367.  
  368. class FlyingSpring : jjBEHAVIORINTERFACE {
  369.  
  370.         void onBehave(jjOBJ@ obj) {
  371.                 float YSpeed = 22;
  372.                 obj.behave(BEHAVIOR::BUTTERFLY,false);
  373.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 40);
  374.  
  375.                 jjPARTICLE@ particle = jjAddParticle(PARTICLE::STAR);
  376.                 particle.snow.frame = jjRandom() & 987;
  377.                 particle.xPos = obj.xPos;
  378.                 particle.yPos = obj.yPos+14;
  379.         }
  380.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int) {
  381.                 if(bullet !is null) {
  382.                 obj.causesRicochet = true;
  383.                 }
  384.                 else
  385.                 player.direction = player.ySpeed = -42;
  386.                 obj.scriptedCollisions = true;
  387.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_SPRING1);
  388.                 return true;
  389.         }
  390. }
  391.  
  392. void PlatformH (jjOBJ@ obj) {
  393.  
  394.         switch (obj.state) {
  395.                 case STATE::START:
  396.                         obj.light = 10;
  397.                         obj.lightType = LIGHT::NORMAL;
  398.                         obj.direction = obj.xSpeed = -2;
  399.                         obj.determineCurAnim(ANIM::DESTSCEN, 4);  
  400.                         obj.determineCurFrame();
  401.                         obj.playerHandling = HANDLING::SPECIAL;
  402.                         obj.state = STATE::FLY;
  403.                         obj.beSolid();
  404.                 case STATE::FLY:
  405.                         obj.xPos = obj.xPos + obj.xSpeed;
  406.                         obj.beSolid();
  407.                         obj.deactivates = false;
  408.                         if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1)) {
  409.                                 obj.direction = obj.xSpeed = -obj.xSpeed;
  410.                         }
  411.                         jjDrawTile(obj.xPos - 17, obj.yPos - 32, 527);
  412.  
  413.                         break;
  414.  
  415.         }
  416. }
  417.  
  418. class GreenSw: jjBEHAVIORINTERFACE {
  419.  
  420.         void onBehave(jjOBJ@ obj) {
  421.                 obj.behave(BEHAVIOR::PLATFORM, false);
  422.                 obj.determineCurAnim(ANIM::SONICPLAT, 0);
  423.                 obj.determineCurFrame();
  424.                 ++obj.counter;
  425.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -56);
  426.         }
  427.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  428.                 if(p.keyFire){
  429.                 FireflyGreen = jjGameTicks + 26*61;
  430.                 p.timerStart(1500);            
  431.                 jjSample(obj.xPos, obj.yPos, SOUND::MENUSOUNDS_TYPEENTER, 1000);
  432.                 }      
  433.                 return true;
  434.         }
  435. }
  436.  
  437.  
  438. class RedSw: jjBEHAVIORINTERFACE {
  439.  
  440.         void onBehave(jjOBJ@ obj) {
  441.                 obj.behave(BEHAVIOR::PLATFORM, false);
  442.                 obj.determineCurAnim(ANIM::SONICPLAT, 0);
  443.                 obj.determineCurFrame();
  444.                 obj.frameID = ++obj.counter/6;
  445.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -48);
  446.         }
  447.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  448.                 if(p.keyFire){
  449.                 FireflyRed = jjGameTicks + 26*61;
  450.                 p.timerStart(1500);            
  451.                 jjSample(obj.xPos, obj.yPos, SOUND::MENUSOUNDS_TYPEENTER, 1000);
  452.                 }      
  453.                 return true;
  454.         }
  455. }
  456.  
  457. class BluSw : jjBEHAVIORINTERFACE {
  458.  
  459.         void onBehave(jjOBJ@ obj) {
  460.                 obj.behave(BEHAVIOR::PLATFORM, false);
  461.                 obj.determineCurAnim(ANIM::SONICPLAT, 0);
  462.                 obj.determineCurFrame();
  463.                 ++obj.counter;
  464.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -40);
  465.         }
  466.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  467.                 if(p.keyFire){
  468.                 FireflyBlu = jjGameTicks + 26*61;
  469.                 p.timerStart(1500);            
  470.                 jjSample(obj.xPos, obj.yPos, SOUND::MENUSOUNDS_TYPEENTER, 1000);
  471.                 }      
  472.                 return true;
  473.         }
  474. }
  475.  
  476. void RedFF (jjOBJ@ obj) {
  477.                         obj.determineCurAnim(ANIM::BEEBOY, 0);  
  478.                         obj.determineCurFrame();
  479.                         obj.frameID = ++obj.counter/6;
  480.         switch (obj.state) {
  481.                 case STATE::START:
  482.                         obj.direction = obj.ySpeed = 2;
  483.                         obj.state = STATE::ACTION;
  484.                 case STATE::ACTION:
  485.                         obj.energy = 1;
  486.                         if(jjKey[0x57] && FireflyRed > jjGameTicks) {
  487.                         obj.yPos = obj.yPos + obj.ySpeed;
  488.                         obj.ySpeed = -2;}
  489.                         if(jjKey[0x53] && FireflyRed > jjGameTicks) {
  490.                         obj.yPos = obj.yPos + obj.ySpeed;
  491.                         obj.ySpeed = 2;}
  492.                         if(jjKey[0x41] && FireflyRed > jjGameTicks){
  493.                         obj.xPos = obj.xPos + obj.xSpeed;
  494.                         obj.direction = obj.xSpeed = -2;}
  495.                         if(jjKey[0x44] && FireflyRed > jjGameTicks){
  496.                         obj.xPos = obj.xPos + obj.xSpeed;
  497.                         obj.direction = obj.xSpeed = 2;}
  498.                         if((jjKey[0x30] || jjKey[0x60]) && FireflyRed > jjGameTicks)
  499.                         {obj.yPos = obj.yPos + obj.ySpeed;
  500.                         obj.ySpeed = 0.3;
  501.                         obj.xPos = obj.xPos + obj.xSpeed;
  502.                         obj.xSpeed = 0.3*obj.direction;
  503.                         p.cameraFreeze(obj.xPos, obj.yPos, true, true);
  504.                         jjOBJ@ o = jjObjects[obj.fireBullet(OBJECT::FIREBALLBULLET)];
  505.                                         o.behavior = BEHAVIOR::BULLET;
  506.                                         o.determineCurAnim(ANIM::AMMO, 14);
  507.                                         o.killAnim = jjObjectPresets[OBJECT::BOUNCERBULLET].killAnim;
  508.                                         o.playerHandling = HANDLING::PLAYERBULLET;
  509.                                         o.bulletHandling = HANDLING::HURTBYBULLET;
  510.                                         o.lightType = LIGHT::POINT;
  511.                                         o.xPos = obj.xPos +6*obj.direction;
  512.                                         o.xAcc = .9;
  513.                                         int xs = (jjRandom() & 9);
  514.                                         o.xSpeed = 1.2;
  515.                                         int ys = (jjRandom() & 6);
  516.                                         o.ySpeed = ys - 3;}
  517.                         else if(FireflyRed > jjGameTicks) {
  518.                         p.xSpeed = 0;
  519.                         p.cameraFreeze(obj.xPos, obj.yPos, true, true);
  520.                         obj.yPos = obj.yPos + obj.ySpeed;
  521.                         obj.ySpeed = 0.3;
  522.                         obj.xPos = obj.xPos + obj.xSpeed;
  523.                         obj.xSpeed = 0.3*obj.direction;
  524.                         p.idle = 0;
  525. }
  526.                 if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1) || FireflyRed == jjGameTicks +1*61 || jjKey[0x5A]) {
  527.                         obj.behavior = BEHAVIOR::EXPLOSION2;
  528.                         obj.delete();
  529.                         p.cameraUnfreeze();
  530.                         FireflyRed = 0;
  531.                         p.timerStop();
  532.                         p.yPos = p.yPos -40;
  533.                         }
  534.                         obj.deactivates = false;
  535.                         break;
  536.         }
  537.  
  538.                         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::SINGLEHUE, 40);
  539. }
  540.  
  541. void GreenFF (jjOBJ@ obj) {
  542.                         obj.determineCurAnim(ANIM::BEEBOY, 0);  
  543.                         obj.determineCurFrame();
  544.                         obj.frameID = ++obj.counter/6;
  545.  
  546.         switch (obj.state) {
  547.                 case STATE::START:
  548.                         obj.state = STATE::ACTION;
  549.                         obj.direction = obj.ySpeed = -2;       
  550.                 case STATE::ACTION:
  551.                         obj.energy = 1;
  552.                         if(jjKey[0x57] && FireflyGreen > jjGameTicks) {
  553.                         obj.yPos = obj.yPos + obj.ySpeed;
  554.                         obj.ySpeed = -2;}
  555.                         if(jjKey[0x53] && FireflyGreen > jjGameTicks) {
  556.                         obj.yPos = obj.yPos + obj.ySpeed;
  557.                         obj.ySpeed = 2;}
  558.                         if(jjKey[0x41] && FireflyGreen > jjGameTicks){
  559.                         obj.xPos = obj.xPos + obj.xSpeed;
  560.                         obj.direction = obj.xSpeed = -2;}
  561.                         if(jjKey[0x44] && FireflyGreen > jjGameTicks){
  562.                         obj.xPos = obj.xPos + obj.xSpeed;
  563.                         obj.direction = obj.xSpeed = 2;}
  564.                         if((jjKey[0x30] || jjKey[0x60]) && FireflyGreen > jjGameTicks)
  565.                         {obj.yPos = obj.yPos + obj.ySpeed;
  566.                         obj.ySpeed = 0.3;
  567.                         obj.xPos = obj.xPos + obj.xSpeed;
  568.                         obj.xSpeed = -0.3*obj.direction;
  569.                         p.cameraFreeze(obj.xPos, obj.yPos, true, true);
  570.                         jjOBJ@ o = jjObjects[obj.fireBullet(OBJECT::FIREBALLBULLET)];
  571.                                         o.behavior = BEHAVIOR::BULLET;
  572.                                         o.determineCurAnim(ANIM::AMMO, 11);
  573.                                         o.killAnim = jjObjectPresets[OBJECT::BOUNCERBULLET].killAnim;
  574.                                         o.playerHandling = HANDLING::PLAYERBULLET;
  575.                                         o.bulletHandling = HANDLING::HURTBYBULLET;
  576.                                         o.lightType = LIGHT::POINT;
  577.                                         o.xPos = obj.xPos +6*obj.direction;
  578.                                         o.xAcc = .9;
  579.                                         int xs = (jjRandom() & 9);
  580.                                         o.xSpeed = 1.2;
  581.                                         int ys = (jjRandom() & 6);
  582.                                         o.ySpeed = ys - 3;}
  583.                         else if(FireflyGreen > jjGameTicks) {
  584.                         p.xSpeed = 0;
  585.                         p.cameraFreeze(obj.xPos, obj.yPos, true, true);
  586.                         obj.yPos = obj.yPos + obj.ySpeed;
  587.                         obj.ySpeed = 0.3*obj.direction;
  588.                         obj.xPos = obj.xPos + obj.xSpeed;
  589.                         obj.xSpeed = 0.3*obj.direction;
  590.                         p.idle = 0;
  591. }
  592.                 if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1) || FireflyGreen == jjGameTicks +1*61 || jjKey[0x5A]) {
  593.                         obj.behavior = BEHAVIOR::EXPLOSION2;
  594.                         obj.delete();
  595.                         p.cameraUnfreeze();
  596.                         FireflyGreen = 0;
  597.                         p.timerStop();
  598.                         p.yPos = p.yPos -40;
  599.                         }
  600.  
  601.                         obj.deactivates = false;
  602.                         break;
  603.         }
  604.                         {jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::SINGLEHUE, 16);}
  605.  
  606. }
  607.  
  608. void BluFF (jjOBJ@ obj) {
  609.                         obj.determineCurAnim(ANIM::BEEBOY, 0);  
  610.                         obj.determineCurFrame();
  611.                         obj.determineCurFrame();
  612.                         obj.frameID = ++obj.counter/6;
  613.         switch (obj.state) {
  614.                 case STATE::START:
  615.                         obj.direction = obj.ySpeed = 2;
  616.                         obj.state = STATE::ACTION;
  617.                 case STATE::ACTION:
  618.                         obj.energy = 1;
  619.                         if(jjKey[0x57] && FireflyBlu > jjGameTicks) {
  620.                         obj.yPos = obj.yPos + obj.ySpeed;
  621.                         obj.ySpeed = -2;}
  622.                         if(jjKey[0x53] && FireflyBlu > jjGameTicks) {
  623.                         obj.yPos = obj.yPos + obj.ySpeed;
  624.                         obj.ySpeed = 2;}
  625.                         if(jjKey[0x41] && FireflyBlu > jjGameTicks){
  626.                         obj.xPos = obj.xPos + obj.xSpeed;
  627.                         obj.direction = obj.xSpeed = -2;}
  628.                         if(jjKey[0x44] && FireflyBlu > jjGameTicks){
  629.                         obj.xPos = obj.xPos + obj.xSpeed;
  630.                         obj.direction = obj.xSpeed = 2;}
  631.                         if((jjKey[0x30] || jjKey[0x60]) && FireflyBlu > jjGameTicks)
  632.                         {obj.yPos = obj.yPos + obj.ySpeed;
  633.                         obj.ySpeed = 0.3;
  634.                         obj.xPos = obj.xPos + obj.xSpeed;
  635.                         obj.xSpeed = 0.3*obj.direction;
  636.                         p.cameraFreeze(obj.xPos, obj.yPos, true, true);
  637.                         jjOBJ@ o = jjObjects[obj.fireBullet(OBJECT::FIREBALLBULLET)];
  638.                                         o.behavior = BEHAVIOR::BULLET;
  639.                                         o.determineCurAnim(ANIM::DEVILDEVAN, 17);
  640.                                         o.killAnim = jjObjectPresets[OBJECT::BOUNCERBULLET].killAnim;
  641.                                         o.playerHandling = HANDLING::PLAYERBULLET;
  642.                                         o.bulletHandling = HANDLING::HURTBYBULLET;
  643.                                         o.lightType = LIGHT::POINT;
  644.                                         o.xPos = obj.xPos +6*obj.direction;
  645.                                         o.xAcc = .9;
  646.                                         int xs = (jjRandom() & 9);
  647.                                         o.xSpeed = 1.2;
  648.                                         int ys = (jjRandom() & 6);
  649.                                         o.ySpeed = ys - 3;}
  650.                         else if(FireflyBlu > jjGameTicks) {
  651.                         p.xSpeed = 0;
  652.                         p.cameraFreeze(obj.xPos, obj.yPos, true, true);
  653.                         obj.yPos = obj.yPos + obj.ySpeed;
  654.                         obj.ySpeed = 0.3;
  655.                         obj.xPos = obj.xPos + obj.xSpeed;
  656.                         obj.xSpeed = 0.3*obj.direction;
  657.                         p.idle = 0;
  658. }
  659.                 if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1) || FireflyBlu == jjGameTicks +1*61 || jjKey[0x5A]) {
  660.                         obj.behavior = BEHAVIOR::EXPLOSION2;
  661.                         obj.delete();
  662.                         p.cameraUnfreeze();
  663.                         FireflyBlu = 0;
  664.                         p.timerStop();
  665.                         p.yPos = p.yPos -40;
  666.                         }
  667.                         obj.deactivates = false;
  668.                         break;
  669.         }
  670.  
  671.                         {jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::SINGLEHUE, 32);}
  672.  
  673. }
  674.  
  675. void onFunction0(jjPLAYER@ p)
  676. {if(jump == false && p.coins < 3)
  677.                 p.activateBoss();
  678.                 p.boss = jjAddObject(OBJECT::MILK, 139*32, 53*32);
  679.                 jjOBJ@ boss = jjObjects[p.boss];
  680.                 p.cameraFreeze(137*32, 53*32, true, false);
  681.                 jjEnabledASFunctions[0] = false;
  682. }
  683.  
  684. void onFunction4(jjPLAYER@ p)
  685. {p.cameraUnfreeze();}
  686.  
  687. void onFunction5(jjPLAYER@ p) {
  688.         if(jjTriggers[1] == true && jjTriggers[2] == true && jjTriggers[3] == true && jjTriggers[4] == false) {
  689.                 jjTriggers[4]=true;
  690.                 jjSample(p.xPos, p.yPos, SOUND::INTRO_MONSTER2, 1000);}
  691.         else
  692.                 {p.showText("@@To open the gate@three switches must be activated.");}
  693. }
  694.  
  695. void onFunction6(jjPLAYER@ p) {
  696.                 if(coinchange == true) {
  697.                 jjAddObject(OBJECT::GOLDCOIN, 6128, 1932);
  698.                 p.showText("@@Yay!");
  699.                 jjSample(p.xPos, p.yPos, SOUND::WITCH_MAGIC, 3000);
  700.                 coinready = true;
  701.                 coinchange = false;}
  702. }
  703.  
  704.  
  705. class FakeCoin : jjBEHAVIORINTERFACE {
  706.        
  707.         void onBehave(jjOBJ@ obj) {
  708.                 if(p.coins == 3)
  709.                 {obj.delete();}
  710.                 obj.behave(BEHAVIOR::PICKUP, false);
  711.                 obj.determineCurAnim(ANIM::PICKUPS, 37);
  712.                 ++obj.counter;
  713.                 obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
  714.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::BRIGHTNESS, 52);}
  715.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  716.                 coinchange = true;
  717.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  718.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_COIN, 1000);
  719.  
  720.                 return true;
  721.         }
  722. }
  723.  
  724. bool walltext = false;
  725.  
  726. class WallJump : jjBEHAVIORINTERFACE {
  727.        
  728.         void onBehave(jjOBJ@ obj) {
  729.                 if(jump==false) {
  730.                 obj.light = 100;
  731.                 obj.lightType = LIGHT::LASER;
  732.                 obj.behave(BEHAVIOR::PICKUP, false);
  733.                 obj.determineCurAnim(ANIM::PICKUPS, 33);
  734.                 ++obj.counter;
  735.                 obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
  736.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 24);}
  737.                 if(jump==true) {obj.delete();}
  738.         }
  739.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  740.         if(p.xPos < 167*32) {
  741.                 jump = true;
  742.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  743.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_PICKUP1, 1000);
  744.                 }
  745.         if(p.xPos > 167*32) {  
  746.                 jump = false;
  747.                 if(walltext == false)
  748.                 {p.showText("@@I gave the shoe to return the favour.@I'm not looking for trouble.");}
  749.                 walltext = true;
  750.         }
  751.                 return true;
  752.         }
  753. }
  754.  
  755.  
  756. void Yeti(jjOBJ@ enemy) {
  757.         switch (enemy.state) {
  758.                 case STATE::START:
  759.                 enemy.state = STATE::ACTION;
  760.                         break;
  761.                 case STATE::ACTION:
  762.  
  763.                 enemy.putOnGround(false);
  764.                                 if (jjLocalPlayers[0].xPos < enemy.xPos) enemy.direction = -1;
  765.                                 else enemy.direction = 1;
  766.                         if ((jjRandom() & 1) == 0) {
  767.                                 enemy.state = STATE::ATTACK;
  768.                                 enemy.frameID = 0;
  769.                                 enemy.counter = 0;
  770.                                 jjSample(enemy.xPos, enemy.yPos, SOUND::COMMON_SWISH8);
  771.                         } else {
  772.                                 if (++enemy.counter > 6) {
  773.                                         enemy.counter = 0;
  774.                                         if (++enemy.frameID >= 11)
  775.                                                 enemy.frameID = 0;
  776.  
  777.                                 }
  778.                         }
  779.                         break;
  780.                 case STATE::ATTACK:
  781.  
  782.                         if (++enemy.counter > 4) {
  783.                                 enemy.counter = 0;
  784.                                 if (++enemy.frameID >= 11) {
  785.                                 jjObjectPresets[OBJECT::TUFTURT].determineCurAnim(ANIM::TUFBOSS, 2);
  786.                                         enemy.state = STATE::ACTION;
  787.  
  788.                                 } else if (enemy.frameID >= 0 && enemy.frameID <= 11) {
  789.  
  790.                                         enemy.determineCurAnim(ANIM::TUFBOSS, 1);
  791.                                         jjOBJ@ obj = jjObjects[enemy.fireBullet(OBJECT::BLASTERBULLET)];
  792.                                         obj.behavior = BEHAVIOR::BULLET;
  793.                                         obj.determineCurAnim(ANIM::AMMO, 30);
  794.                                         obj.killAnim = jjObjectPresets[OBJECT::BOUNCERBULLET].killAnim;
  795.                                         obj.playerHandling = HANDLING::ENEMYBULLET;
  796.                                         obj.bulletHandling = HANDLING::IGNOREBULLET;
  797.                                         obj.lightType = LIGHT::POINT;
  798.                                         obj.xAcc = .9;
  799.                                         int xs = (jjRandom() & 9);
  800.                                         obj.xSpeed = 1.2;
  801.                                         int ys = (jjRandom() & 6);
  802.                                         obj.ySpeed = ys - 3;
  803.                                         obj.counterEnd = 55;
  804.                                         if(p.xPos == obj.xPos && p.yPos == obj.yPos)
  805.                                         {p.freeze();}
  806.                                 }
  807.                                 enemy.determineCurFrame();
  808.                         }
  809.                         break;
  810.                 case STATE::DEACTIVATE:
  811.                 case STATE::KILL:
  812.                         enemy.delete();
  813.                         break;
  814. }
  815.         if(enemy.justHit == 0)
  816.         {jjDrawSpriteFromCurFrame(enemy.xPos, enemy.yPos, enemy.curFrame, enemy.direction, SPRITE::PALSHIFT, 24);}
  817. else enemy.draw();
  818.        
  819. }
  820.  
  821. void onMain() {
  822. gem::deleteCollectedGems();
  823. if(jjKey[9] && jjKey[0x51]) {
  824. p.morphTo(CHAR::JAZZ, false);
  825. }
  826. if(jjKey[9] && jjKey[0x57]) {
  827. p.morphTo(CHAR::SPAZ, false);
  828. }
  829. if(jjKey[9] && jjKey[0x45]) {
  830. p.morphTo(CHAR::LORI, false);
  831. }
  832. }
  833.  
  834. void onLevelReload() {
  835.         MLLE::Palette.apply();
  836.         gem::restorePlayerGems();
  837.         jjLocalPlayers[0].lives++;
  838.         jjWaterLighting = WATERLIGHT::GLOBAL;
  839.         for (uint i = 0; i < 32; ++i)
  840.                 jjTriggers[i] = SavedTriggers[i];
  841.         if(p.coins >= 3)
  842.                 {jjAddObject(OBJECT::CHICKENLEG, 6154, 1834);}
  843.         if(jump == false && p.coins < 3)
  844.                 {jjEnabledASFunctions[0] = true;}
  845. }
  846.  
  847. class PlayerWallJumpProperties {
  848.   uint Stage = 0;
  849.   bool FacingRight;
  850.   int LastSlidingTick = 0;
  851.   bool PressingJumpOneTickAgo = false;
  852.   PlayerWallJumpProperties(){}
  853. }
  854. array<PlayerWallJumpProperties> PlayerWallJumpPropertiesArray(jjLocalPlayerCount);
  855.  
  856. bool doorunblocked = false, startrush = false, readytorush = false, control = true;
  857.  
  858. void onPlayer(jjPLAYER@ play) {
  859.         gem::trackPlayerGems(p);
  860.         gem::upgradeHealth(p);
  861.         if(p.coins == 0)
  862.         {p.coins += 2;}
  863.         p.lightType = LIGHT::NONE;
  864.  
  865.         jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::EXTRALIFE].curAnim];
  866.         anim.frameCount = 1;
  867.         jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  868.         jjPIXELMAP fruit(0, 35*32, 1*32, 1*32, 5);
  869.         fruit.save(frame);
  870.  
  871.                 if(control==false)
  872.                 {p.keyLeft = false;
  873.                 p.keyRight = false;
  874.                 p.keyDown = false;}
  875.  
  876.                 if(p.idle > 100 && p.xPos < 223*32)
  877.                 {p.cameraUnfreeze(true);
  878.                 control=true;}
  879.                 else if (p.idle > 5 && (p.keyLeft || p.keyRight || p.keyJump || p.keyFire))
  880.                 {p.cameraUnfreeze(true);
  881.                 control=true;}
  882.  
  883.         exit = 0;
  884.         if(jjTriggers[1] == true)
  885.                 {exit += 1;}
  886.         if(jjTriggers[2] == true)
  887.                 {exit += 1;}
  888.         if(jjTriggers[3] == true)
  889.                 {exit += 1;}
  890.  
  891.  
  892.         if(p.food == 100 && jjKey[0x52] == false && startrush == false)
  893.                 {p.showText("@@@@@@@@@@@@@@@@Press 'R' when you need to use Sugar Rush!", STRING::MEDIUM);
  894.                 p.startSugarRush(0);
  895.                 startrush = true;
  896.                 readytorush = true;}
  897.  
  898.         if(readytorush == true)
  899.                 {p.food = 100;}
  900.  
  901.         if(p.food == 100 && jjKey[0x52])
  902.                 {p.startSugarRush(1400);
  903.                 p.food = 0;
  904.                 readytorush = false;
  905.                 startrush = false;
  906.         }
  907.  
  908.  
  909.         for (int i = 1; i < jjObjectCount; i++) {
  910.                 jjOBJ@ o = jjObjects[i];
  911.                 if (o.isActive && o.eventID == OBJECT::SEEKERAMMO3 && p.ammo[WEAPON::SEEKER] < 1) {
  912.                         o.state = STATE::KILL;}
  913.         }
  914.         for (int i = 1; i < jjObjectCount; i++) {
  915.                 jjOBJ@ o = jjObjects[i];
  916.                 if (o.isActive && o.eventID == OBJECT::RFAMMO3 && p.ammo[WEAPON::RF] < 1) {
  917.                         o.state = STATE::KILL;}
  918.         }
  919.         for (int i = 1; i < jjObjectCount; i++) {
  920.                 jjOBJ@ o = jjObjects[i];
  921.                 if (o.isActive && o.eventID == OBJECT::TNTAMMO3 && p.ammo[WEAPON::TNT] < 1) {
  922.                         o.state = STATE::KILL;}
  923.         }
  924.         for (int i = 1; i < jjObjectCount; i++) {
  925.                 jjOBJ@ o = jjObjects[i];
  926.                 if (o.isActive && o.eventID == OBJECT::GUN9AMMO3 && p.ammo[WEAPON::GUN9] < 1) {
  927.                         o.state = STATE::KILL;}
  928.         }
  929.         for (int i = 1; i < jjObjectCount; i++) {
  930.                 jjOBJ@ o = jjObjects[i];
  931.                 if (o.isActive && o.eventID == OBJECT::SEEKERPOWERUP && p.ammo[WEAPON::SEEKER] < 1) {
  932.                         o.state = STATE::KILL;}
  933.         }
  934.         for (int i = 1; i < jjObjectCount; i++) {
  935.                 jjOBJ@ o = jjObjects[i];
  936.                 if (o.isActive && o.eventID == OBJECT::RFPOWERUP && p.ammo[WEAPON::RF] < 1) {
  937.                         o.state = STATE::KILL;}
  938.         }
  939.         for (int i = 1; i < jjObjectCount; i++) {
  940.                 jjOBJ@ o = jjObjects[i];
  941.                 if (o.isActive && o.eventID == OBJECT::TNTPOWERUP && p.ammo[WEAPON::TNT] < 1) {
  942.                         o.state = STATE::KILL;}
  943.         }
  944.         for (int i = 1; i < jjObjectCount; i++) {
  945.                 jjOBJ@ o = jjObjects[i];
  946.                 if (o.isActive && o.eventID == OBJECT::GUN9POWERUP && p.ammo[WEAPON::GUN9] < 1) {
  947.                         o.state = STATE::KILL;}
  948.         }
  949.  
  950.         if(p.yPos > jjWaterLevel)
  951.         {play.hurt();}
  952.  
  953.                 if (doorunblocked == false && jjTriggers[1] == true && jjTriggers[2] == true && jjTriggers[3] == true) {
  954.                 p.showText("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Switches unlocked.");
  955.                 p.cameraFreeze(69*32 ,57*32, true, false);
  956.                 doorunblocked = true;}
  957.  
  958.         if(p.coins<3 && p.xPos < 11*32 && p.xPos > 5*32 && p.yPos > 62*32)
  959.         {p.testForCoins(3);
  960.         p.yPos = 58*32;
  961.         p.xPos = 6*32;}
  962.         if(p.coins>=3 && p.xPos < 11*32 && p.xPos > 5*32 && p.yPos > 62*32)
  963.         {jjNxt(false, true);}
  964.  
  965.         if(p.keyUp && jjTriggers[1] == false && p.yPos >6*32 && p.yPos <8*32 && p.xPos > 123*32 && p.xPos <126*32)
  966.                 {jjTriggers[1] = true;
  967.                 jjSample(p.xPos, p.yPos, SOUND::INTRO_MONSTER2);}
  968.         if(p.keyUp && jjTriggers[2] == false && p.yPos >20*32 && p.xPos > 51*32 && p.xPos <53*32)
  969.                 {jjTriggers[2] = true;
  970.                 jjSample(p.xPos, p.yPos, SOUND::INTRO_MONSTER2);}
  971.         if(p.keyUp && jjTriggers[3] == false && p.yPos >30*32 && p.yPos < 32*32 && p.xPos >203*32)
  972.                 {jjTriggers[3] = true;
  973.                 jjSample(p.xPos, p.yPos, SOUND::INTRO_MONSTER2);}
  974.  
  975.  
  976.         if (FireflyRed > jjGameTicks || FireflyGreen > jjGameTicks || FireflyBlu > jjGameTicks) {
  977.         p.keyRight = p.keyLeft = p.keyJump = p.keyRun = p.keyFire = false;
  978.         }
  979.  
  980. // Wall Jump snippet by VioletCLM
  981. PlayerWallJumpProperties@ wallJumpProperties = @PlayerWallJumpPropertiesArray[play.localPlayerID];
  982.   const bool pressingJump = play.keyJump;
  983.   if (jump == true &&
  984.     pressingJump &&
  985.     !wallJumpProperties.PressingJumpOneTickAgo &&
  986.     wallJumpProperties.Stage < 2 &&
  987.     (jjGameTicks - wallJumpProperties.LastSlidingTick) < 10 //10 = number of ticks after technically letting go of the wall during which you can still start the jump. Higher numbers are more generous.
  988.   ) {
  989.     wallJumpProperties.Stage = 2;
  990.     jjSample(play.xPos, play.yPos, SOUND::COMMON_JUMP);
  991.     play.ySpeed = play.jumpStrength;
  992.     play.helicopter = 0;
  993.     play.doubleJumpCount = 0;
  994.   } else if (wallJumpProperties.Stage > 1) {
  995.     if (++wallJumpProperties.Stage == 20)
  996.       wallJumpProperties.Stage = 0;
  997.     else {
  998.       play.keyRight = wallJumpProperties.FacingRight;
  999.       play.keyLeft = !wallJumpProperties.FacingRight;
  1000.       play.keyJump = true;
  1001.       play.helicopter = 0;
  1002.     }
  1003.   } else {
  1004.     const auto anim = play.curAnim - jjAnimSets[play.setID];
  1005.     const int xPosToTest = int(play.xPos) + (play.keyRight ? 13 : -13);
  1006.     uint16 tileIDToTest;
  1007.     if (jump == true &&
  1008.       (anim == RABBIT::FALL || anim == RABBIT::HELICOPTER) &&
  1009.       (play.keyRight || play.keyLeft) &&
  1010.       (jjMaskedPixel(xPosToTest, int(play.yPos)-8) && jjMaskedPixel(xPosToTest, int(play.yPos)+8))
  1011.       //put any additional conditions, e.g. events or tiles you can't slide on, here.
  1012.     ) {
  1013.       play.helicopter = 0;
  1014.       wallJumpProperties.Stage = 1;
  1015.       wallJumpProperties.FacingRight = play.keyLeft;
  1016.       play.ySpeed = 0.25; //modify as desired if you don't like this sliding speed
  1017.       play.keyJump = false;
  1018.       wallJumpProperties.LastSlidingTick = jjGameTicks;
  1019.     } else if (wallJumpProperties.Stage == 1)
  1020.       wallJumpProperties.Stage = 0;
  1021.   }
  1022.   if (play.invisibility = wallJumpProperties.Stage == 1) { //this works for SP, but for MP you'd probably instead want to give everyone SPRITE::INVISIBLE all the time and draw non-local players in an onMain loop.
  1023.     if (play.blink == 0 || ((jjRenderFrame >> 2) & 1) == 1) {
  1024.       const int vDir = !play.antiGrav ? 1 : -1;
  1025.       jjDrawRotatedSprite(play.xPos - play.direction * 3, play.yPos, play.setID, RABBIT::SKID1, jjGameTicks>>4, 256 * play.direction * vDir, -play.direction, vDir, SPRITE::PLAYER, play.playerID);
  1026.     }
  1027.   }
  1028.   wallJumpProperties.PressingJumpOneTickAgo = pressingJump;
  1029. }
  1030. bool onDrawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) {
  1031.         return MLLE::WeaponHook.drawAmmo(player, canvas);
  1032. }
  1033.  
  1034. array<bool> SavedTriggers(32, false);
  1035. //Extendable Checkpoints by VioletCLM
  1036. void CheckpointWrapper(jjOBJ@ obj) {
  1037.   if (obj.state == STATE::STOP) { //don't do anything anymore
  1038.     jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 8);
  1039.   } else if (obj.state == STATE::DEACTIVATE) { //due to death
  1040.     obj.deactivate();
  1041.   } else {
  1042.     obj.behave(BEHAVIOR::CHECKPOINT);
  1043.         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 8);
  1044.     if (obj.state == STATE::DONE) { //triggered by the player hitting it
  1045.       obj.state = STATE::STOP;
  1046.       //save the current state of some properties
  1047.       for (uint i = 0; i < 32; ++i)
  1048.         SavedTriggers[i] = jjTriggers[i];
  1049.  
  1050.       //OPTIONAL: this loop makes checkpoints reusable, so only the most recent checkpoint you touched is ever active
  1051.       for (int i = jjObjectCount; --i > 0;) {
  1052.         jjOBJ@ obj2 = jjObjects[i];
  1053.         if (obj2.eventID == OBJECT::CHECKPOINT && i != obj.objectID && obj2.isActive) {
  1054.           obj2.state = STATE::SLEEP;
  1055.           obj2.var[0] = 0;
  1056.         }
  1057.       }
  1058.     }
  1059.   }
  1060. }
  1061.  
  1062. jjTEXTAPPEARANCE SignTextAppearance = STRING::NORMAL;
  1063. class Sign {
  1064.         private int xPos, yPos; //These pixel-based positions will be generated from tile-based positions in the constructor by multiplying by 32
  1065.         private string text;
  1066.         private uint widthOfText;
  1067.         Sign(){} //AngelScript requires any class that appears in any array to have an explicit default constructor, even if it's never called
  1068.         Sign(int xTile, int yTile, const string &in t) {
  1069.                 xPos = xTile * 32; //Since this is a constant operation, it could strictly be performed in the draw method instead of the constructor, but this way involves fewer multiplication instructions
  1070.                 yPos = yTile * 32; //
  1071.                 text = t;
  1072.                 SignTextAppearance.newline = STRING::SPECIALSIGN; //Causes the drawString method to interpret instances of the \n character as signals to drop down to a new line, similar to the special effect of the @ character in the STRING::SPIN appearance.
  1073.                 SignTextAppearance.spacing = -2; //int jjTEXTAPPEARANCE::spacing is new in 5.2, and this particular value is equivalent to prefixing the string with "ยง2". Make sure to check out bool jjTEXTAPPEARANCE::monospace too, though it didn't end up getting used in this level.
  1074.                 widthOfText = jjGetStringWidth(text, STRING::SMALL, SignTextAppearance); //Used for determining how large of a dark rectangle should be drawn behind the text. A matching heightOfText value could of course be generated by counting the number of newline characters--for example, "heightOfText = text.split("\n").length * 20;"--but here the rectangles are constant height instead to limit the temptation to ramble on and on.
  1075.         }
  1076.         void draw(jjCANVAS@ layer, uint8 textIntensity) const { //Because this method will be called from an onDraw method, it's important to have a jjCANVAS@ passed among the arguments.
  1077.                 layer.drawRectangle(xPos, yPos - 16, widthOfText + 8, 55, 0, SPRITE::TRANSLUCENT);
  1078.                 layer.drawString(xPos, yPos, text, STRING::SMALL, SignTextAppearance, 0, SPRITE::BLEND_HARDLIGHT, textIntensity);
  1079.         }
  1080. }
  1081. const array<Sign> Signs = {
  1082.         Sign(17, 59, "The demons have destroyed the last token.\n Maybe the Alchemist can help you..."),
  1083.         Sign(144, 55, "Try to avoid Demon Ghosts.\nThey are invincible."),
  1084.         Sign(193, 60, "Bring me something coppery I'll turn it\ninto anything! But I'll take your shoe."),
  1085.         Sign(160, 31, "Psst! Looking for a token?\nYou won't find any!"),
  1086.         Sign(96, 48, "Neither stand on thin ice\nnor try swimming. You might freeze."),
  1087.         Sign(36, 58, "With some pink shoes on\nyou can wall jump."),
  1088.  
  1089.  
  1090. };
  1091.  
  1092. void onDrawLayer3(jjPLAYER@, jjCANVAS@ layer) {
  1093.         if((jjKey[0x54] && p.xPos <172*32)||(jjKey[0x54] && p.xPos>172*32 && coinchange == false)){
  1094.         const uint8 textIntensity = 200 + int(jjSin(jjGameTicks * 16) * 50);
  1095.         for (uint signID = 0; signID < Signs.length; ++signID)
  1096.                 Signs[signID].draw(layer, textIntensity);
  1097. }
  1098. }
  1099.  
  1100.