Downloads containing mo4a_2-4.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, DefaultWeapons::Blaster(), DefaultWeapons::Blaster(), WeaponVMega::Backfire::Weapon(), null, DefaultWeapons::Blaster(), null, ArcaneWeapons::MortarLauncher::Weapon()}); ///@MLLE-Generated
  2. #include "MLLE-Include-1.5w.asc" ///@MLLE-Generated
  3. #pragma require "mo4a_2-4.j2l" ///@MLLE-Generated
  4. #include "ArcaneWeapon4.asc" ///@MLLE-Generated
  5. #pragma require "ArcaneWeapon4.asc" ///@MLLE-Generated
  6. #include "WeaponVMega5.asc" ///@MLLE-Generated
  7. #pragma require "WeaponVMega5.asc" ///@MLLE-Generated
  8. #include "MLLE-DefaultWeapons.asc" ///@MLLE-Generated
  9. #pragma require "MLLE-DefaultWeapons.asc" ///@MLLE-Generated
  10. bool boss = false;
  11. #include "Jazz1Enemies v05.asc"
  12. #include "Resize v11.asc"
  13. #include "TrueColor v13.asc"
  14. #include "HH18savegems.asc"
  15. int torch = 0;
  16. bool torch11 = false; bool torch12 = false; bool torch13 = false; bool torch14 = false; bool torch15 = false; bool torch16 = false; bool torch17 = false; bool lever = false;
  17. int SuperCopterOn = 0;
  18.  
  19.  
  20. void onLevelLoad()  {
  21.  
  22.         gem::restorePlayerGems();
  23.  
  24.  
  25.         jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::BANANA].curAnim];
  26.                 anim.frameCount = 1;  
  27.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  28.                 jjPIXELMAP pump(0, 33*32, 1*32, 1*32, 5);
  29.                 pump.save(frame);
  30.         jjLevelName = ("@@@@@@@@@Sahara Desert");
  31.  
  32.         jjObjectPresets[OBJECT::SAVEPOST].behavior = CheckpointWrapper;
  33.         jjObjectPresets[OBJECT::SAVEPOST].deactivates = false;
  34.  
  35.         jjObjectPresets[OBJECT::HAM].behavior = FakeFreezer();
  36.         jjObjectPresets[OBJECT::HAM].scriptedCollisions = true;
  37.         jjObjectPresets[OBJECT::HAM].determineCurAnim(ANIM::PICKUPS, 42);
  38.         jjObjectPresets[OBJECT::HAM].determineCurFrame();
  39.  
  40.         jjObjectPresets[OBJECT::BIGROCK].deactivates = false;
  41.  
  42.         jjObjectPresets[OBJECT::SONICPLATFORM].scriptedCollisions = true;
  43.         jjObjectPresets[OBJECT::SONICPLATFORM].behavior = SpikeBump();
  44.         jjObjectPresets[OBJECT::SONICPLATFORM].deactivates = false;
  45.  
  46.         jjObjectPresets[OBJECT::BOLLPLATFORM].scriptedCollisions = true;
  47.         jjObjectPresets[OBJECT::BOLLPLATFORM].behavior = PlatformV;
  48.         jjObjectPresets[OBJECT::BOLLPLATFORM].deactivates = false;
  49.  
  50.         jjObjectPresets[OBJECT::DRAGON].behavior = BigDragon;
  51.         jjObjectPresets[OBJECT::DRAGON].playerHandling = HANDLING::ENEMY;
  52.         jjObjectPresets[OBJECT::DRAGON].bulletHandling = HANDLING::HURTBYBULLET;
  53.         jjObjectPresets[OBJECT::DRAGON].energy = 5;
  54.         jjObjectPresets[OBJECT::DRAGON].scriptedCollisions = true;
  55.  
  56.         jjObjectPresets[OBJECT::WITCH].behavior = Wizard;
  57.         jjObjectPresets[OBJECT::WITCH].energy = 100;
  58.         jjObjectPresets[OBJECT::WITCH].bulletHandling = HANDLING::HURTBYBULLET;
  59.         jjObjectPresets[OBJECT::WITCH].state = STATE::ACTION;
  60.  
  61.         jjObjectPresets[OBJECT::BURGER].points = 0;
  62.         jjObjectPresets[OBJECT::BURGER].scriptedCollisions = true;             
  63.         jjObjectPresets[OBJECT::BURGER].behavior = WizardSpell;
  64.         jjObjectPresets[OBJECT::BURGER].energy = 1;    
  65.         jjObjectPresets[OBJECT::BURGER].state = STATE::ACTION;
  66.         jjObjectPresets[OBJECT::BURGER].bulletHandling = HANDLING::IGNOREBULLET;
  67.  
  68.         jjObjectPresets[OBJECT::MILK].energy = 6;
  69.         jjObjectPresets[OBJECT::MILK].behavior = SpittingBubba;
  70.         jjObjectPresets[OBJECT::MILK].points = 1000;
  71.         jjObjectPresets[OBJECT::MILK].xSpeed = 1;
  72.         jjObjectPresets[OBJECT::MILK].state = STATE::WALK;
  73.         jjObjectPresets[OBJECT::MILK].deactivates = false;
  74.         jjObjectPresets[OBJECT::MILK].scriptedCollisions = true;
  75.         jjObjectPresets[OBJECT::MILK].isTarget = true;
  76.         jjObjectPresets[OBJECT::MILK].playerHandling = HANDLING::ENEMY;
  77.  
  78.         jjObjectPresets[OBJECT::LEMON].energy = 12;
  79.         jjObjectPresets[OBJECT::LEMON].behavior = BubbaSpirit;
  80.         jjObjectPresets[OBJECT::LEMON].points = 700;
  81.         jjObjectPresets[OBJECT::LEMON].light = 15;
  82.         jjObjectPresets[OBJECT::LEMON].lightType = LIGHT::RING2;
  83.         jjObjectPresets[OBJECT::LEMON].playerHandling = HANDLING::ENEMY;
  84.         jjObjectPresets[OBJECT::LEMON].bulletHandling = HANDLING::IGNOREBULLET;
  85.         jjObjectPresets[OBJECT::LEMON].isTarget = true;
  86.         jjObjectPresets[OBJECT::LEMON].isBlastable = true;
  87.  
  88.  
  89.  
  90.         jjObjectPresets[OBJECT::ICECREAM].behavior = Key();
  91.         jjObjectPresets[OBJECT::ICECREAM].scriptedCollisions = true;
  92.  
  93.         jjObjectPresets[OBJECT::PEAR].behavior = Head1();
  94.         jjObjectPresets[OBJECT::PEAR].scriptedCollisions = true;
  95.  
  96.         jjObjectPresets[OBJECT::WEENIE].behavior = Head();
  97.         jjObjectPresets[OBJECT::WEENIE].scriptedCollisions = true;
  98.  
  99.         jjObjectPresets[OBJECT::FASTFEET].behavior = HeadFlame();
  100.         jjObjectPresets[OBJECT::FASTFEET].scriptedCollisions = true;
  101.  
  102.         jjObjectPresets[OBJECT::DONUT].behavior = AntiCarrot();
  103.         jjObjectPresets[OBJECT::DONUT].scriptedCollisions = true;
  104.         jjObjectPresets[OBJECT::DONUT].determineCurAnim(ANIM::PICKUPS,82);
  105.        
  106.         jjObjectPresets[OBJECT::SILVERCOIN].behavior = SuperCopter();
  107.         jjObjectPresets[OBJECT::SILVERCOIN].scriptedCollisions = true;
  108.  
  109.         jjObjectPresets[OBJECT::LIME].behavior = Light;
  110.         jjObjectPresets[OBJECT::LIME].scriptedCollisions = true;
  111.  
  112.         jjObjectPresets[OBJECT::MOTH].behavior = Treasure();
  113.         jjObjectPresets[OBJECT::MOTH].scriptedCollisions = true;
  114.  
  115.         jjObjectPresets[OBJECT::FREEZEENEMIES].behavior = TimeFreezer();
  116.         jjObjectPresets[OBJECT::FREEZEENEMIES].scriptedCollisions = true;
  117.         Jazz1::MakeEnemy(OBJECT::CRAB, Jazz1::Enemies::Turtemple_ScorpWeenie).SetUsesJJ2StyleDeathAnimation(true);
  118.         Jazz1::MakeEnemy(OBJECT::TUFTURT, Jazz1::Enemies::Turtemple_JeTurtle, true).SetUsesJJ2StyleDeathAnimation(true).SetBulletFireSound(SOUND::INTRO_SHOT1).SetBulletExplosionSound(SOUND::COMMON_GUNSM1);
  119.         Jazz1::MakeEnemy(OBJECT::RAVEN, Jazz1::Enemies::Sluggion_Dragoon).SetUsesJJ2StyleDeathAnimation(true);
  120.         Jazz1::MakeEnemy(OBJECT::DEMON, Jazz1::Enemies:: Battleships_ArmorDoofi).SetUsesJJ2StyleDeathAnimation(true);
  121.  
  122. }
  123.  
  124. class Treasure : jjBEHAVIORINTERFACE {
  125.         void onBehave(jjOBJ@ obj) {
  126.                 obj.behave(BEHAVIOR::MOTH, false);
  127.         }
  128.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) {
  129.                 obj.causesRicochet = true;
  130.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_HIBELL, 1000);
  131.                 jjPARTICLE@ particle = jjAddParticle(PARTICLE::FLOWER);
  132.                 particle.ySpeed = 0;
  133.                 particle.flower.petals = 2;
  134.                 particle.flower.size = 40;
  135.                 particle.flower.color = 15;
  136.                 particle.flower.angularSpeed = 64;
  137.                 particle.flower.angle = 50;
  138.                 particle.xPos = obj.xPos;
  139.                 particle.yPos = obj.yPos;
  140.                 return true;
  141.         }
  142. }
  143.  
  144.  
  145. void PlatformV (jjOBJ@ obj) {
  146.  
  147.         switch (obj.state) {
  148.                 case STATE::START:
  149.                 if(obj.xPos < 32*32)
  150.                         {obj.direction = obj.ySpeed = 6;}
  151.                 if(obj.xPos > 32*32 && obj.xPos < 43*32)
  152.                         {obj.direction = obj.ySpeed = 2;}
  153.                 if(obj.xPos > 42*32)
  154.                         {obj.direction = obj.ySpeed = 4;}
  155.                         obj.determineCurAnim(ANIM::SONICPLAT, 0);  
  156.                         obj.determineCurFrame();
  157.                         obj.state = STATE::FLY;
  158.                         obj.beSolid();
  159.                 case STATE::FLY:
  160.                         if(p.keyUp == true && lever == true && p.yPos > 32*32 && p.xPos > 43*32)
  161.                         {obj.yPos = obj.yPos - obj.ySpeed;}
  162.                         if(p.keyDown == true && lever == true && p.yPos > 32*32 && p.xPos > 43*32)
  163.                         {obj.yPos = obj.yPos + obj.ySpeed;}
  164.                         obj.beSolid();
  165.                         obj.deactivates = false;
  166.                         if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos-50, 1))
  167.                                 {obj.direction = obj.ySpeed = -obj.ySpeed;}
  168.                         obj.draw();
  169.                         break;
  170.  
  171.         }
  172. }
  173.  
  174. int spring = 0;
  175. bool spike = false;
  176. class SpikeBump : jjBEHAVIORINTERFACE {
  177.  
  178. void onBehave(jjOBJ@ obj) {
  179.  
  180.         switch (obj.state) {
  181.                 case STATE::START:
  182.                         obj.determineCurFrame();
  183.                         obj.state = STATE::FLY;
  184.  
  185.  
  186.                 case STATE::FLY:
  187.                         obj.playerHandling = HANDLING::SPECIAL;
  188.                         obj.xPos = obj.xPos + obj.xSpeed;
  189.                         obj.deactivates = false;
  190.                         if(p.xPos > 128*32 && obj.xPos > 128*32 && obj.xPos < 178*32 && obj.yPos > 43*32)
  191.                         {obj.xSpeed = 0.5;}
  192.                         if((p.xPos > 128*32 && obj.xPos > p.xPos + 612) || obj.xPos > 196*32)
  193.                         {obj.delete();}
  194.                        
  195.                         if(obj.xPos > p.xPos + 64 || obj.xPos < p.xPos - 64 || obj.yPos > p.yPos + 64 || obj.yPos < p.yPos - 64)
  196.                         {obj.determineCurAnim(ANIM::BOLLPLAT, 0);
  197.                         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -8);
  198.                         obj.determineCurFrame();}
  199.                         else {jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -24);}
  200.                         break;
  201.  
  202.                
  203.         }
  204. }
  205.  
  206.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) {
  207.                 if(bullet is null && play !is null && (force == -1 || force == 1))
  208.                         {spring = jjGameTicks + 1*61;
  209.                         obj.determineCurAnim(ANIM::BOLLPLAT, 0);
  210.                         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -24);
  211.                         obj.determineCurFrame();
  212.                         p.buttstomp = 121;
  213.                         jjSample(obj.xPos, obj.yPos, SOUND::PINBALL_BELL, 1000);}
  214.                 if(force == 0 && spring < jjGameTicks)
  215.                         {play.hurt();
  216.                         obj.determineCurAnim(ANIM::SPIKEBOLL, 0);  
  217.                         obj.determineCurFrame();
  218.                         if(spike == false)
  219.                         {jjSample(obj.xPos, obj.yPos, SOUND::COMMON_METALHIT, 1000);}
  220.                         spike = true;}
  221.                 return true;
  222.                 }
  223.  
  224. }
  225.  
  226.  
  227.  
  228.  
  229. bool timedoortext = false;
  230.  
  231. class SuperCopter : jjBEHAVIORINTERFACE {
  232.         void onBehave(jjOBJ@ obj) {
  233.  
  234. obj.behave(BEHAVIOR::PICKUP, false);
  235. obj.determineCurAnim(ANIM::PICKUPS, 33);
  236. ++obj.counter;
  237.                 obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
  238.  
  239.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -8);
  240.  
  241. }
  242.  
  243.         bool onObjectHit(jjOBJ@ obj, jjOBJ@, jjPLAYER@ play, int force) {
  244.                 play.timerStart(1500);
  245.                 p.morphTo(CHAR::JAZZ);
  246.                 p.cameraFreeze(53*32, 24*32, true, false);
  247.                 jjTriggers[7]= true;
  248.                 SuperCopterOn= jjGameTicks + 25 * 61;
  249.                 if(timedoortext == false)
  250.                         {p.showText("@@A timed door. Better move my ears fast.");}
  251.                 timedoortext =true;
  252.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  253.                 obj.frameID = 0;
  254.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_PICKUP1, 6000);
  255.  
  256.                 return true;
  257.         }
  258.  
  259. }
  260.  
  261.        
  262. void onMain() {
  263. gem::deleteCollectedGems();
  264. if(jjKey[9] && jjKey[0x51]) {
  265. p.morphTo(CHAR::JAZZ, false);
  266. }
  267. if(jjKey[9] && jjKey[0x57]) {
  268. p.morphTo(CHAR::SPAZ, false);
  269. }
  270. if(jjKey[9] && jjKey[0x45]) {
  271. p.morphTo(CHAR::LORI, false);
  272. }
  273. jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::ROTATINGROCK].curAnim];
  274.                 anim.frameCount = 1;  
  275.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  276.                 jjPIXELMAP pump(0, 20*32, 3*32, 3*32, 5);
  277.                 pump.save(frame);
  278. }
  279.  
  280.  
  281. bool onDrawHealth(jjPLAYER@ player, jjCANVAS@ canvas) {
  282.         if(keylock == true && jjTriggers[3]==true)
  283.                 {canvas.drawSprite(25, 585, ANIM::PICKUPS,43, jjGameTicks>>2, -1, SPRITE::NORMAL);}
  284.         if(Dragonactivated == true && personaltorch == false)
  285.                 {canvas.drawSprite(20, 585, ANIM::PICKUPS,74, jjGameTicks>>2, -1, SPRITE::NORMAL);}
  286.                 //{canvas.drawResizedSprite(20, 585, ANIM::FACES,3, 4,0.7, 0.7, SPRITE::PALSHIFT, 16);}
  287.         if(personaltorch == true)
  288.                 {canvas.drawSprite(20, 585, ANIM::AMMO,13, jjGameTicks>>2, -1, SPRITE::NORMAL);}
  289.     return false;
  290. }
  291.  
  292. bool onDrawLives(jjPLAYER@ player, jjCANVAS@ canvas) {return true;}
  293.  
  294. bool startrush = false, readytorush = false, control = true;
  295.  
  296. void onPlayer(jjPLAYER@ p){
  297.  
  298.         if(p.lives <2)
  299.         {p.lives += 1;}
  300.  
  301.         jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::COKE].curAnim];
  302.         anim.frameCount = 1;
  303.         jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  304.         jjPIXELMAP water(0, 46*32, 1*32, 1*32, 5);
  305.         water.save(frame);
  306.         frame.hotSpotX = -frame.width/2;
  307.  
  308.                 if(control==false)
  309.                 {p.keyLeft = false;
  310.                 p.keyRight = false;
  311.                 p.keyDown = false;}
  312.  
  313.                 if(p.idle > 100 && lever == false)
  314.                 {p.cameraUnfreeze(true);
  315.                 control=true;}
  316.                 else if (p.idle > 5 && (p.keyLeft || p.keyRight || p.keyJump || p.keyFire))
  317.                 {p.cameraUnfreeze(true);
  318.                 control=true;
  319.                 spike = false;}
  320.  
  321.  
  322.         gem::trackPlayerGems(p);
  323.         gem::upgradeHealth(p);
  324.         if(p.coins == 0)
  325.         {p.coins +=3;}
  326.  
  327.         if(p.food == 100 && jjKey[0x52] == false && startrush == false)
  328.                 {p.showText("@@@@@@@@@@@@@@@@Press 'R' when you need to use Sugar Rush!", STRING::MEDIUM);
  329.                 p.startSugarRush(0);
  330.                 startrush = true;
  331.                 readytorush = true;}
  332.  
  333.         if(readytorush == true)
  334.                 {p.food = 100;}
  335.  
  336.         if(p.food == 100 && jjKey[0x52])
  337.                 {p.startSugarRush(1400);
  338.                 p.food = 0;
  339.                 readytorush = false;
  340.                 startrush = false;
  341.         }
  342.  
  343.         for (int i = 1; i < jjObjectCount; i++) {
  344.                 jjOBJ@ o = jjObjects[i];
  345.                 if (o.isActive && o.eventID == OBJECT::SEEKERAMMO3 && p.ammo[WEAPON::SEEKER] < 1) {
  346.                         o.state = STATE::KILL;}
  347.         }
  348.         for (int i = 1; i < jjObjectCount; i++) {
  349.                 jjOBJ@ o = jjObjects[i];
  350.                 if (o.isActive && o.eventID == OBJECT::RFAMMO3 && p.ammo[WEAPON::RF] < 1) {
  351.                         o.state = STATE::KILL;}
  352.         }
  353.         for (int i = 1; i < jjObjectCount; i++) {
  354.                 jjOBJ@ o = jjObjects[i];
  355.                 if (o.isActive && o.eventID == OBJECT::TNTAMMO3 && p.ammo[WEAPON::TNT] < 1) {
  356.                         o.state = STATE::KILL;}
  357.         }
  358.         for (int i = 1; i < jjObjectCount; i++) {
  359.                 jjOBJ@ o = jjObjects[i];
  360.                 if (o.isActive && o.eventID == OBJECT::GUN9AMMO3 && p.ammo[WEAPON::GUN9] < 1) {
  361.                         o.state = STATE::KILL;}
  362.         }
  363.         for (int i = 1; i < jjObjectCount; i++) {
  364.                 jjOBJ@ o = jjObjects[i];
  365.                 if (o.isActive && o.eventID == OBJECT::SEEKERPOWERUP && p.ammo[WEAPON::SEEKER] < 1) {
  366.                         o.state = STATE::KILL;}
  367.         }
  368.         for (int i = 1; i < jjObjectCount; i++) {
  369.                 jjOBJ@ o = jjObjects[i];
  370.                 if (o.isActive && o.eventID == OBJECT::RFPOWERUP && p.ammo[WEAPON::RF] < 1) {
  371.                         o.state = STATE::KILL;}
  372.         }
  373.         for (int i = 1; i < jjObjectCount; i++) {
  374.                 jjOBJ@ o = jjObjects[i];
  375.                 if (o.isActive && o.eventID == OBJECT::TNTPOWERUP && p.ammo[WEAPON::TNT] < 1) {
  376.                         o.state = STATE::KILL;}
  377.         }
  378.         for (int i = 1; i < jjObjectCount; i++) {
  379.                 jjOBJ@ o = jjObjects[i];
  380.                 if (o.isActive && o.eventID == OBJECT::GUN9POWERUP && p.ammo[WEAPON::GUN9] < 1) {
  381.                         o.state = STATE::KILL;}
  382.         }
  383.  
  384. if(spring > jjGameTicks)
  385. {p.ySpeed = -10;}
  386.         if (torch > jjGameTicks) {
  387.         p.lightType = LIGHT::FLICKER;}
  388.         if (torch < jjGameTicks || torch==0) {
  389.         p.lightType = LIGHT::NONE;}
  390.  
  391.         if(SuperCopterOn > jjGameTicks)
  392.         {jjTriggers[7]= true;
  393.         jjCharacters[CHAR::JAZZ].helicopterYSpeed= 0;}
  394.  
  395.         if(SuperCopterOn < jjGameTicks)
  396.         {jjTriggers[7]= false;
  397.         jjCharacters[CHAR::JAZZ].helicopterYSpeed= 1;}
  398.  
  399.  
  400.                 if (p.keyUp && p.xPos> 225*32 && p.xPos< 227*32 && p.yPos >33*32 && p.yPos < 36*32 && jjTriggers[11]==false){
  401.                 jjTriggers[11]= true;
  402.                 jjAddObject(OBJECT::LIME, 226*32, 34*32);}
  403.  
  404.                 if (p.keyUp && p.xPos> 237*32 && p.xPos< 240*32 && p.yPos >33*32 && p.yPos < 36*32 && jjTriggers[12]==false){  
  405.                 jjTriggers[12]= true;
  406.                 jjAddObject(OBJECT::LIME, 238*32, 34*32);}
  407.  
  408.                 if (p.keyUp && p.xPos> 225*32 && p.xPos< 227*32 && p.yPos >27*32 && p.yPos < 30*32 && jjTriggers[13]==false){  
  409.                 jjTriggers[13]= true;
  410.                 jjAddObject(OBJECT::LIME, 226*32, 28*32);}
  411.  
  412.                 if (p.keyUp && p.xPos> 233*32 && p.xPos< 236*32 && p.yPos >27*32 && p.yPos < 30*32 && jjTriggers[14]==false){  
  413.                 jjTriggers[14]= true;
  414.                 jjAddObject(OBJECT::LIME, 234*32, 28*32);}
  415.  
  416.                 if (p.keyUp && p.xPos> 248*32 && p.xPos< 251*32 && p.yPos >27*32 && p.yPos < 30*32 && jjTriggers[15]==false){  
  417.                 jjTriggers[15]= true;
  418.                 jjAddObject(OBJECT::LIME, 249*32, 28*32);}
  419.  
  420.                 if (p.keyUp && p.xPos> 242*32 && p.xPos< 245*32 && p.yPos >27*32 && p.yPos < 30*32 && jjTriggers[16]==false){  
  421.                 jjTriggers[16]= true;
  422.                 jjAddObject(OBJECT::LIME, 243*32, 28*32);}
  423.  
  424.                 if (p.keyUp && p.xPos> 237*32 && p.xPos< 240*32 && p.yPos >27*32 && p.yPos < 30*32 && jjTriggers[17]==false){  
  425.                 jjTriggers[17]= true;
  426.                 jjAddObject(OBJECT::LIME, 238*32, 28*32);}
  427.  
  428.  
  429. if(jjTriggers[17] == true && jjTriggers[16] == true && jjTriggers[15] == true && jjTriggers[14] == true && jjTriggers[13] == true && jjTriggers[12] == true && jjTriggers[11] == true){
  430.                 jjTriggers[18]= true;
  431.  
  432.  
  433.                 }
  434.         if(p.yPos >39*32) {
  435.                 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::WEENIE].curAnim];
  436.                 anim.frameCount = 1;  
  437.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  438.                 jjPIXELMAP pump(0, 2*32, 1*32, 1*32, 5);
  439.                 pump.save(frame);
  440.                 frame.hotSpotX = -18;
  441.         }
  442.  
  443.  
  444.  
  445. }
  446.  
  447. void onlevelReload(){
  448.         gem::restorePlayerGems();
  449.         jjLocalPlayers[0].lives++;
  450.         for (uint i = 0; i < 32; ++i)
  451.                 jjTriggers[i] = SavedTriggers[i];
  452. }
  453.  
  454. void onFunction1(jjPLAYER@ p) {
  455.                 jjTriggers[1] = true;
  456.                 jjTriggerRock(0);}
  457.  
  458. void onFunction2(jjPLAYER@ p) {
  459.                 p.showText("@@OPEN SESAME!");
  460.                 jjTriggers[2] = true;}
  461.  
  462. void onFunction3(jjPLAYER@ p) {
  463.                 p.showText("@@Now I have a torch!");
  464.                 jjSwitchTrigger(20);
  465.                 p.boss=jjAddObject(OBJECT::WEENIE, 54*32, 24*32);}
  466.  
  467. bool windtext = false;
  468.  
  469. void onFunction4(jjPLAYER@ p) {
  470.         if(windtext == false){
  471.                 p.showText("@@I can cross the other side by copter@ears. But it's way too windy.");
  472.                 windtext = true;}
  473. }
  474.  
  475. void onFunction5(jjPLAYER@ p) {
  476.         p.showText("@@@@@@@@@@@@@@@@@@@@@@@@@40 Thieves' Cave", STRING::MEDIUM);
  477.         jjMusicLoad("mo4a_The Lava Stream (Reprise 2).ogg");   
  478.         jjEnabledASFunctions[5] = false;}
  479.  
  480. void onFunction6(jjPLAYER@ p) {
  481. lever = true;
  482. p.cameraFreeze(36*32, 11*32, true, false);
  483. }
  484.  
  485. void onFunction7(jjPLAYER@ p) {
  486.         jjPAL resPal;
  487.         resPal.load("Arabian Cave.j2t");
  488.         resPal.apply();
  489. }
  490.  
  491. bool textdisappear = false, torchidea = false, torchfail = false;
  492. void onFunction8(jjPLAYER@ p) {
  493.         jjLayerOrderSet(array<jjLAYER@> = {jjLayers[2], jjLayers[3], jjLayers[4], jjLayers[5], jjLayers[6], jjLayers[7], jjLayers[8], jjLayers[1]});
  494.         textdisappear = true;
  495. }
  496.  
  497. void onFunction9(jjPLAYER@ p) {
  498.         if(headburn == false)
  499.         {p.showText("@@Oh god...@Is this Ali Babba's head?");
  500.         jjEnabledASFunctions[9] = false;}
  501. }
  502.  
  503. void onFunction10(jjPLAYER@ p) {
  504.         if(personaltorch == false)
  505.         {p.showText("@@It's too dark.@I can't see anything.");
  506.         torchidea = true;
  507.         p.lighting = 1;}
  508.         if(personaltorch == true)
  509.         p.warpToID(4, true);
  510. }
  511.  
  512. void onFunction11(jjPLAYER@ p) {
  513.         if(torchidea == true)
  514.         {p.showText("@@Hey! Let's use Ali Babba's head@as a torch. But how@should I light it?");
  515.         torchfail = true;
  516.         torchidea = false;}
  517. }
  518.  
  519. void onFunction12(jjPLAYER@ p) {
  520.         if(torchfail == true && personaltorch == false)
  521.         {p.showText("@@Nope. Need a stronger fire.");
  522.         torchfail = false;}
  523. }
  524.  
  525. void onFunction13(jjPLAYER@ p) {
  526.         keylock = false; }
  527.  
  528. void onFunction14(jjPLAYER@ p) {
  529.                 if(personaltorch == false)
  530.                 {p.showText("@@Hmm... A strong fire source...");}
  531. }
  532.  
  533. bool sesame = false;
  534. void onFunction15(jjPLAYER@ p) {
  535.                 if(jjTriggers[7] == false && sesame == false)
  536.                 {p.showText("@@OPEN SESAME...@Well, nice try...");
  537.                 sesame = true;}
  538. }
  539.  
  540. class TimeFreezer : jjBEHAVIORINTERFACE {
  541.  
  542.         void onBehave(jjOBJ@ obj) {
  543.                 obj.behave(BEHAVIOR::PICKUP);
  544.                 obj.lightType = LIGHT::LASER;
  545.                 obj.light = 100;
  546.         }
  547.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ p, int force) {
  548.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  549.                 jjNxt();
  550.                 gem::saveGemData();
  551.  
  552.                 return true;
  553.         }
  554. }
  555. class Head1 : jjBEHAVIORINTERFACE {
  556.  
  557.         void onBehave(jjOBJ@ obj) {
  558.                 if(Dragonactivated == true)
  559.                         {obj.delete();}
  560.                 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::PEAR].curAnim];
  561.                 anim.frameCount = 1;  
  562.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  563.                 jjPIXELMAP pump(0, 2*32, 1*32, 1*32, 5);
  564.                 pump.save(frame);
  565.                 frame.hotSpotX = -18;
  566.                 obj.behave(BEHAVIOR::PICKUP);
  567.         obj.bulletHandling = HANDLING::IGNOREBULLET;
  568.         obj.playerHandling = HANDLING::SPECIAL;
  569.  
  570. }
  571.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ per, int force) {
  572.                 Dragonactivated = true;
  573.                 p.showText("@@This head could be useful at something.");
  574.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  575.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_SPLAT2, 1000);
  576.                 return true;
  577.         }
  578. }
  579.  
  580. bool personaltorch = false;
  581.  
  582. class Head : jjBEHAVIORINTERFACE {
  583.  
  584.         void onBehave(jjOBJ@ obj) {
  585.                 obj.behave(BEHAVIOR::PICKUP);
  586.         obj.bulletHandling = HANDLING::IGNOREBULLET;
  587.         obj.playerHandling = HANDLING::SPECIAL;
  588.                 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::WEENIE].curAnim];
  589.                 anim.frameCount = 1;  
  590.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  591.                 jjPIXELMAP pump(0, 2*32, 1*32, 1*32, 5);
  592.                 pump.save(frame);
  593.                 frame.hotSpotX = -18;
  594. }
  595.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ per, int force) {
  596.         if(p.idle >1) {
  597.                 torch = jjGameTicks + 60*61;
  598.                 personaltorch = true;
  599.                 p.showText("@@Now I can visit the last room!");
  600.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  601.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_SPLAT2, 1000); }
  602.                 return true;
  603.         }
  604. }
  605.  
  606.  
  607. class HeadFlame : jjBEHAVIORINTERFACE {
  608.  
  609.         void onBehave(jjOBJ@ obj) {
  610.                 obj.behave(BEHAVIOR::PICKUP);
  611.  
  612.         obj.playerHandling = HANDLING::SPECIAL;
  613.         obj.determineCurAnim(ANIM::AMMO, 55);
  614.         obj.bulletHandling = HANDLING::IGNOREBULLET;
  615.         obj.lightType = LIGHT::FLICKER;
  616.  
  617. if (torch > jjGameTicks) {
  618.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  619.  
  620.         }
  621. }}
  622.  
  623.  
  624. bool keylock = false;
  625.  
  626. class Key : jjBEHAVIORINTERFACE {
  627.  
  628.         void onBehave(jjOBJ@ obj) {
  629.                 obj.behave(BEHAVIOR::PICKUP);
  630.                 if(jjTriggers[3] == true)
  631.                 {obj.delete();}
  632.                 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::ICECREAM].curAnim];
  633.                 anim.frameCount = 1;  
  634.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  635.                 jjPIXELMAP pump(0, 1*32, 1*32, 1*32, 5);
  636.                 pump.save(frame);
  637.                 frame.hotSpotY = -17;
  638. }
  639.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ per, int force) {
  640.                 jjTriggers[3] = true;
  641.                 keylock= true;
  642.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  643.                 p.cameraFreeze(121*32, 34*32, true, false);
  644.                 control = false;
  645.                 jjSample(obj.xPos, obj.yPos, SOUND::MENUSOUNDS_TYPEENTER, 1000);
  646.  
  647.                 return true;
  648.         }
  649. }
  650.  
  651.  
  652.  
  653. bool headburn = false, Dragonactivated = false;
  654.  
  655. void BigDragon(jjOBJ@ enemy) {
  656.  
  657.         if(enemy.energy <5)
  658.         {enemy.energy += 10;}
  659.  
  660.         if(p.xPos >25*32 && p.xPos <30*32 && p.yPos >32*32 && p.yPos <39*32) {
  661.                 //enemy.delete();
  662.                 if(Dragonactivated == true && headburn == false) {
  663.                 jjAddObject(OBJECT::FASTFEET, 846, 38*32);
  664.                 jjAddObject(OBJECT::WEENIE, 840, 38*32);
  665.                 p.showText("@@Let's try this...");
  666.                 headburn = true;}
  667.         }
  668.  
  669.         enemy.behave(BEHAVIOR::DRAGON, false);
  670.        
  671.        
  672.         if (enemy.justHit == 0) {
  673.                 jjDrawResizedSpriteFromCurFrame(enemy.xPos, enemy.yPos, enemy.curFrame, -2, 2, SPRITE::PALSHIFT, -8);}
  674.                 else jjDrawResizedSpriteFromCurFrame(enemy.xPos, enemy.yPos, enemy.curFrame, -2, 2, SPRITE::BRIGHTNESS, 255);
  675. }
  676.  
  677. class AntiCarrot: jjBEHAVIORINTERFACE {
  678.  
  679.         void onBehave(jjOBJ@ obj) {
  680.                 obj.determineCurFrame();
  681.         obj.behave(BEHAVIOR::PICKUP, false);
  682.                 ++obj.counter;
  683.                 obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
  684.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -24);
  685. }
  686.  
  687.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ p, int force) {
  688.                 p.health = 1;
  689.                 p.blink = 245; 
  690.                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_EAT1, 1000);
  691.                 obj.frameID = 0;
  692.                 obj.behavior = BEHAVIOR::EXPLOSION2;
  693.  
  694.  
  695.                 return true;
  696.         }
  697. }
  698. bool final = false;
  699.  
  700.  
  701.  
  702. class FakeFreezer : jjBEHAVIORINTERFACE {
  703.  
  704.         void onBehave(jjOBJ@ obj) {
  705.                 obj.determineCurFrame();
  706.         obj.behave(BEHAVIOR::PICKUP, false);
  707.                 ++obj.counter;
  708.                 obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
  709.         if(final==false)
  710.                 {obj.draw();}
  711.         else
  712.                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -16);
  713.  
  714. }
  715.  
  716.         bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
  717.         if(final == false){
  718.         for (int i = 1; i < jjObjectCount; i++) {
  719.         jjOBJ@ o = jjObjects[i];        jjOBJ@ ob = jjObjects[i];
  720.         if (o.isActive && o.eventID == OBJECT::MILK || ob.isActive && ob.eventID == OBJECT::LEMON) {
  721.                 o.state = STATE::KILL;}
  722.         }
  723.                 p.showText("@@Uh oh... This is fake!");
  724.                 obj.frameID = 0;
  725.                 p.activateBoss();
  726.                 final=true;
  727.                 {p.boss=jjAddObject(OBJECT::WITCH, 236*32, 27*32);}
  728.                 jjMusicLoad("mo4a_Doc's Cave.ogg");
  729.                 jjOBJ@ boss = jjObjects[p.boss];
  730.                 }
  731.                 return true;
  732.  
  733.         }
  734. }
  735.  
  736.  
  737. void Wizard(jjOBJ@ boss) {
  738.                
  739.         if (boss.energy==0) {
  740.                 boss.state=STATE::KILL;
  741.                 boss.delete();
  742.                 boss.counter==0;
  743.                 boss.xSpeed = 3*p.direction;
  744.                 boss.counter += 1;
  745.                 boss.frameID = boss.counter/56;
  746.                 jjAddObject(OBJECT::FREEZEENEMIES, boss.xPos, boss.yPos);
  747.                 jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
  748.                 ++boss.counter;
  749.         }
  750.        
  751.  
  752.         if (boss.xPos < 147*32 || boss.xPos > 153*32)
  753.         {boss.xPos = boss.xPos - 1;}
  754.         if (boss.yPos > 27*32)
  755.         {boss.yPos = boss.yPos - 1;}   
  756.         else {boss.direction==1;}
  757.  
  758.         switch (boss.state) {
  759.                 case STATE::ACTION:
  760.                 boss.lightType = LIGHT::FLICKER;
  761.                 boss.yPos = jjSin(boss.counter*20 + 55)*4 + boss.yOrg;
  762.                 boss.xPos = boss.xSpeed +boss.xPos;
  763.         if (boss.xPos < 230*32)
  764.                 {boss.xSpeed = 10;}
  765.  
  766.         if (boss.xPos > 252*32)
  767.         {boss.xSpeed = -10;}
  768.                        
  769.                 ++boss.counter;
  770.                 if (boss.findNearestPlayer(300*300) > -1)
  771.  
  772.                 {boss.yPos = jjCos(boss.counter/2)*2 + boss.yPos;
  773.                 boss.xPos = 4 + boss.xPos;}
  774.  
  775.                 boss.determineCurFrame();
  776.                 boss.frameID = boss.counter/30;
  777.                 boss.counter += 1;
  778.                 boss.draw();
  779.                         if (++boss.counter > 100&&boss.findNearestPlayer(300*300) > -1)
  780.                         switch (jjRandom() & 2)
  781.                         {case 0:
  782.                         boss.state = STATE::ATTACK;
  783.                         break;
  784.                         case 1:
  785.                         boss.state = STATE::ACTION;
  786.                         break;}
  787.  
  788.                         break;
  789.          case STATE::ATTACK:   
  790.          boss.direction = (p.xPos < boss.xPos) ? -1 : 1;
  791.         if (boss.xPos < 220*32 || boss.xPos < 222*32 || boss.xPos > 242*32)
  792.         {boss.xPos = boss.xPos - 1;}
  793.                 boss.yPos = jjSin(boss.counter*20 + 55)*4 + boss.yOrg;
  794.                 if (boss.counter >= 1200) {
  795.                         int spell = OBJECT::BURGER;
  796.                         jjSample(boss.xPos, boss.yPos, SOUND::WITCH_MAGIC);
  797.                         jjOBJ@ obj = jjObjects[boss.fireBullet(OBJECT::BURGER)];
  798.                         obj.killAnim = obj.determineCurAnim(ANIM::AMMO, 4, false);
  799.                         obj.determineCurAnim(ANIM::WITCH,3);
  800.                         obj.determineCurFrame();       
  801.                         obj.yPos = boss.yPos+22;
  802.                         obj.xPos = boss.xPos+32*(boss.direction);
  803.                 }
  804.                 boss.frameID = boss.counter/53;
  805.                 boss.counter += 6;
  806.                 if (boss.justHit == 0)
  807.                 jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::PALSHIFT, -8);
  808.                 else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);
  809.  
  810.         if (++boss.counter > 1206)
  811.         {boss.xAcc= boss.yAcc =0;
  812.         boss.state = STATE::ACTION;
  813.         boss.counter =0;}
  814.         break;
  815.         case STATE::KILL:
  816.         break; 
  817.         }
  818.         if (boss.state == STATE::ACTION) {
  819.                 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::WITCH].curAnim];
  820.                 anim.frameCount = 1;
  821.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  822.                 jjPIXELMAP wizard2(0, 50*32, 2*32, 2*32, 5);
  823.                 wizard2.save(frame);
  824.         }
  825.  
  826.         else if (boss.state == STATE::ATTACK) {
  827.                 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::WITCH].curAnim];
  828.                 anim.frameCount = 1;
  829.                 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
  830.                 jjPIXELMAP wizard(0, 48*32, 2*32, 2*32, 5);
  831.                 wizard.save(frame);
  832.         }
  833.  
  834.         if (boss.justHit == 0)
  835.                 jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
  836.                 else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);                    
  837. }
  838.        
  839.  
  840.                                        
  841. void WizardSpell(jjOBJ@ enemy) {
  842.                 jjPLAYER@ play = jjLocalPlayers[0];
  843.                
  844.                 if (enemy.xPos > play.xPos)
  845.                         enemy.xPos = enemy.xPos - 3;
  846.                 else if (enemy.xPos < play.xPos)
  847.                         enemy.xPos = enemy.xPos + 3;
  848.                 if (enemy.yPos > play.yPos)
  849.                         enemy.yPos = enemy.yPos - 3;
  850.                 else if (enemy.yPos < play.yPos)
  851.                         enemy.yPos = enemy.yPos + 3;
  852.                 enemy.determineCurAnim(ANIM::WITCH,3);
  853.                 enemy.determineCurFrame();
  854.                 enemy.frameID = enemy.counter/8;
  855.                 ++enemy.counter;
  856.                 enemy.counter += 1;
  857.                  if (enemy.counter >200*jjDifficulty/2+400)
  858.                 {enemy.delete();
  859.                   int explosionID = jjAddObject(OBJECT::BLASTERBULLET, enemy.xPos, enemy.yPos, enemy.creator, CREATOR::OBJECT);
  860.                 jjObjects[explosionID].determineCurAnim(ANIM::AMMO, 4, true);
  861.                 jjObjects[explosionID].state = STATE::EXPLODE;
  862.                 }
  863.                 jjDrawSpriteFromCurFrame(enemy.xPos, enemy.yPos, enemy.curFrame, enemy.direction, SPRITE::PALSHIFT, 8);}
  864.        
  865.  
  866.  
  867.        
  868. void onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) {
  869.         if (obj.eventID == OBJECT::BURGER) {
  870.         p.hurt();
  871.         obj.behavior = BEHAVIOR::EXPLOSION2;
  872.                
  873.         }
  874. }
  875.  
  876.  
  877.  
  878. // Credit: from Stone Abbys by Bloody_Body
  879.         jjOBJ@ spawnedObject;
  880. void SpittingBubba(jjOBJ@ enemy) {
  881.                                         if ( enemy.energy == 0)
  882.                                         enemy.state = STATE::KILL;
  883.         switch (enemy.state) {
  884.                 case STATE::WALK:
  885.                 enemy.behave(BEHAVIOR::WALKINGENEMY);
  886.                 enemy.determineCurAnim(ANIM::BUBBA, 5);
  887.                                                                                
  888.                          if (enemy.findNearestPlayer(64*800) > -1 && ++enemy.counter > 36) enemy.state = STATE::IDLE;
  889.                                 if (enemy.energy == 0)
  890.                                         enemy.state = STATE::KILL;
  891.                         break;
  892.                         case STATE::IDLE:
  893.                         enemy.frameID = enemy.counter/5;
  894.                         enemy.determineCurFrame();
  895.                        
  896.                         switch (jjRandom() & 3) {
  897.                                
  898.                                 case 0:  
  899.                                 case 1:
  900.                                
  901.                                         enemy.state = STATE::ACTION;
  902.                                         enemy.determineCurAnim(ANIM::BUBBA, 0);
  903.                                         enemy.counter = 0;
  904.                                         break;
  905.                                        
  906.                                 case 2:
  907.                                
  908.                                         enemy.state = STATE::WALK;
  909.                                         enemy.determineCurAnim(ANIM::BUBBA, 5);
  910.                                         enemy.counter = 0;
  911.                                        
  912.                                         break;
  913.                                        
  914.                                         }
  915.                         break;
  916.                        
  917.                        
  918.                 case STATE::ACTION:
  919.                 if (++enemy.counter < 36) {
  920.                         enemy.frameID = enemy.counter/5;
  921.                         enemy.determineCurFrame();
  922.                         enemy.direction = (jjLocalPlayers[0].xPos < enemy.xPos) ? -1 : 1;
  923.                                    if (enemy.justHit == 0)
  924.                         if (enemy.counter == 25 ) {
  925.                         //if difficulty is easy Bubba spits once per every "state::action", if normal- twice, it hard or turbo- three times.
  926.                 jjOBJ@ bullet = jjObjects[enemy.fireBullet(OBJECT::FIRESHIELDBULLET)];
  927.                                 bullet.determineCurAnim(ANIM::BUBBA, 4);
  928.                                 bullet.killAnim = bullet.determineCurAnim(ANIM::AMMO, 3, false);
  929.                                 bullet.playerHandling = HANDLING::ENEMYBULLET;
  930.                                 bullet.state = STATE::FLY;
  931.                                 bullet.xPos = enemy.xPos;
  932.                                 bullet.yPos = bullet.yPos - 16;
  933.                                
  934.                                 bullet.animSpeed = 2;
  935.                                 jjSample(enemy.xPos, enemy.yPos, SOUND::BUBBA_SNEEZE2);
  936.                                
  937.                                
  938.                                
  939.                         }
  940.                 } else {
  941.                         enemy.frameID = enemy.counter = 0;
  942.                         enemy.determineCurAnim(ANIM::BUBBA, 5);
  943.                         enemy.state = STATE::IDLE;
  944.                 }
  945.                 break;
  946.        
  947.                        
  948.                 case STATE::FREEZE:
  949.                         if (enemy.freeze > 0) {
  950.                                 enemy.draw();
  951.                                 enemy.freeze -= 4;
  952.                         }
  953.                         if (enemy.freeze < 4) {
  954.                                 enemy.unfreeze(0);
  955.                                 enemy.state = enemy.oldState;
  956.                         }
  957.                         break;
  958.        
  959.                        
  960.                 case STATE::KILL:
  961.                        
  962.                         enemy.particlePixelExplosion(2);
  963.                         @spawnedObject = jjObjects[jjAddObject(OBJECT::LEMON, enemy.xPos, enemy.yPos)];
  964.                         spawnedObject.determineCurAnim(ANIM::BUBBA, 1);
  965.                         jjSample(enemy.xPos, enemy.yPos, SOUND::RAPIER_GOSTRIP);
  966.                         enemy.delete();
  967.                         break;
  968.                         }
  969.                 enemy.draw();
  970.                
  971.                
  972.         }
  973.  
  974.                 void BubbaSpirit(jjOBJ@ enemy) {
  975.                 enemy.determineCurAnim(ANIM::BUBBA, 1);
  976.                 enemy.behave(BEHAVIOR::BEE);
  977.                 }
  978.  
  979. void Light(jjOBJ@ obj) {
  980.  
  981.                 obj.behave(BEHAVIOR::PICKUP, false);
  982.                 obj.determineCurAnim(ANIM::PICKUPS, 2);
  983.                 obj.lightType = LIGHT::FLICKER;
  984. }
  985.  
  986. array<bool> SavedTriggers(32, false);
  987. //Extendable Checkpoints by VioletCLM
  988. void CheckpointWrapper(jjOBJ@ obj) {
  989.   if (obj.state == STATE::STOP) { //don't do anything anymore
  990.     jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 8);
  991.   } else if (obj.state == STATE::DEACTIVATE) { //due to death
  992.     obj.deactivate();
  993.   } else {
  994.     obj.behave(BEHAVIOR::CHECKPOINT);
  995.         jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 8);
  996.     if (obj.state == STATE::DONE) { //triggered by the player hitting it
  997.       obj.state = STATE::STOP;
  998.       //save the current state of some properties
  999.       for (uint i = 0; i < 32; ++i)
  1000.         SavedTriggers[i] = jjTriggers[i];
  1001.  
  1002.       //OPTIONAL: this loop makes checkpoints reusable, so only the most recent checkpoint you touched is ever active
  1003.       for (int i = jjObjectCount; --i > 0;) {
  1004.         jjOBJ@ obj2 = jjObjects[i];
  1005.         if (obj2.eventID == OBJECT::CHECKPOINT && i != obj.objectID && obj2.isActive) {
  1006.           obj2.state = STATE::SLEEP;
  1007.           obj2.var[0] = 0;
  1008.         }
  1009.       }
  1010.     }
  1011.   }
  1012. }
  1013.  
  1014.  
  1015. bool onDrawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) {
  1016.         return MLLE::WeaponHook.drawAmmo(player, canvas);
  1017. }
  1018.  
  1019.  
  1020. jjTEXTAPPEARANCE SignTextAppearance = STRING::NORMAL;
  1021. class Sign {
  1022.         private int xPos, yPos; //These pixel-based positions will be generated from tile-based positions in the constructor by multiplying by 32
  1023.         private string text;
  1024.         private uint widthOfText;
  1025.         Sign(){} //AngelScript requires any class that appears in any array to have an explicit default constructor, even if it's never called
  1026.         Sign(int xTile, int yTile, const string &in t) {
  1027.                 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
  1028.                 yPos = yTile * 32; //
  1029.                 text = t;
  1030.                 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.
  1031.                 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.
  1032.                 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.
  1033.         }
  1034.         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.
  1035.                 layer.drawRectangle(xPos, yPos - 16, widthOfText + 8, 55, 0, SPRITE::TRANSLUCENT);
  1036.                 layer.drawString(xPos, yPos, text, STRING::SMALL, SignTextAppearance, 0, SPRITE::BLEND_HARDLIGHT, textIntensity);
  1037.         }
  1038. }
  1039. const array<Sign> Signs = {
  1040.         Sign(249, 12, "The sun is about to set.\nIt's not safe to linger around."),
  1041.         Sign(198, 9, "A sandstorm is coming lad!\nBetter head back to the city."),
  1042.         Sign(237, 25, "Turtles destroyed our totems.\nWrath of the gods is coming!"),
  1043.         Sign(164, 61, "I'm the Emperor Jazztezuma II.\nWhat you are looking for is beneath the Temple of Sun."),
  1044.         Sign(161, 13, "Collect all the food in these lands\nwithout dying and sugar rush will happen."),
  1045.         Sign(18, 61, "It is rumoured that a Frog Spirit was wandering\naround the Sacred Woods to prtoect our women from turtles."),
  1046.         Sign(166, 48, "Press P if you'd like to\ntrade this ammo for 1 00 Red Gems."),
  1047. };
  1048.  
  1049. void onDrawLayer3(jjPLAYER@, jjCANVAS@ layer) {
  1050.         if(jjKey[0x54] && textdisappear == false){
  1051.         const uint8 textIntensity = 200 + int(jjSin(jjGameTicks * 16) * 50);
  1052.         for (uint signID = 0; signID < Signs.length; ++signID)
  1053.                 Signs[signID].draw(layer, textIntensity);
  1054. }
  1055. }