Downloads containing mo4a_3-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

const bool MLLESetupSuccessful = MLLE::Setup(array<MLLEWeaponApply@> = {null, null, DefaultWeapons::Blaster(), DefaultWeapons::Blaster(), WeaponVMega::Backfire::Weapon(), null, ArcaneWeapons::FusionCannon::Weapon(), null, ArcaneWeapons::MortarLauncher::Weapon()}); ///@MLLE-Generated
#include "MLLE-Include-1.5w.asc" ///@MLLE-Generated
#pragma require "mo4a_3-3-MLLE-Data-1.j2l" ///@MLLE-Generated
#pragma require "Damn2.j2t" ///@MLLE-Generated
#pragma require "mo4a_3-3.j2l" ///@MLLE-Generated
#include "ArcaneWeapon4.asc" ///@MLLE-Generated
#pragma require "ArcaneWeapon4.asc" ///@MLLE-Generated
#include "ArcaneWeapon9.asc" ///@MLLE-Generated
#pragma require "ArcaneWeapon9.asc" ///@MLLE-Generated
#include "WeaponVMega5.asc" ///@MLLE-Generated
#pragma require "WeaponVMega5.asc" ///@MLLE-Generated
#include "MLLE-DefaultWeapons.asc" ///@MLLE-Generated
#pragma require "MLLE-DefaultWeapons.asc" ///@MLLE-Generated
#include "Jazz1Enemies v05.asc"
#include "Resize v11.asc"
#include "TrueColor v13.asc"
#include "HH18savegems.asc"
#pragma require "mo4a_3.pal"
int SpeedUpUntil = 0;
bool passobtained = false;

bool onDrawHealth(jjPLAYER@ player, jjCANVAS@ canvas) {
	if(passobtained == true && jjTriggers[3] == true)
    {canvas.drawSprite(20, 585, ANIM::PICKUPS, 42, jjGameTicks>>2, 1, SPRITE::NORMAL);}
    return false;
}

bool onDrawLives(jjPLAYER@ player, jjCANVAS@ canvas) {return true;}

