Downloads containing mo4a_1-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, DefaultWeapons::Blaster(), null, DefaultWeapons::Blaster()}); ///@MLLE-Generated
#include "MLLE-Include-1.5w.asc" ///@MLLE-Generated
#pragma require "mo4a_1-3.j2l" ///@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_1.pal"
bool ElevatorUp = false, totemfixed = false; 
int exit = 0;


void onLevelLoad()  {
	gem::restorePlayerGems();
	jjWaterLighting = WATERLIGHT::GLOBAL;
	jjSetWaterLevel(2456, true);
	jjLevelName = ("@@@@@@@@@Totem Hills");
	jjIsSnowing = true;
	jjSnowingType = SNOWING::RAIN;
	jjSnowingIntensity = 22;

	if(jjTriggers[9] == false) {
	jjPAL firePal;
	firePal.load("mo4a_1.pal");
	firePal.apply();}

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

	Jazz1::MakeEnemy(OBJECT::DRAGONFLY, Jazz1::Enemies::Jungrock_RedBuzzer).SetUsesJJ2StyleDeathAnimation(true);
	Jazz1::MakeEnemy(OBJECT::NORMTURTLE, Jazz1::Enemies::Holidaius_SnowMonkey).SetUsesJJ2StyleDeathAnimation(true);
	Jazz1::MakeEnemy(OBJECT::HATTER, Jazz1::Enemies::Marbelara_Schwarzenguard, true).SetUsesJJ2StyleDeathAnimation(true).SetBulletFireSound(SOUND::INTRO_SHOT1).SetBulletExplosionSound(SOUND::COMMON_GUNSM1);

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

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

	jjObjectPresets[OBJECT::SONICPLATFORM].scriptedCollisions = true;
	jjObjectPresets[OBJECT::SONICPLATFORM].behavior = Elevator;
	jjObjectPresets[OBJECT::SONICPLATFORM].deactivates = false;

 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;
  }

}

bool keypicked = false;

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 key(0, 40*32, 1*32, 1*32, 4);
	frame.hotSpotY = -frame.width/2;
	key.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[10] = true;
		keypicked = true;
		p.cameraFreeze(118*32, 58*32, true, true);
		obj.behavior = BEHAVIOR::EXPLOSION2;
		jjSample(obj.xPos, obj.yPos, SOUND::MENUSOUNDS_TYPEENTER, 1000);

		return true;
	}
}

void Elevator (jjOBJ@ obj) {

	switch (obj.state) {
		case STATE::START:
			obj.direction = obj.ySpeed = 2;
			obj.determineCurAnim(ANIM::SONICPLAT, 0);   
			obj.determineCurFrame();
			obj.playerHandling = HANDLING::SPECIAL;
			obj.state = STATE::FLY;
			obj.beSolid();
		case STATE::FLY:
			obj.beSolid();
			if(p.keyUp && ElevatorUp == true && p.xPos>obj.xPos-32 && p.xPos<obj.xPos+32) {
			obj.yPos = obj.yPos + obj.ySpeed;
			obj.direction = obj.ySpeed = -2; 
			 }
			if(p.keyDown && ElevatorUp == true && p.xPos>obj.xPos-32 && p.xPos<obj.xPos+32) {
			obj.yPos = obj.yPos + obj.ySpeed;
			p.buttstomp = 90;
			p.ySpeed=3;
			obj.direction = obj.ySpeed = 2; 
			if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1)) {
				obj.ySpeed = 0;
			} 
			}
			obj.draw();
			break;

	}
}

void onMain() {
	jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::ORANGE].curAnim];
	anim.frameCount = 1;
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
	jjPIXELMAP fruit(0, 41*32, 1*32, 1*32, 4);
	fruit.save(frame);
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); 
}

}


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;
		jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, -8);
}
	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) {
		p.coins += 1; 
		obj.behavior = BEHAVIOR::EXPLOSION2;
		jjSample(obj.xPos, obj.yPos, SOUND::COMMON_COIN, 1000);

		return true;
	}
}

bool startrush = false, readytorush = false, control = true;

