Downloads containing hgfRMfinalboss.j2as

Downloads
Name Author Game Mode Rating
JJ2+ Only: The Redacted Missions happygreenfrog Single player 6.9 Download file

File preview

#include "MLLE-Include-1.4.asc"
const bool MLLESetupSuccessful = MLLE::Setup();
#pragma require "hgfRMfinalboss.j2l"
#pragma require "RMFinalBoss.it"

//thanks to Sir Ementaler, Violet CLM, and szmol96 for the scripting help!

void onLevelLoad() {
 //jjObjectPresets[OBJECT::DEVILDEVAN].behavior = bossBehave;
 jjObjectPresets[OBJECT::BUBBA].behavior = devanForce();
 jjObjectPresets[OBJECT::BUBBA].isFreezable = false;
 jjObjectPresets[OBJECT::BUBBA].energy = 50+(jjDifficulty*2);
 jjObjectPresets[OBJECT::BUBBA].playerHandling = HANDLING::SPECIAL;
 jjObjectPresets[OBJECT::BUBBA].bulletHandling = HANDLING::DETECTBULLET;
 jjObjectPresets[OBJECT::BUBBA].scriptedCollisions = true;
 //jjObjectPresets[OBJECT::BUBBA].causesRicochet = true;
 jjUseLayer8Speeds = true;
 //just a thing I borrowed from plusPixelMapEx
 jjANIMATION@ anim = jjAnimations[jjObjectPresets[OBJECT::BUBBA].curAnim];
 anim.frameCount = 1;
 jjANIMFRAME@ frame = jjAnimFrames[anim.firstFrame];
 jjANIMFRAME@ replacedframe = jjAnimFrames[jjAnimations[jjAnimSets[ANIM::PINBALL].firstAnim+2].firstFrame];
 frame = replacedframe;
 frame.hotSpotX = -frame.width / 2;
 frame.hotSpotY = -frame.height / 2;
}

int rPart(float x,float y) {
 // render a part of Devan Force
 jjDrawSprite(x, y, ANIM::PINBALL, 0, 0, 0);
 return 0;
}

int rTurret(float x,float y, int dir) {
 // render a part of Devan Force
 jjDrawSprite(x, y, ANIM::SONCSHIP, 6, dir, 0);
 return 0;
}

int rUpTurret(float x,float y, int dir) {
 // render a part of Devan Force
 jjDrawResizedSprite(x, y, ANIM::SONCSHIP, 6, dir, 1, -1);
 return 0;
}

int blasterB(float x,float y,int objID,float speed)
{
 jjOBJ@ bullet = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, x, y, objID)];
 bullet.behavior = BEHAVIOR::BULLET;
 bullet.determineCurAnim(ANIM::AMMO, 21);
 bullet.playerHandling = HANDLING::ENEMYBULLET;
 bullet.ySpeed = speed;
 jjSample(x, y, SOUND::AMMO_LASER);
 return 0;
}

int laserB(float x,float y,int objID,float xSpd, float ySpd)
{
 jjOBJ@ bullet = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, x, y, objID)];
 bullet.behavior = BEHAVIOR::BULLET;
 bullet.determineCurAnim(ANIM::AMMO, 61);
 bullet.playerHandling = HANDLING::ENEMYBULLET;
 bullet.xSpeed = xSpd;
 bullet.ySpeed = ySpd;
 bullet.counterEnd = 255;
 jjSample(x, y, SOUND::COMMON_ELECTRIC1);
 return 0;
}

int asterB(float x,float y,int objID,float xSpd, float ySpd)
{
 jjOBJ@ bullet = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, x, y, objID)];
 bullet.behavior = BEHAVIOR::BULLET;
 bullet.determineCurAnim(ANIM::AMMO, 11);
 bullet.playerHandling = HANDLING::ENEMYBULLET;
 bullet.xSpeed = xSpd;
 bullet.ySpeed = ySpd;
 bullet.counterEnd = 255;
 jjSample(x, y, SOUND::AMMO_LASER2);
 return 0;
}

int mislB(float x,float y,int objID,float xSpd,float ySpd,float yAccel)
{
jjOBJ@ normis = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, x, y, objID)];
 normis.behavior = BEHAVIOR::BULLET;
 normis.determineCurAnim(ANIM::AMMO, 50);
 normis.playerHandling = HANDLING::ENEMYBULLET;
 normis.xSpeed = xSpd;
 normis.ySpeed = ySpd;
 normis.yAcc = yAccel;
 normis.counterEnd = 255;
 jjSample(x, y, SOUND::AMMO_MISSILE);
 return 0;
}

int bombB(float x,float y,int objID,float xSpd,float ySpd,float yAcc)
{
 jjOBJ@ bomb = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, x, y, objID)];
 bomb.behavior = BEHAVIOR::BULLET;
 bomb.determineCurAnim(ANIM::AMMO, 1);
 bomb.playerHandling = HANDLING::ENEMYBULLET;
 bomb.ySpeed = ySpd;
 bomb.counterEnd = 255;
 bomb.xSpeed = xSpd;
 bomb.yAcc = yAcc;
 jjSample(x, y, SOUND::COMMON_PLOP1);
 return 0;
}

int screenFlash() {
jjDrawRectangle(0, 0, 128*32, 64*32, jjPalette.findNearestColor(jjPALCOLOR(255,255,255)), SPRITE::NORMAL, 0, 4, 4, -1);
return 0;
}

//initialize some global values
int devanFrame = 1;
int devanAnim = 1;
int bossKillDelay = 240;
void onMain() {
devanFrame += 1;
if (devanAnim == 1){
 if (devanFrame > 40)
 {
  devanFrame = 1;
 }
}
if (devanFrame < 70){
 jjDrawSprite(124*32, 88, ANIM::DEVAN, devanAnim, devanFrame / 10, -1);
}
if (bossKillDelay <= 180){bossKillDelay -= 1;}
if (bossKillDelay == 0){jjNxt(true, false);}
}