void onLevelLoad() {
	jjIsSnowing = true;
	jjSnowingType = SNOWING::RAIN;
	jjSnowingIntensity = 22;
	jjIsSnowingOutdoorsOnly = true;
jjPIXELMAP rain(32,32);
  for (uint x = 0; x < rain.width; ++x) {
    for (uint y = 0; y < rain.height; ++y) {
      if (x == 16) { //draw in the middle of the tile, xPixel 16
        if (y <= 24) rain[x,y] = 75; //if at yPixel 24 or less, use color 75
        else rain[x,y] = 74; //use color 74 for yPixels 25-32
      } else {
        rain[x,y] = 0;
      }
    }
  }
 
  jjANIMATION@ anim = jjAnimations[jjAnimSets[ANIM::COMMON].firstAnim + 2];
  for (uint frameID = 0; frameID < anim.frameCount; ++frameID) {
    jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame + frameID];
    rain.save(frame);
    frame.hotSpotX = -frame.width/2;
    frame.hotSpotY = -frame.height;
  }

	jjWaterLighting = WATERLIGHT::GLOBAL;
	jjSetWaterLevel(45*32, true);
	jjLevelName = ("@@@@@@@@@Poseidon Island");
	gem::restorePlayerGems();

	jjObjectPresets[OBJECT::SAVEPOST].behavior = CheckpointWrapper;
	jjObjectPresets[OBJECT::SAVEPOST].deactivates = false;

	Jazz1::MakeEnemy(OBJECT::HATTER, Jazz1::Enemies::Megairbase_Doofusguard).SetUsesJJ2StyleDeathAnimation(true).SetBulletFireSound(SOUND::INTRO_SHOTGRN).SetBulletExplosionSound(SOUND::COMMON_GUNSM1);
	Jazz1::MakeEnemy(OBJECT::DRAGONFLY, Jazz1::Enemies::Marbelara_Drageen).SetUsesJJ2StyleDeathAnimation(true);
	Jazz1::MakeEnemy(OBJECT::FLOATSUCKER, Jazz1::Enemies::Marbelara_Firebomb).SetUsesJJ2StyleDeathAnimation(true);
	Jazz1::MakeEnemy(OBJECT::NORMTURTLE, Jazz1::Enemies::Dreempipes_TerrapinSwimmer).SetUsesJJ2StyleDeathAnimation(true);

	jjObjectPresets[OBJECT::FRUITPLATFORM].scriptedCollisions = true;
	jjObjectPresets[OBJECT::FRUITPLATFORM].behavior = Wheel();

	jjObjectPresets[OBJECT::BOLLPLATFORM].scriptedCollisions = true;
	jjObjectPresets[OBJECT::PINKPLATFORM].behavior = Lava;
	jjObjectPresets[OBJECT::PINKPLATFORM].playerHandling = HANDLING::SPECIAL;
	jjObjectPresets[OBJECT::PINKPLATFORM].bulletHandling = HANDLING::IGNOREBULLET;
	jjObjectPresets[OBJECT::PINKPLATFORM].deactivates = false;

	//jjObjectPresets[OBJECT::GRASSPLATFORM].xSpeed = 5;
	jjObjectPresets[OBJECT::GRASSPLATFORM].scriptedCollisions = true;
	jjObjectPresets[OBJECT::GRASSPLATFORM].behavior = PlatformH;

	jjObjectPresets[OBJECT::BIGBOX].behavior = Computer();
	jjObjectPresets[OBJECT::BIGBOX].scriptedCollisions = true;

	jjObjectPresets[OBJECT::AIRBOARD].behavior = Key();
	jjObjectPresets[OBJECT::AIRBOARD].scriptedCollisions = true;

	jjObjectPresets[OBJECT::TRIGGERCRATE].behavior = Junk();
	jjObjectPresets[OBJECT::TRIGGERCRATE].scriptedCollisions = true;

	jjObjectPresets[OBJECT::FREEZEENEMIES].behavior = Pass();
	jjObjectPresets[OBJECT::FREEZEENEMIES].scriptedCollisions = true;

	jjObjectPresets[OBJECT::SMALLTREE].determineCurAnim(ANIM::BIGTREE,0);

	jjObjectPresets[OBJECT::SILVERCOIN].behavior = PlatinCoin();
	jjObjectPresets[OBJECT::SILVERCOIN].scriptedCollisions = true;

	jjObjectPresets[OBJECT::SONICPLATFORM].scriptedCollisions = true;
	jjObjectPresets[OBJECT::SONICPLATFORM].behavior = SpikeBump();
	jjObjectPresets[OBJECT::SONICPLATFORM].deactivates = false;
	
	jjObjectPresets[OBJECT::STOPWATCH].behavior = Fastrun();
	jjObjectPresets[OBJECT::STOPWATCH].scriptedCollisions = true;

	jjObjectPresets[OBJECT::ROBOT].behavior = Robot();
	jjObjectPresets[OBJECT::ROBOT].playerHandling = HANDLING::SPECIAL;
	jjObjectPresets[OBJECT::ROBOT].scriptedCollisions = true;

	jjObjectPresets[OBJECT::CHICKENLEG].behavior = AntiCarrot();
	jjObjectPresets[OBJECT::CHICKENLEG].scriptedCollisions = true;
	jjObjectPresets[OBJECT::CHICKENLEG].determineCurAnim(ANIM::PICKUPS,82);

	jjObjectPresets[OBJECT::LIZARD].scriptedCollisions = true;
	jjObjectPresets[OBJECT::LIZARD].determineCurAnim(ANIM::ROBOT,4);
	jjObjectPresets[OBJECT::LIZARD].behavior = Robot2();

 

}

class Junk : jjBEHAVIORINTERFACE {

	void onBehave(jjOBJ@ obj) {
		obj.behave(BEHAVIOR::MONITOR, false);
		++obj.counter;
		obj.playerHandling = HANDLING::SPECIAL;

		jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::INVISIBLE);
}

	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
		if(bullet !is null && bullet.var[3] == WEAPON::GUN8)
		{jjTriggers[15] = true;
		obj.delete();}


		return true;
	}

}


class PlatinCoin : jjBEHAVIORINTERFACE {

	void onBehave(jjOBJ@ obj) {
		if(p.coins >=3)
			{obj.delete();}
		obj.behave(BEHAVIOR::PICKUP, false);
		++obj.counter; 
		obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
		if(itsraining == true)
		{jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -8);}
		else jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::TRANSLUCENTPALSHIFT, -8);
}

	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
		if(itsraining == true)
		{p.coins += 1; 
		obj.behavior = BEHAVIOR::EXPLOSION2;
		jjSample(obj.xPos, obj.yPos, SOUND::COMMON_COIN, 1000);}


		return true;
	}
}