void onPlayer(jjPLAYER@ play) {
		if(control==false)
		{p.keyLeft = false;
		p.keyRight = false;
		p.keyDown = false;}

		if(p.idle > 100)
		{p.cameraUnfreeze(true);
		control=true;}
		else if (p.idle > 5 && (p.keyLeft || p.keyRight || p.keyJump || p.keyFire))
		{p.cameraUnfreeze(true);
		control=true;}

	jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::EXTRALIFE].curAnim];
	anim.frameCount = 1;
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
	jjPIXELMAP to(0, 39*32, 1*32, 1*32, 4);
	frame.hotSpotY = -frame.width/2;
	to.save(frame);


	if(p.xPos > 116*32) {
	jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::AIRBOARD].curAnim];
	anim.frameCount = 1;
	jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
	jjPIXELMAP key(0, 40*32, 1*32, 1*32, 4);
	frame.hotSpotY = -frame.width/2; }

  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
    }
  }
	gem::trackPlayerGems(p);
	gem::upgradeHealth(p);

	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;
	}

	exit = 0;
	if(jjTriggers[9]==true)
		{jjIsSnowing = false;
		exit += 1;}
	if(jjTriggers[7]==true)
		{exit += 1;}
	if(jjTriggers[5]==true)
		{exit += 1;}
	if(jjTriggers[4]==true)
		{exit += 1;}
	if(jjTriggers[3]==true)
		{exit += 1;}
	if(jjTriggers[2]==true)
		{exit += 1;}
	if(jjTriggers[1]==true)
		{exit += 1;}

	if(jjTriggers[1]==true && jjTriggers[2]==true && jjTriggers[3]==true && jjTriggers[4]==true && jjTriggers[5]==true && jjTriggers[7]==true && jjTriggers[9]==true)
		{ElevatorUp = true;}

	p.lightType = LIGHT::NONE;
	if(p.coins==0)
		{p.coins +=2;}
	if(p.yPos > jjWaterLevel && totemfixed == false)
		{p.health = 0;}

	for (int i = 1; i < jjObjectCount; i++) {
	jjOBJ@ o = jjObjects[i];
		if (o.isActive && o.eventID == OBJECT::SILVERCOIN && p.coins >= 3) {
		o.state = STATE::KILL;
		}

	}

	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;}
	}
}


void onFunction0(jjPLAYER@ p){
	p.cameraFreeze(122*32, 2*32, true, true);


}
void onFunction1(jjPLAYER@ p){
	p.cameraUnfreeze();
}

void onFunction2(jjPLAYER@ p){
	if(jjTriggers[2] == false && totemfixed == false){
	jjSetWaterLevel(320, false);
	jjTriggers[2] = true;}

}

void onFunction3(jjPLAYER@ p){
	if(jjTriggers[3] == false){
	jjSetWaterLevel(72*32, false);
	jjTriggers[3] = true;}
}

void onFunction4(jjPLAYER@ p){
	if(jjTriggers[4] == false && totemfixed == false){
	jjSetWaterLevel(1472, false);
	jjTriggers[4] = true;}
}

void onFunction5(jjPLAYER@ p){
	if(jjTriggers[5] == false && totemfixed == false){
	jjSetWaterLevel(77*32, false);
	jjTriggers[5] = true;}

}

void onFunction6(jjPLAYER@ p){
	if(ElevatorUp == true)
		{p.showText("@@Press UP and DOWN to move the platform.");}
	if(ElevatorUp == false)
		{p.showText("@@I have to fix all of the totems@to be able to use this platform.");}
}


void onFunction7(jjPLAYER@ p){
	if(jjTriggers[7] == false && totemfixed == false){
	jjSetWaterLevel(320, false);
	jjTriggers[7] = true;}

}

void onFunction8(jjPLAYER@ p){
	if(jjTriggers[1]==false && totemfixed == false)
	jjSetWaterLevel(320, false);

}


void onFunction9(jjPLAYER@ p){
	jjPAL resPal;
	resPal.load("Aztec Empire.j2t");
	resPal.apply();
	if(jjTriggers[9] == false && totemfixed == false){
	p.showText("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Totems fixed.");
	jjSetWaterLevel(3000, true);
	totemfixed = true;
	jjMusicLoad("mo4a_South Plain - Part 1.ogg");
	jjLayerOrderSet(array<jjLAYER@> = {jjLayers[2], jjLayers[3], jjLayers[4], jjLayers[5], jjLayers[6], jjLayers[7], jjLayers[8], jjLayers[1]});
	jjTriggers[9] = true;
	}
}

void onFunction10(jjPLAYER@ p){
	if(jjTriggers[1] == false){
	jjSetWaterLevel(68*32, false);
	jjTriggers[1] = true;}

}

void onFunction11(jjPLAYER@ p){
	if(jjTriggers[3]==false){
	jjSetWaterLevel(49*32, true);
	jjTriggers[2] = false;}

}

void onFunction12(jjPLAYER@ p){
	if(jjTriggers[3]==true){
	jjSetWaterLevel(77*32, true);}

}

void onFunction13(jjPLAYER@ p){
	if(jjTriggers[5] == false)
	{jjSetWaterLevel(59*32, false);}
}