const array<SOUND::Sample> ButtstompSounds = {SOUND::COMMON_SPLAT1, SOUND::COMMON_SPLAT2, SOUND::COMMON_SPLAT3, SOUND::COMMON_SPLAT4}; //taken from plus52Scripting, used mostly for collision code
class devanForce : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
 
 switch (obj.state) {
  case STATE::START:
   //don't start boss until player has reached boss activation point
   obj.state = STATE::DELAYEDSTART;
   
  case STATE::DELAYEDSTART:
   //loop players
   for (int i = 0; i < jjLocalPlayerCount; ++i) {
    jjPLAYER@ localPlayer = jjLocalPlayers[i];
    if (localPlayer.bossActivated) {
     localPlayer.boss = obj.objectID;
     obj.state = STATE::START;
    }
   }
   
   if (obj.state == STATE::START) {
    //set object to be handled like a boss
    obj.playerHandling = HANDLING::SPECIAL;
	//start boss
	obj.state = STATE::ATTACK;
	//initialize some important variables
	obj.age = 1500; //boss attack cooldown
	obj.special = 0; //next attack the boss is going to use
	obj.var[0] = 0; //phase
	obj.var[1] = 0; //screen flash
	obj.var[2] = 0; //movement value 1 (varies from phase to phase)
	obj.var[3] = 0; //movement value 2 (varies from phase to phase)
	obj.var[4] = 0; //anim value 1 (varies from phase to phase)
	obj.var[5] = 0; //anim value 2 (varies from phase to phase)
	obj.var[6] = 240; //death sequence
	obj.energy = 50 + (jjDifficulty *2);
    break;
   }
   return;
   
  case STATE::JUMP:
   obj.energy = 5;
   bossKillDelay -= 1;
   if (bossKillDelay == 239){
    for (int i = 0; i < jjLocalPlayerCount; ++i) {
     jjPLAYER@ localPlayer = jjLocalPlayers[i];
     localPlayer.showText("@@@@@@|NO! MY BEAUTIFUL DEVAN FORCE!@NOOOOOOOOOOOOOOOOOOOOOOOOO!!!", STRING::MEDIUM);
	}
	//devanAnim = 7;
	//devanFrame = 1;
   }
   if (bossKillDelay > 180){
    jjDrawSprite(obj.xPos, obj.yPos, ANIM::PINBALL, 2, 0, 0);jjPARTICLE@ particle = jjAddParticle(PARTICLE::FIRE);
   }
   if (bossKillDelay < 0){
    jjNxt(true, false);
   }
	
  case STATE::DEACTIVATE:
   //reset boss
   jjMusicLoad("order.j2b");
   obj.deactivate();
   break;
  case STATE::ATTACK:
   //special drawing layered below main boss
   //phase 1
   if (obj.var[0] == 1){
	//setup early sine
	float eSine1 = sin(obj.var[4]*0.1);
	float eSine2 = sin((obj.var[4]*0.1)+90);
	float eSine3 = sin((obj.var[4]*0.1)+180);
	float eSine4 = sin((obj.var[4]*0.1)+270);
	//render parts
    rPart(obj.xPos+16+(eSine3*4), obj.yPos+(eSine1*2));rPart(obj.xPos+32+(eSine4*4), obj.yPos+(eSine2*2));
	rPart(obj.xPos-(16+(eSine1*4)), obj.yPos+(eSine3*2));rPart(obj.xPos-(32+(eSine1*4)), obj.yPos+(eSine4*2));
	rPart(obj.xPos+20, obj.yPos-(16+(eSine1*4)));rPart(obj.xPos-20, obj.yPos-(16+(eSine4*4)));
	rPart(obj.xPos+(eSine2*4), obj.yPos-(24+(eSine3*4)));
   }
   //phase 2
   if (obj.var[0] == 2){
	//setup early sine
	float eSine1 = sin(obj.var[4]*0.1);
	float eSine2 = sin((obj.var[4]*0.1)+90);
	float eSine3 = sin((obj.var[4]*0.1)+180);
	float eSine4 = sin((obj.var[4]*0.1)+270);
	//render parts
    rPart(obj.xPos+24+(eSine3*4), obj.yPos+(eSine1*2));rPart(obj.xPos+48+(eSine4*4), obj.yPos+(eSine2*2));
	rPart(obj.xPos-(24+(eSine1*4)), obj.yPos+(eSine3*2));rPart(obj.xPos-(48+(eSine1*4)), obj.yPos+(eSine4*2));
	rPart(obj.xPos+32, obj.yPos-(24+(eSine1*4)));rPart(obj.xPos-32, obj.yPos-(24+(eSine4*4)));
	rPart(obj.xPos+(eSine2*4), obj.yPos-(40+(eSine3*4)));rPart(obj.xPos+(eSine4*4), obj.yPos-(24+(eSine1*4)));
	rPart(obj.xPos+20+(eSine3*4), obj.yPos+(eSine1*2)+16);rPart(obj.xPos+40+(eSine4*4), obj.yPos+(eSine2*2)+16);
	rPart(obj.xPos-20+(eSine3*4), obj.yPos+(eSine1*2)+16);rPart(obj.xPos-40+(eSine4*4), obj.yPos+(eSine2*2)+16);
	rPart(obj.xPos+64+(eSine3*4), obj.yPos+(eSine1*2)-28);rPart(obj.xPos-64+(eSine2*4), obj.yPos+(eSine4*2)-28);
	rPart(obj.xPos+64+(eSine3*4), obj.yPos+(eSine1*2)-64);rPart(obj.xPos-64+(eSine2*4), obj.yPos+(eSine4*2)-64);
   }
   //phase 3
   if (obj.var[0] == 3){
	//setup early sine
	float eSine1 = sin(obj.var[4]*0.1);
	float eSine2 = sin((obj.var[4]*0.1)+90);
	float eSine3 = sin((obj.var[4]*0.1)+180);
	float eSine4 = sin((obj.var[4]*0.1)+270);
	//render parts
	rPart(obj.xPos+(eSine3*4)+20, obj.yPos+(12+(eSine1*4)));rPart(obj.xPos+(eSine2*4)-20, obj.yPos+(12+(eSine4*4)));
	rPart(obj.xPos+(eSine2*4), obj.yPos-(16+(eSine3*4)));
	//"fuse"/tail/whatever
	rPart(obj.xPos+(eSine2*4)-4, obj.yPos-(32+(eSine3*4)));
	rPart(obj.xPos+(eSine2*4)-16, obj.yPos-(48+(eSine3*6)));
	rPart(obj.xPos+(eSine2*4)-32, obj.yPos-(56+(eSine3*4)));
	rPart(obj.xPos+(eSine2*6)-64, obj.yPos-(52+(eSine3*4)));
	//body
    rPart(obj.xPos+16+(eSine3*4), obj.yPos+(eSine1*2));rPart(obj.xPos+32+(eSine4*4), obj.yPos+(eSine2*2));
	rPart(obj.xPos+48+(eSine2*4), obj.yPos+(eSine4*2));rPart(obj.xPos+64+(eSine3*4), obj.yPos+(eSine1*2));
	//weapon set 1
	rTurret(obj.xPos+48+(eSine2*4), obj.yPos+(eSine4*2),3);rUpTurret(obj.xPos+64+(eSine3*4), obj.yPos+(eSine1*2),2);
	rPart(obj.xPos-(16+(eSine1*4)), obj.yPos+(eSine3*2));rPart(obj.xPos-(32+(eSine1*4)), obj.yPos+(eSine4*2));
	rPart(obj.xPos-(48+(eSine3*4)), obj.yPos+(eSine2*2));rPart(obj.xPos-(64+(eSine4*4)), obj.yPos+(eSine1*2));
	//weapon set 2
	rTurret(obj.xPos-(48+(eSine3*4)), obj.yPos+(eSine2*2),3);rUpTurret(obj.xPos-(64+(eSine4*4)), obj.yPos+(eSine1*2),4);
   }
   //phase 4
   if (obj.var[0] == 4){
	//setup early sine
	float eSine1 = cos(obj.var[4]*0.1);
	float eSine2 = sin((obj.var[4]*0.1));
	float eSine3 = cos((obj.var[4]*0.1)+125);
	float eSine4 = sin((obj.var[4]*0.1)+135);
	//render parts
    rPart(obj.xPos+(eSine1*32), obj.yPos+(eSine2*32));rPart(obj.xPos+(eSine3*32), obj.yPos+(eSine4*32));
   }
   
   //phase 5
   if (obj.var[0] == 5){
	//setup early sine
	float eSine1 = sin(obj.var[4]*0.03);
	float eSine2 = sin((obj.var[4]*0.03)+90);
	float eSine3 = sin((obj.var[4]*0.03)+180);
	float eSine4 = sin((obj.var[4]*0.1));
	float eSine5 = sin((obj.var[4]*0.1)+180);
	//render parts
	//body
	rPart(obj.xPos-24, obj.yPos+16);rPart(obj.xPos+24, obj.yPos+16);
	rPart(obj.xPos-48, obj.yPos+32);rPart(obj.xPos-28, obj.yPos+32);rPart(obj.xPos+48, obj.yPos+32);rPart(obj.xPos+28, obj.yPos+32);
	rPart(obj.xPos-64, obj.yPos+48);rPart(obj.xPos-32, obj.yPos+48);rPart(obj.xPos-16, obj.yPos+48);rPart(obj.xPos+64, obj.yPos+48);rPart(obj.xPos+32, obj.yPos+48);rPart(obj.xPos+16, obj.yPos+48);
	rPart(obj.xPos-48, obj.yPos+64);rPart(obj.xPos-28, obj.yPos+64);rPart(obj.xPos+48, obj.yPos+64);rPart(obj.xPos+28, obj.yPos+64);
	//left leg
	rPart(obj.xPos-48,obj.yPos+96+(eSine4*6));//rPart(obj.xPos-96,obj.yPos+96)
	rPart(obj.xPos-48,obj.yPos+128+(eSine4*12));//rPart(obj.xPos-96,obj.yPos+128)
	//left foot
	rPart(obj.xPos-40,obj.yPos+144+(eSine4*18));
	rPart(obj.xPos-56,obj.yPos+144+(eSine4*18));
	//right leg
	rPart(obj.xPos+48,obj.yPos+96+(eSine5*6));//rPart(obj.xPos+96,obj.yPos+96);
	rPart(obj.xPos+48,obj.yPos+128+(eSine5*12));//rPart(obj.xPos+96,obj.yPos+128);
	//right foot
	rPart(obj.xPos+56,obj.yPos+144+(eSine5*18));
	rPart(obj.xPos+40,obj.yPos+144+(eSine5*18));
	//left neck
	rPart(obj.xPos-(48+(eSine1*3)), obj.yPos-(48+(eSine1*3)));rPart(obj.xPos-(32+(eSine1*2)), obj.yPos-(32+(eSine1*2)));rPart(obj.xPos-(16+(eSine1*1)), obj.yPos-(16+(eSine1*1)));
	//middle neck
	rPart(obj.xPos, obj.yPos-(54+(eSine2*3)));rPart(obj.xPos, obj.yPos-(36+(eSine2*2)));rPart(obj.xPos, obj.yPos-(18+(eSine2*1)));
	//right neck
	rPart(obj.xPos+(48+(eSine1*3)), obj.yPos-(48+(eSine1*3)));rPart(obj.xPos+(32+(eSine1*2)), obj.yPos-(32+(eSine1*2)));rPart(obj.xPos+(16+(eSine1*1)), obj.yPos-(16+(eSine1*1)));
	//heads
	rPart(obj.xPos-(64+(eSine1*4)), obj.yPos-(48+(eSine1*4)));rPart(obj.xPos-(64+(eSine1*4)), obj.yPos-(64+(eSine1*4)));
	rTurret(obj.xPos-(64+(eSine1*4)), obj.yPos-(72+(eSine1*4)),3);
	rPart(obj.xPos, obj.yPos-(56+(eSine2*4)));rPart(obj.xPos, obj.yPos-(72+(eSine2*4)));
	rTurret(obj.xPos, obj.yPos-(80+(eSine2*4)),3);
	rPart(obj.xPos+(64+(eSine3*4)), obj.yPos-(48+(eSine3*4)));rPart(obj.xPos+(64+(eSine3*4)), obj.yPos-(64+(eSine3*4)));
	rTurret(obj.xPos+(64+(eSine3*4)), obj.yPos-(72+(eSine3*4)),3);
   }
   //phase 6
   if (obj.var[0] == 6){
	//setup early sine
	float eSine1 = cos(obj.var[4]*0.1);
	float eSine2 = sin((obj.var[4]*0.1));
	float eSine3 = cos((obj.var[4]*0.2));
	float eSine4 = sin((obj.var[4]*0.2));
	rPart(obj.xPos, obj.yPos-32);rPart(obj.xPos, obj.yPos-64);
	rPart(obj.xPos+28, obj.yPos-6);rPart(obj.xPos+56, obj.yPos-12);
	rPart(obj.xPos-28, obj.yPos-6);rPart(obj.xPos-56, obj.yPos-12);
	rPart(obj.xPos+12, obj.yPos+18);rPart(obj.xPos+24, obj.yPos+36);
	rPart(obj.xPos-12, obj.yPos+18);rPart(obj.xPos-24, obj.yPos+36);
   }
   
   //draw boss
   if (bossKillDelay > 180){jjDrawSprite(obj.xPos, obj.yPos, ANIM::PINBALL, 2, 0, 0);}
   //set Devan Force as boss
   for (int i = 0; i < jjLocalPlayerCount; ++i) {
    jjPLAYER@ localPlayer = jjLocalPlayers[i];
    if (localPlayer.bossActivated) {
     localPlayer.boss = obj.objectID;
    }
   }
   
   //constantly cool down pattern
   obj.age -= 1;
   //screen flash
   if (obj.var[1] > 0){screenFlash();obj.var[1] = obj.var[1] - 1;}
   
   //intro
   if (obj.var[0] == 0){
    //prevent boss from taking damage
    obj.energy = 95;
    //text
	for (int i = 0; i < jjLocalPlayerCount; ++i) {
     jjPLAYER@ localPlayer = jjLocalPlayers[i];
	 //if (obj.age == 1499){localPlayer.showText("@@@@|Devan: So you've arrived...", STRING::MEDIUM);}if (obj.age == 1050){localPlayer.showText("@@@@|My super-weapon is finally complete.", STRING::MEDIUM);}if (obj.age == 600){localPlayer.showText("@@@@|Prepare yourself for...@Devan Force!", STRING::MEDIUM);}if (obj.age == 150){jjMusicStop();localPlayer.showText("@@@@@@|BLASTER FORCE!", STRING::LARGE);}
	 if (obj.age == 1499){obj.age = 1050;}
	 if (obj.age == 1050){localPlayer.showText("@@@@|Devan: So you've arrived...", STRING::MEDIUM);}
	 //if (obj.age == 600){localPlayer.showText("@@@@|I've come prepared this time.", STRING::MEDIUM);}
	 if (obj.age == 600){localPlayer.showText("@@@@|I've been waiting. My latest machine cannot fail!", STRING::MEDIUM);}
     if (obj.age == 150){jjMusicStop();localPlayer.showText("@@@@@@|BLASTER FORCE!", STRING::LARGE);}
	 }
	
    //screen flash
    if (obj.age < 10 && obj.age >0){screenFlash();}
	
	//start phase 1
	if (obj.age <= 0){
	 //load song
	 jjMusicLoad("RMFinalBoss.it");
	 //set values for phase 1
	 obj.age = 150; obj.var[0] = 1;
	 obj.energy = 50+(jjDifficulty*2);
	 obj.var[2] = 4;
	 jjSample(obj.xPos, obj.yPos, SOUND::BILSBOSS_BILLAPPEAR);
	}
   }
   
   //phase 1
   if (obj.var[0] == 1){
	 //launch bullet
	 if (obj.age % (ceil(16/(jjDifficulty+1))) == 0 && obj.age < 90 && obj.special == 0){
	  blasterB(obj.xPos-128,obj.yPos,obj.objectID,5*(jjDifficulty+1));
	  blasterB(obj.xPos-128,obj.yPos,obj.objectID,-5*(jjDifficulty+1));
     }
	 
	 //launch bullet
	 if (obj.age % (ceil(16/(jjDifficulty+1))) == 0 && obj.age < 90 && obj.special == 1){
	  blasterB(obj.xPos+128,obj.yPos,obj.objectID,5*(jjDifficulty+1));
	  blasterB(obj.xPos+128,obj.yPos,obj.objectID,-5*(jjDifficulty+1));
     }
	 
	 //prepare drawing
	 obj.var[4] = obj.var[4] + 1;
	 float sineOne = sin(obj.var[4]*0.1);
	 float sineTwo = sin((obj.var[4]*0.1)+90);
	 
	 //draw boss
	 if (obj.special == 0 && obj.age > 90){
	  rPart(obj.xPos+(96*((obj.age-105)/30.0) + (sineOne*4)), obj.yPos + (sineOne*4));
	  rPart(obj.xPos+(192*((obj.age-105)/30.0)), obj.yPos + (sineTwo*4));
	  rTurret(obj.xPos+(256*((obj.age-105)/30.0)), obj.yPos + (sineTwo*4), 3);
	  rUpTurret(obj.xPos+(224*((obj.age-105)/30.0)), obj.yPos + (sineTwo*4)-32, 3);
	 }
	 
	 //draw boss
	 if (obj.special == 0 && obj.age <= 90){
	  rPart(obj.xPos-48, obj.yPos + (sineOne*4));
	  rPart(obj.xPos-96, obj.yPos + (sineTwo*4));
	  rTurret(obj.xPos-128, obj.yPos + (sineTwo*4), 3);
	  rUpTurret(obj.xPos-112, obj.yPos + (sineTwo*4)-32, 3);
	 }
	 
	 //draw boss
	 if (obj.special == 1 && obj.age > 90){
	  rPart(obj.xPos-(96*((obj.age-105)/30.0)), obj.yPos + (sineOne*4));
	  rPart(obj.xPos-(192*((obj.age-105)/30.0)), obj.yPos + (sineTwo*4));
	  rTurret(obj.xPos-(256*((obj.age-105)/30.0)), obj.yPos + (sineTwo*4), 3);
	  rUpTurret(obj.xPos-(224*((obj.age-105)/30.0)), obj.yPos + (sineTwo*4)-32, 3);
	 }
	 
	 //draw boss
	 if (obj.special == 1 && obj.age <=90){
	  rPart(obj.xPos+48, obj.yPos + (sineOne*4));
	  rPart(obj.xPos+96, obj.yPos + (sineTwo*4));
	  rTurret(obj.xPos+128, obj.yPos + (sineTwo*4), 3);
	  rUpTurret(obj.xPos+112, obj.yPos + (sineTwo*4)-32, 3);
	 }
	 
	 //reset cooldown
	 
	 if (obj.age <= 0){
	  obj.special = 1-obj.special;
	  obj.age = 120;
	 }
	  
	 
	 //movement
	 obj.xPos += obj.var[2];
	 if (obj.xPos > 126*32 && obj.var[2] > -4){obj.var[2] = obj.var[2] - 1;}
	 if (obj.xPos < 106*32 && obj.var[2] < 4){obj.var[2] = obj.var[2] + 1;}
   }
   
   //phase 2
   if (obj.var[0] == 2){
	
	 //launch normal missiles
	 if (obj.age % (ceil(24/(jjDifficulty+1))) == 0 && obj.age < 70+(5*jjDifficulty) && obj.special == 0){
      mislB(obj.xPos-64,obj.yPos-64,obj.objectID,int (jjRandom() % 15) - 7,-6,0.1+((jjDifficulty+1)*0.025));//mislB(obj.xPos-64,obj.yPos-64,obj.objectID,int (jjRandom() % 15) - 7,-6,0.1*(jjDifficulty+1));
	  mislB(obj.xPos+64,obj.yPos-64,obj.objectID,int (jjRandom() % 15) - 7,-6,0.1+((jjDifficulty+1)*0.025));
     }
	 
	 //launch homing missiles
	 if (obj.age == 0 && obj.special == 1){
	  jjOBJ@ misl = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos-64, obj.yPos-64, obj.objectID)];
	  jjOBJ@ misl2 = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos+64, obj.yPos-64, obj.objectID)];
	  misl.behavior = BEHAVIOR::BILSYBULLET;
	  misl2.behavior = BEHAVIOR::BILSYBULLET;
	  misl.determineCurAnim(ANIM::AMMO, 42);
	  misl2.determineCurAnim(ANIM::AMMO, 42);
	  misl.playerHandling = HANDLING::ENEMYBULLET;
	  misl2.playerHandling = HANDLING::ENEMYBULLET;
	  misl.xSpeed = (jjRandom() % 5) - 3;
	  misl2.xSpeed = (jjRandom() % 5) - 3;
      misl.ySpeed = -6;
	  misl2.ySpeed = -6;
	  misl.yAcc = 0.1*(jjDifficulty+1);
	  misl2.yAcc = 0.1*(jjDifficulty+1);
	  misl.counterEnd = 255;
	  misl2.counterEnd = 255;
	  jjSample(obj.xPos, obj.yPos, SOUND::AMMO_MISSILE);
     }
	 
	 	 //launch lots of slow normal missiles
	 if (obj.age % (ceil(16/(jjDifficulty+1))) == 0 && obj.age < 45+(15*jjDifficulty) && obj.special == 3){
      //mislB(obj.xPos-56,obj.yPos-64,obj.objectID,int (jjRandom() % 3) - 2,-4,0.025*(jjDifficulty+1));
	  //mislB(obj.xPos-72,obj.yPos-64,obj.objectID,int (jjRandom() % 3) - 2,-4,0.025*(jjDifficulty+1));
	  //mislB(obj.xPos+56,obj.yPos-64,obj.objectID,int (jjRandom() % 3) - 2,-4,0.025*(jjDifficulty+1));
	  //mislB(obj.xPos+72,obj.yPos-64,obj.objectID,int (jjRandom() % 3) - 2,-4,0.025*(jjDifficulty+1));
      mislB(obj.xPos-56,obj.yPos-64,obj.objectID,(int (jjRandom() % 5) - 3)*0.1,-4,0.025*(jjDifficulty+1));
	  mislB(obj.xPos-72,obj.yPos-64,obj.objectID,(int (jjRandom() % 5) - 3)*0.1,-4,0.025*(jjDifficulty+1));
	  mislB(obj.xPos+56,obj.yPos-64,obj.objectID,(int (jjRandom() % 5) - 3)*0.1,-4,0.025*(jjDifficulty+1));
	  mislB(obj.xPos+72,obj.yPos-64,obj.objectID,(int (jjRandom() % 5) - 3)*0.1,-4,0.025*(jjDifficulty+1));
	  //jjOBJ@ bullet = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos-56, obj.yPos-64, obj.objectID)];jjOBJ@ bullet2 = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos-72, obj.yPos-64, obj.objectID)];jjOBJ@ bullet3 = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos+56, obj.yPos-64, obj.objectID)];jjOBJ@ bullet4 = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos+72, obj.yPos-64, obj.objectID)];bullet.behavior = BEHAVIOR::BULLET;bullet2.behavior = BEHAVIOR::BULLET;bullet3.behavior = BEHAVIOR::BULLET;bullet4.behavior = BEHAVIOR::BULLET;bullet.determineCurAnim(ANIM::AMMO, 50);bullet2.determineCurAnim(ANIM::AMMO, 50);bullet3.determineCurAnim(ANIM::AMMO, 50);bullet4.determineCurAnim(ANIM::AMMO, 50);bullet.playerHandling = HANDLING::ENEMYBULLET;bullet2.playerHandling = HANDLING::ENEMYBULLET;bullet3.playerHandling = HANDLING::ENEMYBULLET;bullet4.playerHandling = HANDLING::ENEMYBULLET;bullet.xSpeed = (jjRandom() % 3) - 2;bullet2.xSpeed = (jjRandom() % 3) - 2;bullet3.xSpeed = (jjRandom() % 3) - 2;bullet4.xSpeed = (jjRandom() % 3) - 2;bullet.ySpeed = -4;bullet2.ySpeed = -4;bullet3.ySpeed = -4;bullet4.ySpeed = -4;bullet.yAcc = 0.025*(jjDifficulty+1);bullet2.yAcc = 0.025*(jjDifficulty+1);bullet3.yAcc = 0.025*(jjDifficulty+1);bullet4.yAcc = 0.025*(jjDifficulty+1);bullet.counterEnd = 255;bullet2.counterEnd = 255;bullet3.counterEnd = 255;bullet4.counterEnd = 255;jjSample(obj.xPos-128, obj.yPos, SOUND::AMMO_MISSILE);
     }
	 
	 //prepare drawing
	 obj.var[4] = obj.var[4] + 1;
     float sine1 = sin(obj.var[4]*0.1);
	 float sine2 = sin((obj.var[4]*0.1)+90);
	 float sine3 = sin((obj.var[4]*0.1)+180);
	 float sine4 = sin((obj.var[4]*0.1)+270);
	 
	 //draw boss
	 //rTurret(obj.xPos+64, (obj.yPos -64 ) + (sineTwo * 4), 3);
	 //rTurret(obj.xPos+64, (obj.yPos -64 ) + (sineTwo * 4), 3);
	 rTurret(obj.xPos+64+(sine3*4), obj.yPos + (sine1*2)-64, 3);
	 rUpTurret(obj.xPos+64+(sine3*4), obj.yPos + (sine1*2)-64, 3);
	 rTurret(obj.xPos-64+(sine2*4), obj.yPos + (sine4*2)-64, 3);
	 rUpTurret(obj.xPos-64+(sine2*4), obj.yPos + (sine4*2)-64, 3);
	 
	 //reset cooldown
	 
	 if (obj.age <= 0){
	  obj.special = obj.special + 1;
	  if (obj.special > 4){obj.special = 0;}
	  obj.age = 120;
	 }
	 if (obj.special == 2){obj.age -= 1;}
	 
	 //movement
	 obj.xPos += obj.var[2];
	 for (int i = 0; i < jjLocalPlayerCount; ++i) {
	  jjPLAYER@ localPlayer = jjLocalPlayers[i];
	  if (obj.xPos > localPlayer.xPos +64 && obj.var[2] > -4 && obj.xPos <= 128*32) {obj.var[2] = obj.var[2] - 1;}//turn around because of player
	  if (obj.xPos < localPlayer.xPos-64 && obj.var[2] < 4 && obj.xPos >= 104*32) {obj.var[2] = obj.var[2] + 1;} //turn around because of player
	  if (obj.xPos > 128*32 && obj.var[2] > -4){obj.var[2] = obj.var[2] - 1;}//turn around because of wall
	  if (obj.xPos < 104*32 && obj.var[2] < 4){obj.var[2] = obj.var[2] + 1;}//turn around because of wall
	 }
   }
   //phase 3
   if (obj.var[0] == 3){
	 //launch bomb
	 if (obj.age <= 0 && obj.special == 0){
	  bombB(obj.xPos - 48, obj.yPos, obj.objectID, 0, 0, 0.025 * (jjDifficulty+1));
	  //jjOBJ@ bomb = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos-48, obj.yPos, obj.objectID)];bomb.behavior = BEHAVIOR::BULLET;bomb.determineCurAnim(ANIM::AMMO, 1);bomb.playerHandling = HANDLING::ENEMYBULLET;bomb.ySpeed = 0;bomb.counterEnd = 100;bomb.yAcc = 0.1*(jjDifficulty+1);jjSample(obj.xPos-128, obj.yPos, SOUND::COMMON_PLOP1);
     }
	 if (obj.age <= 0 && obj.special == 1){
      bombB(obj.xPos + 48, obj.yPos, obj.objectID, 0, 0, 0.025 * (jjDifficulty+1));
	  //jjOBJ@ bomb = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos+48, obj.yPos, obj.objectID)];bomb.behavior = BEHAVIOR::BULLET;bomb.determineCurAnim(ANIM::AMMO, 1);bomb.playerHandling = HANDLING::ENEMYBULLET;bomb.ySpeed = 0;bomb.counterEnd = 100;bomb.yAcc = 0.1*(jjDifficulty+1);jjSample(obj.xPos-128, obj.yPos, SOUND::COMMON_PLOP1);
     }
	 if (obj.age <= 0 && obj.special == 2){
      bombB(obj.xPos-48, obj.yPos, obj.objectID, 2 * (jjDifficulty+1), -2.5, 0.025 * (jjDifficulty+1));
	  //jjOBJ@ bomb = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos-48, obj.yPos, obj.objectID)];bomb.behavior = BEHAVIOR::BULLET;bomb.determineCurAnim(ANIM::AMMO, 1);bomb.playerHandling = HANDLING::ENEMYBULLET;bomb.ySpeed = -5;bomb.counterEnd = 100;bomb.xSpeed = 2*(jjDifficulty+1);bomb.yAcc = 0.1*(jjDifficulty+1);jjSample(obj.xPos-128, obj.yPos, SOUND::COMMON_PLOP1);
     }
	 if (obj.age <= 0 && obj.special == 3){
      bombB(obj.xPos + 48, obj.yPos, obj.objectID, -2 * (jjDifficulty+1), -2.5, 0.05 * (jjDifficulty+1));
	  //jjOBJ@ bomb = jjObjects[jjAddObject(OBJECT::BLASTERBULLET, obj.xPos+48, obj.yPos, obj.objectID)];bomb.behavior = BEHAVIOR::BULLET;bomb.determineCurAnim(ANIM::AMMO, 1);bomb.playerHandling = HANDLING::ENEMYBULLET;bomb.ySpeed = -5;bomb.counterEnd = 100;bomb.xSpeed = -2*(jjDifficulty+1);bomb.yAcc = 0.1*(jjDifficulty+1);jjSample(obj.xPos-128, obj.yPos, SOUND::COMMON_PLOP1);
     }
	 
	 //reset cooldown
	 
	 if (obj.age <= 0){
	  obj.special = jjRandom() % 4;
	  obj.age = 60/(jjDifficulty+1);
	 }
	  
	 
	 //movement
	 obj.xPos += obj.var[2];
	 if (obj.var[3] == 0){obj.var[2] = 6; obj.var[3] = 1;}
	 if (obj.xPos > 125*32 && obj.var[2] > -7){obj.var[2] = obj.var[2] - 1;}
	 if (obj.xPos < 107*32 && obj.var[2] < 7){obj.var[2] = obj.var[2] + 1;}
	 
	 //animate
	 obj.var[4] = obj.var[4] + 1;
   }
   
   //phase 4
   if (obj.var[0] == 4){
	 if (obj.age % 5 == 0 && obj.age < 60 && obj.special == 0){
	  laserB(obj.xPos,obj.yPos-32,obj.objectID,0,0.5*(jjDifficulty+1));
     }
	 if (obj.age % 10 == 0 && obj.age < 60 && obj.special == 1){
	  laserB(obj.xPos,obj.yPos-32,obj.objectID,(-1+(int(jjRandom()) % 3)),0.5*(jjDifficulty+1));
     }
	 
	 //reset cooldown
	 
	 if (obj.age <= 0){
	  obj.special = 1 - obj.special;
	  obj.age = 120;
	 }
	  
	 
	 //movement
	 obj.xPos += obj.var[2];
	 if (obj.var[3] == 0){obj.var[2] = 6; obj.var[3] = 1;}
	 for (int i = 0; i < jjLocalPlayerCount; ++i) {
	  jjPLAYER@ localPlayer = jjLocalPlayers[i];
	  if (obj.xPos > localPlayer.xPos +96 && obj.var[2] > -7 && obj.xPos <= 128*32) {obj.var[2] = obj.var[2] - 1;}//turn around because of player
	  if (obj.xPos < localPlayer.xPos-96 && obj.var[2] < 7 && obj.xPos >= 104*32) {obj.var[2] = obj.var[2] + 1;} //turn around because of player
	  if (obj.xPos > 128*32 && obj.var[2] > -7){obj.var[2] = obj.var[2] - 1;}//turn around because of wall
	  if (obj.xPos < 104*32 && obj.var[2] < 7){obj.var[2] = obj.var[2] + 1;}//turn around because of wall
	 }
	 
	 
	 //animate
	 obj.var[4] = obj.var[4] + 1;
   }
   
   //phase 5
   if (obj.var[0] == 5){
	 //launch missiles
	 if (obj.age <= 0 && obj.special == 0){
	  mislB(obj.xPos-64,obj.yPos-64,obj.objectID,-5,jjDifficulty,0.1*(jjDifficulty+1));
	  mislB(obj.xPos-64,obj.yPos-64,obj.objectID,-3,jjDifficulty,0.1*(jjDifficulty+1));
	  mislB(obj.xPos,obj.yPos-72,obj.objectID,1,jjDifficulty,0.1*(jjDifficulty+1));
	  mislB(obj.xPos,obj.yPos-72,obj.objectID,-1,jjDifficulty,0.1*(jjDifficulty+1));
	  mislB(obj.xPos+64,obj.yPos-64,obj.objectID,3,jjDifficulty,0.1*(jjDifficulty+1));
	  mislB(obj.xPos+64,obj.yPos-64,obj.objectID,5,jjDifficulty,0.1*(jjDifficulty+1));
     }
	 //launch lasers
	 if (obj.age % 5 == 0 && obj.age <= 20 && obj.special == 1){
      laserB(obj.xPos,obj.yPos-64,obj.objectID,0,6*(jjDifficulty+1));
	  laserB(obj.xPos-64,obj.yPos-72,obj.objectID,0,6*(jjDifficulty+1));
	  laserB(obj.xPos+64,obj.yPos-64,obj.objectID,0,6*(jjDifficulty+1));
     }
	 //launch bombs
	 if (obj.age <= 0 && obj.special == 2){
      bombB(obj.xPos-64, obj.yPos-64, obj.objectID, 2 * (jjDifficulty+1), 0, 0.025 * (jjDifficulty+1));
	  bombB(obj.xPos-64, obj.yPos-64, obj.objectID, -2 * (jjDifficulty+1), 0, 0.025 * (jjDifficulty+1));
	  bombB(obj.xPos, obj.yPos-72, obj.objectID, 2 * (jjDifficulty+1), 0, 0.025 * (jjDifficulty+1));
	  bombB(obj.xPos, obj.yPos-72, obj.objectID, -2 * (jjDifficulty+1), 0, 0.025 * (jjDifficulty+1));
	  bombB(obj.xPos+64, obj.yPos-64, obj.objectID, 2 * (jjDifficulty+1), 0, 0.025 * (jjDifficulty+1));
	  bombB(obj.xPos+64, obj.yPos-64, obj.objectID, -2 * (jjDifficulty+1), 0, 0.025 * (jjDifficulty+1));
     }
	 
	 //reset cooldown
	 
	 if (obj.age <= 0){
	  obj.special += 1;
	  if (obj.special > 3){obj.special = 0;}
	  obj.age = 60-(jjDifficulty*5);
	 }
	  
	 
	 //movement
	 obj.xPos += obj.var[2];
	 if (obj.var[3] == 0){obj.var[2] = 2; obj.var[3] = 1;}
	 if (obj.xPos > 125*32 && obj.var[2] > -2){obj.var[2] = obj.var[2] - 1;}
	 if (obj.xPos < 107*32 && obj.var[2] < 2){obj.var[2] = obj.var[2] + 1;}
	 
	 //animate
	 obj.var[4] = obj.var[4] + 1;
   }

   //phase 6
   if (obj.var[0] == 6){
     int alreadyShot = 0;
	 if (obj.var[3] == 0){obj.var[2] = 3; obj.var[3] = 1;obj.age = 240;}
	 //launch lasers
	 if (obj.age % 2 == 0 && obj.age <= 120 && obj.special == 0 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,1.5*(jjDifficulty),1.5*(jjDifficulty+1));
	  obj.special = jjRandom() % 8;
	  alreadyShot = 1;
     }
	 if (obj.age % 2 == 0 && obj.age <= 120 && obj.special == 1 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,-1.5*(jjDifficulty),1.5*(jjDifficulty+1));
	  obj.special = jjRandom() % 8;
	  alreadyShot = 1;
     }
	 if (obj.age % 2 == 0 && obj.age <= 120 && obj.special == 2 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,1.5*(jjDifficulty),-1.5*(jjDifficulty+1));
	  obj.special = jjRandom() % 8;
	  alreadyShot = 1;
     }
	 if (obj.age % 2 == 0 && obj.age <= 120 && obj.special == 3 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,-1.5*(jjDifficulty),-1.5*(jjDifficulty+1));
	  obj.special = jjRandom() % 8;
	  alreadyShot = 1;
     }
	 if (obj.age % 2 == 0 && obj.age <= 120 && obj.special == 4 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,0,2*(jjDifficulty));
	  obj.special = jjRandom() % 8;
	  alreadyShot = 1;
     }
	 if (obj.age % 2 == 0 && obj.age <= 120 && obj.special == 5 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,0,-2*(jjDifficulty));
	  obj.special = jjRandom() % 8;
	  alreadyShot = 1;
     }
	 if (obj.age % 2 == 0 && obj.age <= 120 && obj.special == 6 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,2*(jjDifficulty),0);
	  obj.special = jjRandom() % 8;
	  alreadyShot = 1;
     }
	 if (obj.age % 2 == 0 && obj.age <= 120 && obj.special == 7 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,-2*(jjDifficulty),0);
	  obj.special = jjRandom() % 8;
	  alreadyShot = 1;
     }
	 //fire extra laser
	 if (obj.age % 20 == 0 && obj.age <= 120 && obj.special >= 10 && alreadyShot == 0){
      asterB(obj.xPos,obj.yPos-64,obj.objectID,0,5*(jjDifficulty));
	  obj.special = 11;
	  alreadyShot = 1;
     }
	 //reset cooldown
	 if (obj.age <= 0){
      if (obj.special < 10){obj.special = 10;}
	  if (obj.special == 11){obj.special = 0;}
	  obj.age = 180;
	 }
	  
	 
	 //movement
	 obj.xPos += obj.var[2];
	 if (obj.xPos > 127*32 && obj.var[2] > -3){obj.var[2] = obj.var[2] - 1;}
	 if (obj.xPos < 103*32 && obj.var[2] < 3){obj.var[2] = obj.var[2] + 1;}
	 
	 //animate
	 obj.var[4] = obj.var[4] + 1;
   }
   
   //phase 7
   if (obj.var[0] == 7){
	 //launch bomb
	 if (obj.age <= 0 && obj.special == 0){
	  bombB(obj.xPos, obj.yPos, obj.objectID, 0, 0, 0.05 * (jjDifficulty));
     }
	 //launch missile
	 if (obj.age <= 0 && obj.special == 1){
      mislB(obj.xPos,obj.yPos,obj.objectID,0,-6,0.2*(jjDifficulty));
     }
	 //launch blaster
	 if (obj.age <= 0 && obj.special == 2){
      blasterB(obj.xPos,obj.yPos,obj.objectID,1*(jjDifficulty));
     }
	 //launch laser
	 if (obj.age <= 0 && obj.special == 3){
      laserB(obj.xPos,obj.yPos,obj.objectID,1.5*(jjDifficulty),1.5*(jjDifficulty+1));
	  laserB(obj.xPos,obj.yPos,obj.objectID,-1.5*(jjDifficulty),1.5*(jjDifficulty+1));
     }
	 
	 //reset cooldown
	 
	 if (obj.age <= 0){
	  obj.special = jjRandom() % 4;
	  obj.age = 45/(jjDifficulty);
	 }
	  
	 
	 //movement
	 obj.xPos += obj.var[2];
	 if (obj.var[3] == 0){obj.var[2] = 8; obj.var[3] = 1;}
	 obj.yPos = (11*32)+(sin(obj.var[4]*0.1)*64);
	 if (obj.xPos > 127*32 && obj.var[2] > -8){obj.var[2] = obj.var[2] - 1;}
	 if (obj.xPos < 104*32 && obj.var[2] < 8){obj.var[2] = obj.var[2] + 1;}
	 
	 //animate
	 obj.var[4] = obj.var[4] + 1;
   }
   //end of phases
   
   //next phase
   if (obj.energy <= 0){
	if (obj.var[0] == 1)
	{
	 obj.xPos = 115*32;obj.yPos = 12*32;
	 for (int i = 0; i < jjLocalPlayerCount; ++i) {
	  jjPLAYER@ localPlayer = jjLocalPlayers[i];
	  localPlayer.showText("@@@@@@|SILO FORCE!", STRING::LARGE);
	 }
    }
	if (obj.var[0] == 2)
	{
	 obj.xPos = 115*32;obj.yPos = 12*32;
	 for (int i = 0; i < jjLocalPlayerCount; ++i) {
	  jjPLAYER@ localPlayer = jjLocalPlayers[i];
	  localPlayer.showText("@@@@@@|BOMB FORCE!", STRING::LARGE);
	 }
    }
	if (obj.var[0] == 3)
	{
	 obj.xPos = 115*32;obj.yPos = 12*32;
	 for (int i = 0; i < jjLocalPlayerCount; ++i) {
	  jjPLAYER@ localPlayer = jjLocalPlayers[i];
	  localPlayer.showText("@@@@@@|DYNAMO FORCE!", STRING::LARGE);
	 }
    }
	if (obj.var[0] == 4)
	{
	 obj.xPos = 115*32;obj.yPos = 12*32;
	 for (int i = 0; i < jjLocalPlayerCount; ++i) {
	  jjPLAYER@ localPlayer = jjLocalPlayers[i];
	  localPlayer.showText("@@@@@@|HYDRA FORCE!", STRING::LARGE);
	 }
    }
	if (obj.var[0] == 5)
	{
	 obj.xPos = 115*32;obj.yPos = 12*32;
	 for (int i = 0; i < jjLocalPlayerCount; ++i) {
	  jjPLAYER@ localPlayer = jjLocalPlayers[i];
	  //localPlayer.showText("@@@@@@|WIND FORCE!", STRING::LARGE);
	  localPlayer.showText("@@@@@@|ASTER FORCE!", STRING::LARGE);
	 }
    }
	if (obj.var[0] == 6)
	{
	 obj.xPos = 115*32;obj.yPos = 12*32;
	 for (int i = 0; i < jjLocalPlayerCount; ++i) {
	  jjPLAYER@ localPlayer = jjLocalPlayers[i];
	  //localPlayer.showText("@@@@@@|JAVEILIN FORCE!", STRING::LARGE);
	  localPlayer.showText("@@@@@@|CORE FORCE!", STRING::LARGE);
	 }
    }
    
	int maxForms = 3 +( jjDifficulty * 2);
	if (maxForms > 7){maxForms = 7;}
	if (obj.var[0] < maxForms){
     if (jjDifficulty < 3){jjObjects[jjAddObject(OBJECT::CARROT, 115*32, 17*32)];}
	 obj.energy = 50+(jjDifficulty*2);
     obj.age = 120; //cooldown reset
	 obj.var[1] = 10; //flash screen
	 obj.var[2] = 0; //reset move value 1
	 obj.var[3] = 0; //reset move value 2
	 obj.var[4] = 0; //reset anim value 1
	 obj.var[5] = 0; //reset anim value 2
	 obj.special = 0;
	 jjSample(obj.xPos, obj.yPos, SOUND::BILSBOSS_BILLAPPEAR); //play sound
	 obj.var[0] = obj.var[0]+1; //next phase
    }
   }
	
	//kill boss
	if (obj.energy <= 0){obj.var[0] = 1337;}
	if (obj.var[0] == 1337){
     bossKillDelay -= 1;
     if (bossKillDelay == 239){
      for (int i = 0; i < jjLocalPlayerCount; ++i) {
       jjPLAYER@ localPlayer = jjLocalPlayers[i];
       localPlayer.showText("@@@@@@|NO! MY BEAUTIFUL DEVAN FORCE!@NOOOOOOOOOOOOOOOOOOOOOOOOO!!!", STRING::MEDIUM);
       devanAnim = 6;
       devanFrame = 1;
	  }
     }
	 //debris
     if (bossKillDelay > 180){
	  jjOBJ@ debris1 = jjObjects[jjAddObject(OBJECT::SHARD, (obj.xPos - 32) + (jjRandom() % 64), (obj.yPos- 32) + (jjRandom() % 64))];
	  jjOBJ@ debris2 = jjObjects[jjAddObject(OBJECT::SHARD, (obj.xPos - 32) + (jjRandom() % 64), (obj.yPos- 32) + (jjRandom() % 64))];
	  jjOBJ@ debris3 = jjObjects[jjAddObject(OBJECT::SHARD, (obj.xPos - 32) + (jjRandom() % 64), (obj.yPos- 32) + (jjRandom() % 64))];
	  debris1.determineCurAnim(ANIM::AMMO, 79);
	  debris2.determineCurAnim(ANIM::AMMO, 79);
	  debris3.determineCurAnim(ANIM::AMMO, 79);
	  //jjPARTICLE@ particle = jjAddParticle(PARTICLE::FIRE);if (particle != null) {particle.xPos = obj.xPos;particle.yPos = obj.yPos;particle.xSpeed = 0.5*(((jjRandom() % 2)*2)-1);particle.ySpeed = 3;}
     }
	 //explosions
     if (bossKillDelay > 180 && bossKillDelay % 3 == 0){
	  jjOBJ@ explosion1 = jjObjects[jjAddObject(OBJECT::EXPLOSION, (obj.xPos - 32) + (jjRandom() % 64), (obj.yPos- 32) + (jjRandom() % 64))];
	  explosion1.determineCurAnim(ANIM::AMMO, 80+(jjRandom() % 3));
	  jjOBJ@ explosion2 = jjObjects[jjAddObject(OBJECT::EXPLOSION, (obj.xPos - 32) + (jjRandom() % 64), (obj.yPos- 32) + (jjRandom() % 64))];
	  explosion2.determineCurAnim(ANIM::AMMO, 80+(jjRandom() % 3));
	  jjOBJ@ explosion3 = jjObjects[jjAddObject(OBJECT::EXPLOSION, (obj.xPos - 32) + (jjRandom() % 64), (obj.yPos- 32) + (jjRandom() % 64))];
	  explosion3.determineCurAnim(ANIM::AMMO, 2+(jjRandom() % 5));
	  jjOBJ@ explosion4 = jjObjects[jjAddObject(OBJECT::EXPLOSION, (obj.xPos - 32) + (jjRandom() % 64), (obj.yPos- 32) + (jjRandom() % 64))];
	  explosion4.determineCurAnim(ANIM::AMMO, 2+(jjRandom() % 5));
	  jjSample(obj.xPos, obj.yPos, SOUND::COMMON_EXPL_TNT);
     }
	 if (bossKillDelay <= 180){obj.delete();}
     if (bossKillDelay == 0){
      jjNxt(true, false);
     }
	}
	
   default:
   //empty  
   }
 }
 	
	
	
	
	//object collision code from plus52Scripting
	
	bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ player, int force) { //As described in the signs in-level, this is a nearly 100% faithful recreation of standard enemy collision code.
		if (bullet !is null) {
			//recreation of HANDLING::HURTBYBULLET with HANDLING::ENEMY
			if ((bullet.var[6] & 16) == 0) //not a fireball
				bullet.state = STATE::EXPLODE;
			if (obj.freeze > 0 && force < 3)
				force = 3;
			obj.energy -= force;
			if (obj.var[0] == 3){obj.energy -= int(ceil(force*0.5));} //increase the damage that Bomb Force takes because it feels dragged out a bit too long otherwise
			if (obj.var[0] == 4){obj.energy -= force;} //double the damage that Core Force takes because oh goodness is it hard
			if (obj.var[0] == 5){obj.energy -= int(ceil(force*0.5));} //increase the damage that Hydra Force takes because otherwise it takes a bit too long
			if (obj.var[0] == 7){obj.energy -= force;} //double the damage that Core Force takes because it's really hard to hit
			obj.justHit = 5; //flash white for 5 ticks--jjOBJ::justHit is automatically deincremented by the JJ2 engine, so individual behavior functions don't need to worry about doing that.
			obj.freeze = 0;
		} //else { //recreation of HANDLING::ENEMY; player guaranteed to be non-null
//			if (force != 0) { //attacking via special attack, e.g. buttstomp
//				obj.energy -= 4; //constant amount of damage for special attacks
//				obj.justHit = 5;
//				if (obj.freeze > 0) {
//					obj.unfreeze(1);
//				} else {
//					if (obj.energy == 0)
//						obj.particlePixelExplosion(2);
//					jjSample(obj.xPos, obj.yPos, ButtstompSounds[jjRandom() % ButtstompSounds.length]);
//				}
//				
//				if (force > 0) { //buttstomp or sugar rush
//					player.buttstomp = 50; //landing
//					player.ySpeed = player.ySpeed / -2 - 8;
//					player.yAcc = 0;
//					player.extendInvincibility(-70);
//				} else if (force == -101) { //running into frozen enemy
//					player.xAcc = 0;
//					player.xSpeed /= -2;
//					player.ySpeed = -6;
//					player.extendInvincibility(-10);
//				}
//			} else { //not attacking
//				player.hurt();
		return true;
	}
}
//included only for compatibility, taken from plus52Scripting
bool givePlayerPointsForObject(jjPLAYER@ player, jjOBJ@ obj) { //This will probably be made a jjOBJ method as part of the real JJ2+ API eventually, because it shows up all the time in the native code, but that hasn't happened yet, so here you go. Increases the player's jjPLAYER::score to match the object's jjOBJ::points, and creates a string particle with that number which flies up to the top left corner of the screen.
	if (player is null)
		return false;
	if (obj.points != 0 && (jjGameMode == GAME::SP || jjGameMode == GAME::COOP)) {
		player.score += obj.points;
		jjPARTICLE@ particle = jjAddParticle(PARTICLE::STRING);
		if (particle !is null) {
			particle.xPos = obj.xPos;
			particle.yPos = obj.yPos;
			particle.xSpeed = (-32768 - int(jjRandom() & 0x3FFF)) / 65536.f;
			particle.ySpeed = (-65536 - int(jjRandom() & 0x7FFF)) / 65536.f;
			particle.string.text = formatInt(obj.points);
		}
		obj.points = 0; //Ensures that JJ2 won't end up increasing the player's score TWICE, since a call to (the native version of) this function is actually part of the standard pickup-handling code and would otherwise therefore get you in trouble with the FiveUp onObjectHit code.
		return true;
	}
	return false;
}