class AntiCarrot: jjBEHAVIORINTERFACE {

	void onBehave(jjOBJ@ obj) {
		obj.determineCurFrame();
		obj.behave(BEHAVIOR::PICKUP, false);
		++obj.counter; 
		obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
		jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -24);
	}

	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ p, int force) { 
		p.health = 1;
		p.blink = 245;	
		jjSample(obj.xPos, obj.yPos, SOUND::COMMON_EAT1, 1000);
		obj.frameID = 0;
		obj.behavior = BEHAVIOR::EXPLOSION2;

		return true; 
	}
}

void onFunction0(jjPLAYER@ p) {
if(lavarise==false)
{p.showText("@@Hey! That must be the Library Pass@the girl has lost!");
jjEnabledASFunctions[0] = false;}
}

void onFunction1(jjPLAYER@ p) {
	p.showText("@@@@@@@@@@@@@@@@@@@@@@@@@Mt. Poseidon", STRING::MEDIUM);
	jjLayerOrderSet(array<jjLAYER@> = {jjLayers[1], jjLayers[2], jjLayers[3], jjLayers[4], jjLayers[5], jjLayers[7], jjLayers[8], jjLayers[6]});
	jjEnabledASFunctions[1] = false;}

void onFunction2(jjPLAYER@ p) {
	jjMusicLoad("mo4a_Doc's Cave.ogg");
	p.showText("@@|||||||Intruder Alert on Facilty 3!@Destroy the target!");
		p.activateBoss();

}

void onFunction3(jjPLAYER@ p) {
	jjMusicLoad("lwe_a7.mod");
	p.bossActivated = false;

}

void onFunction4(jjPLAYER@ p) {
	if(p.yPos >43*32)
		{p.lighting = 50;}
	if(itsraining == false) {
	jjSetWaterLevel(66*32, true);
	jjPAL firePal;
	firePal.load("mo4a_3.pal");
	firePal.apply();}
}

bool comptext = false, junktext = false;
void onFunction5(jjPLAYER@ p) {
	if(comptext == false) {
	p.showText("@I can move the computer to plug it.");
	comptext = true;
	}

}
void onFunction6(jjPLAYER@ p) {
	if(junktext == false && jjTriggers[15] == false) {
	p.showText("@@My weapons won't be able to@clear the path.");
	junktext = true;
	}

}

void onFunction7(jjPLAYER@ p) 
	{p.health = 0;}

void onFunction8(jjPLAYER@ p)  {
	if(itsraining == false)
	{p.cameraFreeze(190*32, 10*32, true, false);
	jjEnabledASFunctions[8] = false;}
	}

int spring = 0;
bool spike = false;
class SpikeBump : jjBEHAVIORINTERFACE {

void onBehave(jjOBJ@ obj) {

	switch (obj.state) {
		case STATE::START:
			obj.determineCurFrame();
			obj.state = STATE::FLY;

		case STATE::FLY:
			obj.playerHandling = HANDLING::SPECIAL;
			obj.deactivates = false;
			if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1)) {
				obj.direction = obj.xSpeed = -obj.xSpeed;
			}
			
			if(obj.xPos > p.xPos + 64 || obj.xPos < p.xPos - 64 || obj.yPos > p.yPos + 64 || obj.yPos < p.yPos - 64)
			{obj.determineCurAnim(ANIM::BOLLPLAT, 0); 
			jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -8);
			obj.determineCurFrame();}
			else {jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -24);}
			break;

		
	}
}

	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) { 
		if(bullet is null && play !is null && (force == -1 || force == 1))
			{spring = jjGameTicks + 1*61;
			obj.determineCurAnim(ANIM::BOLLPLAT, 0); 
			jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -24);
			obj.determineCurFrame();
			p.buttstomp = 121;
			jjSample(obj.xPos, obj.yPos, SOUND::PINBALL_BELL, 1000);}
		if(force == 0 && spring < jjGameTicks)
			{play.hurt();
			obj.determineCurAnim(ANIM::SPIKEBOLL, 0);   
			obj.determineCurFrame();
			if(spike == false)
			{jjSample(obj.xPos, obj.yPos, SOUND::COMMON_METALHIT, 1000);}
			spike = true;}
		return true;
		}

}