void onFunction14(jjPLAYER@ p){
	if(p.coins >=3){
	jjNxt(false, true);
	gem::saveGemData();}
	if(p.coins <3){
	p.testForCoins(3);}
}

void onFunction15(jjPLAYER@ p){
	if(jjTriggers[5] == false)
	{jjSetWaterLevel(77*32, true);
	keypicked = false;}
}

void onFunction16(jjPLAYER@ p) {
		keypicked = false;
}


bool onDrawHealth(jjPLAYER@ player, jjCANVAS@ canvas) {
    canvas.drawSprite(20, 585, ANIM::PICKUPS, 0, jjGameTicks>>2, -1, SPRITE::NORMAL);
    canvas.drawString(30, 585, formatInt(exit%8, "1") + "/7", STRING::SMALL, STRING::NORMAL);
if(keypicked == true && p.xPos > 116*32 && jjTriggers[10] == true)
    {canvas.drawSprite(100, 585, ANIM::PICKUPS, 36, jjGameTicks>>2, -1, SPRITE::NORMAL);}
    return false;
}

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



void onLevelReload() {
	if(jjTriggers[9] == false) {
	jjPAL firePal;
	firePal.load("mo4a_1.pal");
	firePal.apply();}

	if(jjTriggers[9] == true) {
	jjPAL resPal;
	resPal.load("Aztec Empire.j2t");
	resPal.apply();}

	if(jjTriggers[9]==false)
	{jjIsSnowing = true;
	jjTriggers[7] = false;
	jjSnowingType = SNOWING::RAIN;}

	if(jjTriggers[2]==false)
	{jjIsSnowing = true;
	jjTriggers[4] = false;
	jjSnowingType = SNOWING::RAIN;}

	if(jjTriggers[3]==false)
	{jjIsSnowing = true;
	jjTriggers[2] = false;
	jjSnowingType = SNOWING::RAIN;}

	if(p.xPos>192*32 && p.yPos >50*32 && jjTriggers[2] == false)
		{jjSetWaterLevel(68*32, true);}
	if(p.xPos>160*32 && p.xPos<185*32 && p.yPos <28*32 && jjTriggers[3] == false)
		{jjSetWaterLevel(49*32, true);}
	if(p.xPos>102*32 && p.xPos<124*32 && p.yPos <60*32 && p.yPos >55*32 && jjTriggers[5] == false)
		{jjSetWaterLevel(72*32, true);}
	if(p.xPos<15*32 && p.xPos > 7*32 && p.yPos >66*32 && jjTriggers[9] == false)
		{jjSetWaterLevel(77*32, true);}
	if(p.xPos<36*32 && p.yPos >56*32 && jjTriggers[7] == false)
		{jjSetWaterLevel(77*32, true);}

	jjEnableEachASFunction();
	gem::restorePlayerGems();
	jjLocalPlayers[0].lives++;
	jjWaterLighting = WATERLIGHT::GLOBAL;
  	for (uint i = 0; i < 32; ++i)
	  	jjTriggers[i] = SavedTriggers[i];
}

array<bool> SavedTriggers(32, false);
//Extendable Checkpoints by VioletCLM
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];

  
    }
  }
}

jjTEXTAPPEARANCE SignTextAppearance = STRING::NORMAL;
class Sign {
	private int xPos, yPos; //These pixel-based positions will be generated from tile-based positions in the constructor by multiplying by 32
	private string text;
	private uint widthOfText;
	Sign(){} //AngelScript requires any class that appears in any array to have an explicit default constructor, even if it's never called
	Sign(int xTile, int yTile, const string &in t) {
		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
		yPos = yTile * 32; //
		text = t;
		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.
		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.
		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.
	}
	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.
		layer.drawRectangle(xPos, yPos - 16, widthOfText + 8, 55, 0, SPRITE::TRANSLUCENT);
		layer.drawString(xPos, yPos, text, STRING::SMALL, SignTextAppearance, 0, SPRITE::BLEND_HARDLIGHT, textIntensity);
	}
}
const array<Sign> Signs = {
	Sign(134, 58, "Find the 9 distorted totems and fix them.\nOr the city will be flooded."),
};

void onDrawLayer3(jjPLAYER@, jjCANVAS@ layer) { 
	if(jjKey[0x54] && (jjTriggers[9] == false || p.yPos >68*32)){
	const uint8 textIntensity = 200 + int(jjSin(jjGameTicks * 16) * 50); 
	for (uint signID = 0; signID < Signs.length; ++signID) 
		Signs[signID].draw(layer, textIntensity);
}
}
bool onDrawAmmo(jjPLAYER@ player, jjCANVAS@ canvas) {
	return MLLE::WeaponHook.drawAmmo(player, canvas);
}