void PlatformH (jjOBJ@ obj) {

	switch (obj.state) {
		case STATE::START:
			obj.direction = obj.xSpeed = -2;
			obj.playerHandling = HANDLING::SPECIAL;
			obj.state = STATE::FLY;
			obj.beSolid();
		case STATE::FLY:
			if(lavarise==true)
			{obj.xPos = obj.xPos + obj.xSpeed;}
			obj.beSolid();
			obj.deactivates = false;
			if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1)) {
				obj.direction = obj.xSpeed = -obj.xSpeed;
			}
			obj.determineCurAnim(ANIM::GRASSPLAT, 0);   
			obj.determineCurFrame();
			jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 32);	
			break;
	}
}

class Wheel : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj){

	obj.playerHandling = HANDLING::SPECIAL;
		obj.energy = 2;
		if(obj.energy == 0)
		{obj.energy += 1;}
		jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::FRUITPLATFORM].curAnim];
		anim.frameCount = 1;
		jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
		jjPIXELMAP lamp(0, 31*32, 2*32, 2*32, 5);
		lamp.save(frame);
		frame.hotSpotX = -32;
		obj.behave(BEHAVIOR::BUMP, false);
	if(obj.justHit == 0)
	{jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::BRIGHTNESS, 180);}
	else 	obj.draw();
	}
	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) { 
		obj.bulletHandling = HANDLING::HURTBYBULLET;
		if(play !is null && bullet !is null && lavarise == true && jjTriggers[1] == false)
			{itsraining = true;
			jjPAL resPal;
			resPal.load("Atlantis Island-lite.j2t");
			resPal.apply();
			p.showText("@@Yay! Lava's under control.@I'll survive.");
			jjSample(p.xPos, p.yPos, SOUND::ROBOT_HYDROPUF);
			jjTriggers[1] = true;}
		if(passobtained == false && bullet.xPos > obj.xPos)
			{bullet.delete();
			p.showText("@@That wheel might release some water.@No point in doing that right now.");}
		return true; 
	}
}

void Lava (jjOBJ@ obj) {
jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::PINKPLATFORM].curAnim];
	anim.frameCount = 1;
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
	jjPIXELMAP lava(0, 45*32, 70*32, 11*32, 5);
	lava.save(frame);
	frame.hotSpotX = -60;
		jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::NORMAL);
			if(p.yPos>obj.yPos-22 && p.xPos > 134*32 && itsraining == false)
				{p.health = 0;}
if(itsraining == true && lavarise == true && p.xPos < 130*32 && p.yPos > 28*32)
{obj.delete();
obj.behave(BEHAVIOR::EXPLOSION2);}
if(itsraining == true && lavarise == true) 
		{obj.state = STATE::FREEZE;
		obj.beSolid();
		jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::SINGLEHUE, 59);}
switch (obj.state) {
		case STATE::START:
			obj.state = STATE::FLY;

		case STATE::FLY:
		++obj.counter; 
		obj.xPos = jjSin(obj.counter*4)*4 + obj.xOrg;
		if(lavarise == true && p.xPos >134*32)
			
			{obj.direction = obj.ySpeed = -0.2;
			obj.yPos = obj.yPos + obj.ySpeed;
			}
		obj.deactivates = false;
			if(p.xPos <  116*32)
			obj.deactivate();
		

			break;

	}

}


void onMain() {

gem::deleteCollectedGems();
if(jjKey[9] && jjKey[0x51]) {
p.morphTo(CHAR::JAZZ, false); 
}
if(jjKey[9] && jjKey[0x57]) {
p.morphTo(CHAR::SPAZ, false); 
}
if(jjKey[9] && jjKey[0x45]) {
p.morphTo(CHAR::LORI, false); 
}

	jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::PEACH].curAnim];
	anim.frameCount = 1;
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
	jjPIXELMAP fruit(0, 30*32, 1*32, 1*32, 5);
	fruit.save(frame);
	frame.hotSpotX = -frame.width / 2;
}

class Computer : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) {

	jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::BIGBOX].curAnim];
	anim.frameCount = 1;
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
	jjPIXELMAP comp(0, 33*32, 3*32, 2*32, 5);
	comp.save(frame);
	frame.hotSpotX = -42;

	if(obj.xPos<78*32)
	{jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::BIGBOX].curAnim];
	anim.frameCount = 1;
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
	jjPIXELMAP comp(0, 23*32, 3*32, 2*32, 5);
	comp.save(frame);
	frame.hotSpotX = -32;
	p.showText("@@@@@@@@@@@@@@@@@@@Robot control unit.@Hit 'A' and 'D' to walk.@Hit '0' to fire.");
	obj.yPos = obj.yPos + 120;
	electric = true;
	jjTriggers[6]=true;
	jjSample(p.xPos, p.yPos, SOUND::INTRO_MONSTER2, 1000);
	jjSample(obj.xPos, obj.yPos, SOUND::COMMON_ITEMTRE, 1000);}
			obj.behave(BEHAVIOR::BIGOBJECT);}

}

bool electric = false;
class Robot : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) {
		if(obj.energy <= 0) {
			obj.state = STATE::KILL;
			p.boss = -1;
			jjTriggers[2] = true;
			jjAddObject(OBJECT::LIZARD, obj.xPos, obj.yPos);
			robotdefeated = true;
			obj.behave(BEHAVIOR::EXPLOSION2);
			obj.scriptedCollisions = true;
			p.activateBoss(false);
		}
	
		else obj.behave(BEHAVIOR::ROBOT, false);
		if(obj.justHit == 0)	
		{jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -8);}
		else obj.draw();
	}
	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) { 
		if(play !is null && bullet !is null)
		obj.bulletHandling = HANDLING::DETECTBULLET;
		obj.causesRicochet = true;
		if(play !is null && force == 0)
		play.hurt();
		if(play !is null && (force == -1 || force == 1))
		obj.playerHandling = HANDLING::ENEMY;
		return true; 
	}

}

class Robot2 : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) {
	if(electric == true)
	{p.cameraFreeze(obj.xPos, obj.yPos, true, true);}
		if((jjKey[0x30] || jjKey[0x60]) && electric==true && obj.xPos > 75*32 && obj.xPos < 88*32 && obj.yPos >59*32)
			{obj.determineCurAnim(ANIM::ROBOT,2);
				jjOBJ@ o = jjObjects[obj.fireBullet(OBJECT::FIREBALLBULLET)];
					o.behavior = BEHAVIOR::BULLET;
					o.determineCurAnim(ANIM::ROBOT, 0);
					o.killAnim = jjObjectPresets[OBJECT::BOUNCERBULLET].killAnim;
					o.playerHandling = HANDLING::PLAYERBULLET;
					o.bulletHandling = HANDLING::HURTBYBULLET;
					o.lightType = LIGHT::POINT;
					o.xPos = obj.xPos + 26*obj.direction;
					o.xAcc = .2;
					int xs = (jjRandom() & 49);
					o.xSpeed = 0.2;
					int ys = (jjRandom() & 46);
					o.ySpeed = ys - 3;}

		if(jjKey[0x44] && electric==true && obj.xPos < 88*32 && obj.yPos >59*32)
			{obj.xPos = obj.xPos + 10;
			obj.determineCurAnim(ANIM::ROBOT,15);
			obj.direction = 1;}
		if(jjKey[0x41] && electric==true && obj.xPos > 77*32 && obj.yPos >59*32)
			{obj.xPos = obj.xPos - 10;
			obj.determineCurAnim(ANIM::ROBOT,15);
			obj.direction = -1;}

		if(jjTriggers[15] == true && electric == true)
			{jjPARTICLE@ particle = jjAddParticle(PARTICLE::SMOKE);
			particle.xPos = 91*32;
			particle.yPos = 59*32;
			jjTriggers[15]=true;
			electric = false;
			p.showText("@Mission accomplished!");
			jjSample(p.xPos, p.yPos, SOUND::INTRO_BOEM2);}



	else obj.behave(BEHAVIOR::ROBOT, true);
	obj.determineCurAnim(ANIM::ROBOT,4);

	jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -8);
	obj.playerHandling = HANDLING::PLAYERBULLET;
	}
}

class Key : jjBEHAVIORINTERFACE {

	void onBehave(jjOBJ@ obj) {
		obj.behave(BEHAVIOR::PICKUP, false);
	jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::AIRBOARD].curAnim];
	anim.frameCount = 1; 
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
		jjPIXELMAP pump(0, 43*32, 1*32, 1*32, 5);
	pump.save(frame);
		++obj.counter; 
		obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
		jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::NORMAL);
}
	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) { 
		jjTriggers[15] = true;
		obj.behavior = BEHAVIOR::EXPLOSION2;
		jjSample(obj.xPos, obj.yPos, SOUND::MENUSOUNDS_TYPEENTER, 1000);

		return true; 
	}
}

bool itsraining = false;
bool lavarise= false;
class Pass : jjBEHAVIORINTERFACE {

	void onBehave(jjOBJ@ obj) {
		obj.behave(BEHAVIOR::PICKUP, false);
		if(passobtained == true)
			{obj.delete();}

jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::FREEZEENEMIES].curAnim];
	anim.frameCount = 1; 
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
	jjPIXELMAP pump(0, 44*32, 1*32, 1*32, 5);
	pump.save(frame);
		++obj.counter; 
		obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;
		jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::NORMAL);
}
	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) { 
		lavarise=true;
		//jjTriggers[3] = true;
		obj.behavior = BEHAVIOR::EXPLOSION2;
		jjSample(obj.xPos, obj.yPos, SOUND::MENUSOUNDS_TYPEENTER, 1000);
		passobtained = true;
		return true; 
	}
}
class Fastrun : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) {

obj.behave(BEHAVIOR::PICKUP, false);
obj.determineCurAnim(ANIM::PICKUPS, 33);
++obj.counter; 
		obj.yPos = jjSin(obj.counter*15 + 5)*4 + obj.yOrg;

		jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -24);

}

	bool onObjectHit(jjOBJ@ obj, jjOBJ@, jjPLAYER@ play, int force) {
	play.timerStart(800);
		SpeedUpUntil = jjGameTicks + 13 * 61;
		obj.behavior = BEHAVIOR::EXPLOSION2;
		obj.frameID = 0;
		jjSample(obj.xPos, obj.yPos, SOUND::COMMON_PICKUP1, 6000);

		return true;
	}

}

bool startrush = false, readytorush = false, robotdefeated = false;

void onPlayer(jjPLAYER@ play) {

  for (int i = 0; i < 1024; i++) { //loop through the global array jjParticles[1024]
    jjPARTICLE@ particle = jjParticles[i];
    if (particle.type == PARTICLE::RAIN) {
      particle.xSpeed = 0; //make rain fall straight down
      particle.ySpeed = play.ySpeed < 0? 10 : int(10 + play.ySpeed); //the rain speed accounts for differences in the player speed, and so won't appear to fall more slowly when the player is falling
    }
  }

if (p.idle > 5 && p.xPos >180*32 && (p.keyLeft || p.keyRight || p.keyJump || p.keyFire))
		{spike = false;}

for (int i = 0; i < 1024; i++) { //loop through the global array jjParticles[1024]
    jjPARTICLE@ particle = jjParticles[i];
    if (particle.type == PARTICLE::RAIN) {
      particle.xSpeed = 0; //make rain fall straight down
      particle.ySpeed = play.ySpeed < 0? 10 : int(10 + play.ySpeed); //the rain speed accounts for differences in the player speed, and so won't appear to fall more slowly when the player is falling
    }
  }
	if(electric==true)
	{p.keyRight = false;
	p.keyLeft = false;
	p.keyDown = false;
	p.keyUp = false;
	p.keyJump = false;}

	if(electric==false && p.yPos > 15*32)
	{p.cameraUnfreeze();}

	for (int i = 1; i < jjObjectCount; i++) { 
		jjOBJ@ o = jjObjects[i];
		if (jjTriggers[15] == true && o.eventID == OBJECT::ROBOT) {
			o.delete();
		}
	}

	for (int i = 1; i < jjObjectCount; i++) { 
		jjOBJ@ obb = jjObjects[i];
		if (jjTriggers[15] == true && obb.eventID == OBJECT::DEVANROBOT) {
			obb.delete();
		}
	}

	for (int i = 1; i < jjObjectCount; i++) { 
		jjOBJ@ obb = jjObjects[i];
		if (jjTriggers[15] == true && obb.isActive && obb.eventID == OBJECT::DEVANROBOT) {
			obb.delete();
		}
	}

	if(p.food == 100 && jjKey[0x52] == false && startrush == false)
		{p.showText("@@@@@@@@@@@@@@@@Press 'R' when you need to use Sugar Rush!", STRING::MEDIUM);
		p.startSugarRush(0);
		startrush = true;
		readytorush = true;}

	if(readytorush == true)
		{p.food = 100;}

	if(p.food == 100 && jjKey[0x52])
		{p.startSugarRush(1400);
		p.food = 0;
		readytorush = false;
		startrush = false;
	}


	gem::trackPlayerGems(p);
	gem::upgradeHealth(p);
	if(p.xPos > 136*32 && itsraining == false)
	{jjMusicLoad("mo4a_Umber's Sacrifice.ogg");}

	if(itsraining == true)
	{jjMusicLoad("mo4a_Riding the Shell.ogg");}

	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::SEEKERAMMO3 && p.ammo[WEAPON::SEEKER] < 1) {
			o.state = STATE::KILL;}
	}
	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::RFAMMO3 && p.ammo[WEAPON::RF] < 1) {
			o.state = STATE::KILL;}
	}
	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::TNTAMMO3 && p.ammo[WEAPON::TNT] < 1) {
			o.state = STATE::KILL;}
	}
	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::GUN9AMMO3 && p.ammo[WEAPON::GUN9] < 1) {
			o.state = STATE::KILL;}
	}
	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::SEEKERPOWERUP && p.ammo[WEAPON::SEEKER] < 1) {
			o.state = STATE::KILL;}
	}
	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::RFPOWERUP && p.ammo[WEAPON::RF] < 1) {
			o.state = STATE::KILL;}
	}
	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::TNTPOWERUP && p.ammo[WEAPON::TNT] < 1) {
			o.state = STATE::KILL;}
	}
	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::GUN9POWERUP && p.ammo[WEAPON::GUN9] < 1) {
			o.state = STATE::KILL;}
	}

	if(p.coins == 0)
		{p.coins +=2;}
	if(spring > jjGameTicks)
		{p.ySpeed = -10;}
	if(p.coins<3 && p.xPos < 3*32 && p.yPos < 40*32 && p.yPos > 34*32)
		{p.testForCoins(3);}
	if(p.coins>=3 && p.xPos < 3*32 && p.yPos < 40*32 && p.yPos > 34*32)
		{jjNxt(false, true);
	gem::saveGemData();}

	if ((p.idle > 5 && p.xPos >170*32 && (p.keyLeft || p.keyRight || p.keyJump || p.keyFire))|| p.xPos < 170*32 || p.idle > 100)
		{p.cameraUnfreeze();}
	p.lightType = LIGHT::NONE;
  	if (SpeedUpUntil > jjGameTicks) {
		play.invincibility = 10;
		play.keyRun = true;
	if(play.keyRight)
		play.xSpeed = 30;
	if(play.keyLeft)
		play.xSpeed = -30;
		jjTriggers[5] = true;
	}

		if(passobtained == true)
		{jjTriggers[3] = true;}


if (SpeedUpUntil < jjGameTicks) {

play.jumpStrength = -10;
		jjTriggers[5] = false;
}
}

array<bool> SavedTriggers(32, false); //you will need some way to keep track of whatever information you want saved... a global variable is the simplest choice

 
void CheckpointWrapper(jjOBJ@ obj) {
  if (obj.state == STATE::STOP) { //don't do anything anymore
    jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 8);
  } else if (obj.state == STATE::DEACTIVATE) { //due to death
    obj.deactivate();
  } else {
    obj.behave(BEHAVIOR::CHECKPOINT);
	jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, 8);
    if (obj.state == STATE::DONE) { //triggered by the player hitting it
      obj.state = STATE::STOP;
      //save the current state of some properties
      for (uint i = 0; i < 32; ++i)
        SavedTriggers[i] = jjTriggers[i];

      //OPTIONAL: this loop makes checkpoints reusable, so only the most recent checkpoint you touched is ever active
      for (int i = jjObjectCount; --i > 0;) {
        jjOBJ@ obj2 = jjObjects[i];
        if (obj2.eventID == OBJECT::CHECKPOINT && i != obj.objectID && obj2.isActive) {
          obj2.state = STATE::SLEEP;
          obj2.var[0] = 0;
        }
      }
    }
  }
}

void onLevelReLoad(jjPLAYER@ play) {

  for (uint i = 0; i < 32; ++i)
    jjTriggers[i] = SavedTriggers[i]; //although this example uses jjTriggers, other things should work as well
	jjWaterLighting = WATERLIGHT::GLOBAL;
	gem::restorePlayerGems();
	jjLocalPlayers[0].lives++;
	play.jumpStrength = -10;
	jjTriggers[5] = false;
	lavarise = false;	

}
bool onDrawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) {
	return MLLE::WeaponHook.drawAmmo(player, canvas);
}