Downloads containing StoneAbyss5.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Original Levels - Stone... ShaddowBlack0 Single player 4.7 Download file
TSF with JJ2+ Only: Original Levels - Stone... ShaddowBlack0 Single player 4.7 Download file
TSF with JJ2+ Only: Original Levels - Stone... ShaddowBlack0 Single player 4.7 Download file
TSF with JJ2+ Only: Original Levels - Stone... ShaddowBlack0 Single player 4.7 Download file
JJ2+ Only: Stone AbyssFeatured Download Bloody_Body Single player 9.6 Download file

File preview

bool stoned=false, Disarmed=false, Boss=false; 
int i,u=1,c=1,s=1,b=0, m=0, f;
jjPAL myPal,Golden;
jjOBJ@ spawnedObject;
jjOBJ@ spawnedObject2;
jjOBJ@ spawnedObject3;

void onMain() {

	if (Disarmed) {
		jjObjectPresets[OBJECT::SEEKERBULLETPU].playerHandling=HANDLING::PICKUP;
		jjObjectPresets[OBJECT::SEEKERBULLETPU].behavior=FlyingAmmo;
		jjObjectPresets[OBJECT::HATTER].isTarget = false;
		jjObjectPresets[OBJECT::CHESHIRE2].isTarget = false;
	}


myPal.load("Psych2c10.j2t");
updateGems();
  for(int i = 1; i < jjObjectCount; i++) {
    if(jjObjects[i].isActive && jjObjects[i].eventID == OBJECT::SMOKERING&&Boss&&jjDifficulty<3) { //If you play EASY or MEDIUM Tweedle fires smokerings and they behave themselves
      jjObjects[i].ySpeed = 0;                                                                     //like common bullets not counting the fact that they make you dizzy instead of getting hurt and don't vanish after collision with player
      jjObjects[i].xPos = jjObjects[i].xPos+(jjObjects[i].direction*2);                            //but if you play on HARD or TURBO mode smoke rings move back and forth like boomerang.
       }                                                                                           //It is their initial way of motion and it is really hard to avoid them if there are lots of them
	 }                                                                                             //This effect doesn't influence Caterpillar's rings because it starts after you touch the ActivateBoss event
                                                                                                   //Based on "Smoke Ring Gun" snippet written by szmol96

//jjAlert("u "+ formatInt(u, "1"));
jjPLAYER@ play = jjLocalPlayers[0];
if (play.stoned!=0)
{ stoned=true;
jjTexturedBGStyle = TEXTURE::TUNNEL;
s=0;
if (stoned=true && (jjGameTicks & 10)==0 && jjColorDepth == 16)
{b=0; m=0;
for (i = 0; i < 254; i++) {
				jjPalette.color[i+1].setHSL(
					jjPalette.color[i+1].getHue()/20 + jjGameTicks,
					jjPalette.color[i+1].getSat()/20+ 240,//before the release of the new version of JJ2 (dated by 6 April 2015) this thing worked perfectly without adding anything to saturation
					jjPalette.color[i+1].getLight()//but in the newest version there suddenly appeared some problems with it, so I had to add some number (240 seems to be the most suitable) to it otherwise half of colours stayed grey
				);}
				apply();
}}
else if (play.stoned==0)
{stoned=false;
jjTexturedBGStyle = TEXTURE::WARPHORIZON;

if (s==0 &&m<=99&& !Boss && (jjGameTicks & 20) == 0)//sobering up


{
m++;
		jjSetFadeColors(0,40,80);
		jjLocalPlayers[i].lighting = 100;
		//jjPalette.reset();
		jjPalette.copyFrom(
			1,		
			254,		
			1,		
			myPal,	
			m/100.0	
		);
		jjPalette.apply();
		}
		
		else if (m==99) {
		myPal.apply();
		m=100;
		
}

else if (s==0 &&b<=99 && Boss && (jjGameTicks & 20) == 0)//sobering up
{
b++;
		jjSetFadeColors(0+b/2,0+3*b/10,0);
		jjLocalPlayers[i].lighting = 98-b/10;
		//jjPalette.reset();
		jjPalette.copyFrom(
			1,		
			254,		
			1,		
			Golden,	
			b/100.0	
		);
		jjPalette.apply();
		}
		
		else if (b==99) {
		Golden.apply();
		b=100;
		
}

}

if (s==1 &&b<=99 && Boss && (jjGameTicks & 20) == 0) { 

b++;
		jjSetFadeColors(0+b/2,40-b/10,80-b*0.8);
		jjLocalPlayers[i].lighting = 98-b/10;
		jjPalette.reset();
		jjPalette.copyFrom(
			1,		
			254,		
			1,		
			Golden,	
			b/100.0	
		);
		jjPalette.apply();
		}
		
		else if (b==99) {
		Golden.apply();
		b=100;
		}
}



void onLevelReload() {
jjMusicLoad("funkyg.j2b");
b=0;
Boss=false;
Disarmed=false;
jjPalette.reset();
jjSetFadeColors(0,40,80);
}

void onLevelLoad() {


//jjTexturedBGTexture = TEXTURE::WISETYNESS;
				//jjTexturedBGStyle = TEXTURE::TUNNEL;
		for (int weaponID = WEAPON::BLASTER; weaponID <= WEAPON::GUN9; ++weaponID) {
		jjWEAPON@ weaponProfile = jjWeapons[weaponID];
		weaponProfile.comesFromBirds = weaponProfile.comesFromBirdsPowerup = true; 
	}
	
	Golden.gradient(0, 0,0,             0, 0,0,         0, 10, 1.0);
	Golden.gradient(255, 255,255,             255, 255,255,         10, 6, 1.0);
	Golden.gradient(199, 255,0,             199, 255,0,         16, 1, 1.0);
	Golden.gradient(143, 219,0,             0, 11,0,         17, 7, 1.0);
	Golden.gradient(255, 0,0,             163, 0,0,         24, 4, 1.0);
	Golden.gradient(135, 0,0,             11, 0,0,         28, 4, 1.0);
	Golden.gradient(187, 227,255,             0, 139,255,         32, 4, 1.0);
	Golden.gradient(0, 107,203,             0, 7,11,         36, 4, 1.0);
	Golden.gradient(255, 255,0,             255, 199,0,         40, 2, 1.0);
	Golden.gradient(255, 147,0,             255, 95,0,         42, 2, 1.0);
	Golden.gradient(203, 55,0,             11, 0,0,         44, 4, 1.0);
	Golden.gradient(251, 139,183,       239, 0,99,         48, 4, 1.0);            
	Golden.gradient(191, 0,71,      55, 0,19,         52, 4, 1.0);
	Golden.gradient(220, 165,113,             154, 129,100,         56, 3, 1.0);
	Golden.gradient(219, 195,0,             11, 7,0,         59, 5, 1.0);
	Golden.gradient(255, 243,211,             255, 243,211,         64, 1, 1.0);
	Golden.gradient(219, 207,175,             11, 7,7,         65, 7, 1.0);
	Golden.gradient(211, 231,255,             211, 231,255,         72, 1, 1.0);
	Golden.gradient(171, 195,219,             107, 127,155,         73, 3, 1.0);
	Golden.gradient(75, 95,119,             7, 7,11,         76, 4, 1.0);
	Golden.gradient(0, 255,195,             0, 11,7,         80, 8, 1.0);
	Golden.gradient(231, 119,255,             11, 0,7,         88, 8, 1.0);

	Golden.gradient(247, 102,23,             247, 102,23,            96, 1, 1.0);
	Golden.gradient(199,88, 27,             40,17, 6,           97, 7, 1.0);
	Golden.gradient(36,14, 41,             0,0, 15,           104, 8, 1.0);
	Golden.gradient(242, 173,30,  			138, 27,55,  		 112, 8, 1.0);
	Golden.gradient(93, 23, 38, 			    7, 2, 2, 		     120, 8, 1.0);
	Golden.gradient(179, 73, 108,            50, 20, 30, 	          128, 8, 1.0);
	Golden.gradient(44, 18, 27,            1, 0, 0, 	          136, 8, 1.0);
	Golden.gradient(255, 190, 23,                241, 172, 25,             144, 2, 1.0);
	Golden.gradient(235, 158, 23,                186, 92, 37,             146, 6, 1.0);
	Golden.gradient(173, 81, 42,                50, 7, 21,             152, 8, 1.0);
	Golden.gradient(150, 174, 183,            107, 77, 56,         160, 8, 1.0);
	Golden.gradient(98, 65, 47,            1, 1, 1,         168, 8, 1.0);
	Golden.gradient(22, 30, 77,            0, 0, 3,           176, 32, 1.0);
	
	//	jjPalette.copyFrom(
		//	1,		
		//	254,		
		//	1,		
		//	Golden,	
		//	0.5
		//);
		//jjPalette.apply();
	
	
	jjObjectPresets[OBJECT::BILSY].behavior = Tweedle;//Initially I used OBJECT::TWEEDLEBOSS but there was a small problem with it
	jjObjectPresets[OBJECT::BILSY].points = 0;//Tweedle doesn't behave like other bosses, his original "objecthit" function (or anything else that is responsible for collisions with players and bullets in the original code of JJ2) is the same as the common enemies have: 
	jjObjectPresets[OBJECT::BILSY].energy = 100;//He receives too much damage from the special attacks and buttstomps.
	jjObjectPresets[OBJECT::BILSY].isBlastable = false;//That wasn't good especially because I wanted him to steal player's ammo with a magnet so the player would be forced to use buttstomps and special attacks...
	//jjObjectPresets[OBJECT::BILSY].scriptedCollisions = true;//It would be too easy to defeat him this way and I wanted to make this level and this fight really challenging. And probably I was too lazy to write onObjecthit for him
	jjObjectPresets[OBJECT::BILSY].bulletHandling = HANDLING::HURTBYBULLET;//However, OBJECT::BILSY had solved all of these problems
	jjObjectPresets[OBJECT::BILSY].playerHandling = HANDLING::SPECIAL;
	jjObjectPresets[OBJECT::BILSY].state = STATE::START;
	jjObjectPresets[OBJECT::BILSY].xSpeed = 1;
	//jjObjectPresets[OBJECT::BILSY].deactivates = true;
	
	//jjObjectPresets[OBJECT::SEEKERBULLETPU].determineCurAnim(ANIM::AMMO, 57);
	//jjObjectPresets[OBJECT::SEEKERBULLETPU].behavior=FlyingAmmo;
	//jjObjectPresets[OBJECT::SEEKERBULLETPU].playerHandling=HANDLING::PICKUP;
	//jjObjectPresets[OBJECT::SEEKERBULLETPU].lightType = LIGHT::NONE;
	
	jjObjectPresets[OBJECT::BEES].behavior = NPC;
	jjObjectPresets[OBJECT::BEES].bulletHandling = HANDLING::IGNOREBULLET;
	jjObjectPresets[OBJECT::BEES].playerHandling = HANDLING::EXPLOSION;
	
	jjObjectPresets[OBJECT::APPLE].light = 115;
	jjObjectPresets[OBJECT::APPLE].lightType = LIGHT::FLICKER;
	jjObjectPresets[OBJECT::APPLE].bulletHandling = HANDLING::IGNOREBULLET;
	jjObjectPresets[OBJECT::APPLE].playerHandling = HANDLING::EXPLOSION;
	jjObjectPresets[OBJECT::APPLE].isBlastable = false;
	
	jjObjectPresets[OBJECT::SPARK].behavior = Flame;
	jjObjectPresets[OBJECT::SPARK].bulletHandling = HANDLING::IGNOREBULLET;
	jjObjectPresets[OBJECT::SPARK].playerHandling = HANDLING::ENEMYBULLET;
	jjObjectPresets[OBJECT::SPARK].animSpeed = 1; //damage done to player
	jjObjectPresets[OBJECT::SPARK].state = STATE::FLOAT;
	jjObjectPresets[OBJECT::SPARK].lightType = LIGHT::POINT;
	jjObjectPresets[OBJECT::SPARK].points =0;
	jjObjectPresets[OBJECT::SPARK].light =55;
	jjObjectPresets[OBJECT::SPARK].isTarget=false;
	jjObjectPresets[OBJECT::SPARK].scriptedCollisions=true;
	
	jjObjectPresets[OBJECT::CHESHIRE2].energy = 5+jjDifficulty;
	jjObjectPresets[OBJECT::CHESHIRE2].special = 5+jjDifficulty;
	jjObjectPresets[OBJECT::CHESHIRE2].behavior = FlamingCat;
	jjObjectPresets[OBJECT::CHESHIRE2].points = 800;
    jjObjectPresets[OBJECT::CHESHIRE2].playerHandling = HANDLING::ENEMY;
	jjObjectPresets[OBJECT::CHESHIRE2].bulletHandling = HANDLING::HURTBYBULLET;
	jjObjectPresets[OBJECT::CHESHIRE2].isTarget = true;
	jjObjectPresets[OBJECT::CHESHIRE2].isBlastable = true;
	jjObjectPresets[OBJECT::CHESHIRE2].state = STATE::FLOAT;
	}
	
	void updateGems()
{
  for(int i=1;i<jjObjectCount;i++)
  {
    if(jjObjects[i].isActive)
    {
      if(jjObjects[i].eventID==OBJECT::SUPERGEM)
      {
        jjObjects[i].var[0]=jjParameterGet(jjObjects[i].xOrg/32,jjObjects[i].yOrg/32,0,2)+1;
      }
      if(jjObjects[i].eventID==OBJECT::FLICKERGEM)
      {
        if(jjEventGet(jjObjects[i].xOrg/32,jjObjects[i].yOrg/32)==OBJECT::SUPERGEM)
        {
          jjObjects[i].var[0]=jjParameterGet(jjObjects[i].xOrg/32,jjObjects[i].yOrg/32,0,2)+1;
        }
        else if(jjEventGet(jjObjects[i].xOrg/32,jjObjects[i].yOrg/32+1)==OBJECT::GEMSTOMP)
        {
          jjObjects[i].var[0]=jjParameterGet(jjObjects[i].xOrg/32,jjObjects[i].yOrg/32+1,0,2)+1;
        }
        if(jjObjects[i].var[0]==2||jjObjects[i].var[0]==3)
        {
          jjObjects[i].points=500*(jjObjects[i].var[0]-1);
        }
      }
    }
  }
}

		void onFunction30(jjPLAYER@ play) {
		
		Boss=true;
play.boss=jjAddObject(OBJECT::BILSY, 274*32, 74*32);
	}
	
void FlamingCat(jjOBJ@ enemy) { 
	
	
		switch (enemy.state) {
		case STATE::FLOAT:
		enemy.bulletHandling = HANDLING::IGNOREBULLET;
		enemy.determineCurAnim(ANIM::CAT2, 3);	
		enemy.determineCurFrame();	
		
			if (enemy.findNearestPlayer(164*164) > -1) 
			{enemy.state = STATE::ATTACK;
			int c=((jjRandom() & 19) - 9.5);}
			break;
	 case STATE::ATTACK:
	 enemy.playerHandling = HANDLING::ENEMY;
	 enemy.bulletHandling = HANDLING::HURTBYBULLET;
	 ++enemy.counter;
	 if (enemy.counter == 1)
	 {jjSample(enemy.xPos, enemy.yPos, SOUND::INTRO_GREN1);}
	 
	 enemy.direction = (jjLocalPlayers[0].xPos < enemy.xPos) ? -1 : 1;
	 	if (jjRandom() & 2 == 0 && jjDifficulty<3) {
			jjOBJ@ obj = jjObjects[enemy.fireBullet(OBJECT::SPARK)];
			obj.determineCurAnim(ANIM::AMMO,55);
			obj.determineCurFrame();	
			obj.yPos = enemy.yPos+15;
			obj.xPos = enemy.xPos;
		}
		else if (jjRandom() & 2 == 0 && jjDifficulty>2){
	 
			jjOBJ@ obj = jjObjects[enemy.fireBullet(OBJECT::SPARK)];
			obj.determineCurAnim(ANIM::AMMO,0);
			obj.determineCurFrame();	
			obj.yPos = enemy.yPos+15;
			obj.xPos = enemy.xPos;
		}
		enemy.determineCurAnim(ANIM::CAT2,2);
		enemy.determineCurFrame();
		enemy.frameID = enemy.counter/50;
		enemy.counter += 5; 
		
		enemy.xPos = jjSin(enemy.counter/c)*c + enemy.xPos; 
		enemy.yPos = jjCos(enemy.counter/3*c)*2*c + enemy.yPos ;//Lissajous figures :D
	if (++enemy.counter > 3300) 
	{
	enemy.xAcc= enemy.yAcc =0;
	enemy.state = STATE::FADEOUT;
	enemy.counter =0;
	
						}
		
		
		
		
	break;
		case STATE::FADEOUT:
		enemy.playerHandling = HANDLING::PARTICLE;
		enemy.bulletHandling = HANDLING::IGNOREBULLET;
	if (++enemy.counter < 100) {
			enemy.determineCurAnim(ANIM::CAT2, 1);
			enemy.frameID = enemy.counter / 20;
			enemy.determineCurFrame();
			}
			else {
			enemy.state = STATE::FADEIN;
			enemy.determineCurAnim(ANIM::CAT2, 0);
			if (enemy.findNearestPlayer(2000*2000) > -1) 
			{{jjPLAYER@ play = jjLocalPlayers[0];			 
			enemy.xPos = play.xPos - (jjRandom() & 100)+50;
			enemy.yPos = play.yPos - (jjRandom() & 100)+50;}
			enemy.direction = (jjLocalPlayers[0].xPos < enemy.xPos) ? -1 : 1;
			enemy.determineCurFrame();
			enemy.counter = 0;
			}
			else {enemy.state = STATE::FLOAT;}
		}
		break;
		case STATE::FADEIN:
			enemy.bulletHandling = HANDLING::HURTBYBULLET;
		c=((jjRandom() & 5)-2.5);

		if (++enemy.counter < 100) {
			enemy.frameID = enemy.counter / 20;
			enemy.determineCurFrame();
		} else {
	 {enemy.state = STATE::ATTACK;}
				enemy.counter=0;
		}
		
		break;
		
	case STATE::FREEZE:
			if (enemy.freeze > 0) {
				enemy.draw();
				enemy.freeze -= 4;
			}
			if (enemy.freeze < 4) {
				enemy.unfreeze(0);
				enemy.state = enemy.oldState;
			}
			break;
	case STATE::DEACTIVATE:
		enemy.deactivate();
		break;		
	case STATE::KILL:
	if (jjRandom() & 2 == 0)
	{jjAddObject(OBJECT::TOASTERAMMO3, enemy.xPos, enemy.yPos, p.playerID, CREATOR::PLAYER);}
	enemy.delete();
		break;
	}
	enemy.draw();
	}
	
	void Flame(jjOBJ@ enemy) {
	if (enemy.state== STATE::FLOAT) {
		enemy.behave(BEHAVIOR::SPARK);
		++enemy.counter;
		if (enemy.counter >150*jjDifficulty+100)
				enemy.delete();
	} else
		enemy.delete();
	}
	
								void Flame1(jjOBJ@ enemy) {
		jjPLAYER@ play = jjLocalPlayers[0];
		
		if (enemy.xPos > play.xPos)
				enemy.xPos = enemy.xPos - (2+jjDifficulty/4); 
		else if (enemy.xPos < play.xPos) 
				enemy.xPos = enemy.xPos + (2+jjDifficulty/4);
		if (enemy.yPos > play.yPos)
				enemy.yPos = enemy.yPos - (2+jjDifficulty/4); 
		else if (enemy.yPos < play.yPos) 
				enemy.yPos = enemy.yPos + (2+jjDifficulty/4);
		
		//enemy.draw();
		++enemy.counter;
		enemy.counter += 1; 
		 if (enemy.counter >150*jjDifficulty+100)
		{enemy.delete();
		}
	enemy.draw();}
	
	
		void Tweedle(jjOBJ@ boss) {
		
	jjPLAYER@ play = jjLocalPlayers[0];
	if ( boss.energy <=0) 
	{	boss.state = STATE::DONE; 
	boss.counter == 0;}			
		switch (boss.state) {
	case STATE::START:
	u=(jjRandom() & 3);
		boss.determineCurAnim(ANIM::TWEEDLE, 6);
		boss.determineCurFrame();
		boss.frameID = boss.counter/5;
		if (boss.justHit == 0)
		jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
		else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);
		boss.putOnGround(true);	
		if (boss.energy < 100 && ++boss.counter <= 5*(jjDifficulty+2)) {
		++boss.energy;
		
		jjSample(boss.xPos, boss.yPos, SOUND::BILSBOSS_ZIP);
		//boss.lightType = LIGHT::LASER;
		//boss.light =55;

		
		}
		//if (++boss.counter >= 55)
	//	{boss.light =0;}
	if (++boss.counter == 55){
		jjPARTICLE@ particle = jjAddParticle(PARTICLE::STRING);
		if (particle !is null) {
		particle.xPos = boss.xPos-20;
		particle.yPos = boss.yPos;
		particle.string.text = "HEAL";}
		
		particle.ySpeed = -0.4;
		jjAlert("Tweedle heals himself by "+ formatInt(2*(jjDifficulty), "1"));
	}	
		if ((boss.findNearestPlayer(600*600) > -1) && ++boss.counter > 55)
		{boss.state = STATE::IDLE; boss.counter = 0;}
		break;
 case STATE::WALK:
        boss.behave(BEHAVIOR::WALKINGENEMY);
        {
		if (boss.counter >= 180)
		{boss.counter = 0; }
       //jjAlert("boss.counter "+ formatInt(boss.counter, "1"));
	   //jjAlert("boss.frameID "+ formatInt(boss.frameID, "1"));
                boss.counter++;
                if (u==0||u==1)
                {if (++boss.counter < 165){
                        boss.xSpeed= (jjDifficulty+3)*boss.direction;
                        boss.determineCurAnim(ANIM::TWEEDLE, 1);
                        if (boss.counter == 10){
                        jjSample(boss.xPos, boss.yPos, SOUND::INTRO_GREN3);}
                        if (boss.justHit == 0)
                        {jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);}
                        boss.determineCurFrame();
                        //boss.frameID = boss.counter/10;
						}
                        else
                        {boss.frameID = boss.counter = 0;
                        boss.state = STATE::IDLE;}
                        }
                        else if (u==2||u==3)
                        {if (++boss.counter < 180){
                        boss.xSpeed= boss.direction;
                        boss.determineCurAnim(ANIM::TWEEDLE, 8);}
                        else
                        {boss.frameID = boss.counter = 0;
                        boss.state = STATE::IDLE;}
						
						if (boss.justHit == 0)
                        {jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);}
                        boss.determineCurFrame();
						
                        //boss.frameID = boss.counter/10;
                        }

       
                break;
        }
	case STATE::FREEZE:
			if (boss.freeze > 0) {
				boss.draw();
				boss.freeze -= 4;
			}
			if (boss.freeze < 4) {
				boss.unfreeze(0);
				boss.state = boss.oldState;
			}
			break;
	case STATE::DEACTIVATE:
		boss.deactivate();
		break;
	case STATE::DONE:

		boss.determineCurAnim(ANIM::TWEEDLE, 5);
		boss.determineCurFrame();
		boss.frameID = boss.counter/20;
		jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
	++boss.counter;
	if (++boss.counter>89) {
	boss.energy = 100;}
			if (++boss.counter>90) {
	boss.state = STATE::START;
	boss.behavior = Tweedle2;
		boss.counter==0;			
		//jjEventSet(p.xPos / 32, p.yPos / 32, AREA::EOL);
		}
		break;

	case STATE::IDLE:
		boss.frameID = boss.counter/5;
		boss.determineCurFrame();
		if (boss.justHit == 0)
		jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
		else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);
		 
			if (boss.var[0] == 0) { boss.var[0] = 1; }
			switch (jjRandom() & 3) {
			
				case 0:
				
					boss.state = STATE::ATTACK;
					boss.direction = (jjLocalPlayers[0].xPos < boss.xPos) ? -1 : 1;
					if (play.charCurr == CHAR::JAZZ)
					{boss.determineCurAnim(ANIM::TWEEDLE, 4);}
					else
					{boss.determineCurAnim(ANIM::TWEEDLE, 3);}
					boss.counter = 0;
					break;
				
				case 1:
					boss.state = STATE::WALK;
					boss.counter = 0;
					break;

				case 2:
					boss.state = STATE::START;
					boss.determineCurAnim(ANIM::TWEEDLE, 6); 
					boss.counter = 0;
					break;
					
					
			}
		
		break;

	case STATE::ATTACK:

		if (++boss.counter < 36) {
			boss.frameID = boss.counter / 5;
			boss.determineCurFrame();
			if (boss.justHit == 0)
		jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
		else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);
			if ((u==0||u==1)&& ( boss.counter == 25||boss.counter == 30|| boss.counter == 35))
			{
		jjOBJ@ bullet = jjObjects[boss.fireBullet(OBJECT::BOUNCERBULLET)];
				
				bullet.killAnim = bullet.determineCurAnim(ANIM::AMMO, 4, false);
				bullet.playerHandling = HANDLING::ENEMYBULLET;
				bullet.state = STATE::FLY;
				bullet.ySpeed = (-(jjRandom() & 6)+3);
				bullet.xPos = boss.xPos;
				bullet.yPos = boss.yPos-7; 	
				bullet.animSpeed = 1;
				jjSample(boss.xPos, boss.yPos, SOUND::AMMO_SPZBL1);
			}
			else if ((u==2) && (boss.counter == 25||boss.counter == 30||boss.counter == 35))
			{
		jjOBJ@ bullet = jjObjects[boss.fireBullet(OBJECT::BLASTERBULLET)];
				
				bullet.killAnim = bullet.determineCurAnim(ANIM::AMMO, 4, false);
				bullet.playerHandling = HANDLING::ENEMYBULLET;
				bullet.state = STATE::FLY;
				bullet.xPos = boss.xPos;
				bullet.yPos = boss.yPos-7; 	
				bullet.animSpeed = 1;
				jjSample(boss.xPos, boss.yPos, SOUND::AMMO_GUN3PLOP);
			}
			else if (u==3 && ( boss.counter == 30))
			{
		jjOBJ@ bullet = jjObjects[boss.fireBullet(OBJECT::ELECTROBULLETPU)];
				
				bullet.playerHandling = HANDLING::ENEMYBULLET;
				bullet.state = STATE::FLY;
				bullet.xPos = boss.xPos;
				bullet.yPos = boss.yPos-7; 	
				
				bullet.animSpeed = 1;
				jjSample(boss.xPos, boss.yPos, SOUND::AMMO_LASER2);
			}
			
		} else {
			boss.frameID = boss.counter = 0;
			boss.determineCurAnim(ANIM::TWEEDLE, 6);
			boss.state = STATE::IDLE;
		}
		break;
	}
	
}

	void Tweedle2(jjOBJ@ boss) {
	jjPLAYER@ play = jjLocalPlayers[0];
	//boss.light=0;
	if ( boss.energy ==0) 
	{boss.state = STATE::KILL;
	boss.counter == 0;}			
		switch (boss.state) {
	case STATE::START:
	
	 if (++boss.counter >= 0&&++boss.counter <= 400)
	 	{boss.determineCurFrame();
			boss.frameID = boss.counter/60;}
	boss.determineCurAnim(ANIM::TWEEDLE, 0);
	boss.direction = (jjLocalPlayers[0].xPos < boss.xPos) ? -1 : 1;
	 if (++boss.counter > 400&&++boss.counter <= 2800)
{boss.determineCurFrame();
boss.frameID = boss.counter/40;
boss.determineCurAnim(ANIM::TWEEDLE, 7);}	
		if (++boss.counter > 0){
		Disarmed=true;
	play.noFire=true;}
	if (++boss.counter > 500&& ++boss.counter < 800&&jjGameTicks%5==0){
	//play.noFire=true;
	u++;
	jjSample(boss.xPos, boss.yPos, SOUND::SONCSHIP_METAL1);
	@spawnedObject2 = jjObjects[jjAddObject(OBJECT::SEEKERBULLETPU, play.xPos, play.yPos)];
	++spawnedObject2.counter;	
	spawnedObject2.light =0;	
	//if (spawnedObject2.xPos==boss.xPos && spawnedObject2.yPos==boss.yPos)
	//{spawnedObject2.delete();}
	jjDrawSpriteFromCurFrame(spawnedObject2.xPos, spawnedObject2.yPos, spawnedObject2.curFrame, spawnedObject2.direction, SPRITE::NORMAL);
			}
		
		boss.determineCurFrame();
		boss.frameID = boss.counter/5;
		if (boss.justHit == 0)
		jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
		else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);
		boss.putOnGround(true);	
		
		if (++boss.counter > 690&&++boss.counter <= 700)
	{play.showText("@@Tweedle has stolen your ammo!@You can't shoot now!", STRING::SMALL);}
		if (++boss.counter > 2800&&++boss.counter <= 3010) {
		boss.determineCurAnim(ANIM::TWEEDLE, 2);
		boss.determineCurFrame();
		boss.frameID = boss.counter/70;
		}
		
		if ((boss.findNearestPlayer(600*600) > -1) && ++boss.counter > 3010) {
		boss.state = STATE::ATTACK; 
		boss.counter == 0;}
		break;
		case STATE::STILL:
	u=(jjRandom() & 3);
		if (boss.energy < 100 && ++boss.counter <= 2*(jjDifficulty+2)) {
		++boss.energy;}
		if (++boss.counter > 53){
		jjPARTICLE@ particle = jjAddParticle(PARTICLE::STRING);
		if (particle !is null) {
		particle.xPos = boss.xPos-20;
		particle.yPos = boss.yPos;
		particle.string.text = "HEAL";}
		
		particle.ySpeed = -0.4;
		jjAlert("Tweedle heals himself by "+ formatInt((jjDifficulty), "1"));
	}
		boss.determineCurAnim(ANIM::TWEEDLE, 6);
		boss.determineCurFrame();
		boss.frameID = boss.counter/5;
		if (boss.justHit == 0)
		jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
		else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);
		boss.putOnGround(true);	
	
		if ((boss.findNearestPlayer(600*600) > -1) && ++boss.counter > 55)
		{boss.state = STATE::IDLE; boss.counter == 0;}
		break;
	case STATE::WALK:
	                        
  if (++boss.counter < 180){
                        boss.behave(BEHAVIOR::WALKINGENEMY);
                        boss.xSpeed= boss.direction;
                        boss.determineCurAnim(ANIM::TWEEDLE, 8);
                        //jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
                       boss.determineCurFrame();}
                        else
                        {boss.counter = 0;
                        boss.state = STATE::IDLE;
                        boss.playerHandling = HANDLING::SPECIAL;
                        boss.bulletHandling = HANDLING::HURTBYBULLET;}
               
                break;
	case STATE::FREEZE:
			if (boss.freeze > 0) {
				boss.draw();
				boss.freeze -= 4;
			}
			if (boss.freeze < 4) {
				boss.unfreeze(0);
				boss.state = boss.oldState;
			}
			break;
	//case STATE::DEACTIVATE:
	//	boss.state = STATE::FADEOUT;
	//	break;
	case STATE::DONE:
	//play.showText("@What a stupid clown!", STRING::SMALL);
		if (++boss.counter == 5){
					jjPARTICLE@ particle = jjAddParticle(PARTICLE::STRING);
			if (particle !is null) {
				particle.xPos = boss.xPos;
				particle.yPos = boss.yPos;
				particle.string.text = "3000";
				particle.ySpeed = -1.2;
				particle.xSpeed = -1.1;
				play.score += 3000;
			}}
		boss.determineCurAnim(ANIM::TWEEDLE, 5);
		boss.determineCurFrame();
	boss.frameID = boss.counter/10;
	jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
++boss.counter;
		if (++boss.counterEnd == 50){
		jjOBJ@ obj = jjObjects[boss.fireBullet(OBJECT::BOUNCEONCE)];
		jjSample(boss.xPos, boss.yPos, SOUND::MENUSOUNDS_SELECT0);
		if (play.charCurr == CHAR::JAZZ)
		{obj.determineCurAnim(ANIM::AMMO, 19);}
		else
			{obj.determineCurAnim(ANIM::AMMO, 18);}
	}if (++boss.counter==90 ){boss.particlePixelExplosion(2);
		
			}
			if (++boss.counter>100) {
			
	jjEventSet(play.xPos / 32, play.yPos / 32, AREA::EOL);
		}
	break;
			case STATE::KILL:
	case STATE::DEACTIVATE:
		boss.deactivate();
		break;

	case STATE::WAIT: //caused by BEHAVIOR::WALKINGENEMY sometimes
	case STATE::IDLE:
		boss.frameID = boss.counter/5;
		boss.determineCurFrame();
		if (boss.justHit == 0)
		jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
		else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);
		 
			if (boss.var[0] == 0) { boss.var[0] = 1; }
			switch (jjRandom() % 10) {
				case 0:
				case 1:
				case 2:
				case 3:
					boss.state = STATE::ATTACK;
					boss.direction = (jjLocalPlayers[0].xPos < boss.xPos) ? -1 : 1;
					if (play.charCurr == CHAR::JAZZ)
					{boss.determineCurAnim(ANIM::TWEEDLE, 4);}
					else
					{boss.determineCurAnim(ANIM::TWEEDLE, 3);}
					boss.counter = 0;
					break;
					
				
				case 4:
				case 5:
				case 6:
				//jjAlert("boss.xPos "+ formatInt(boss.xPos, "1"));
				//jjAlert("boss.yPos "+ formatInt(boss.yPos, "1"));
				if (boss.yPos < play.yPos-32 || boss.yPos > play.yPos+32 || boss.xPos < play.xPos-32*3 || boss.xPos > play.xPos+32*3)
				{	boss.state = STATE::FADEOUT;
					boss.determineCurAnim(ANIM::TWEEDLE, 1);
					
					boss.counter = 0;
					if (jjDifficulty > 0) { 
						boss.playerHandling = HANDLING::PARTICLE;
						boss.bulletHandling = HANDLING::IGNOREBULLET;
					} {
						boss.xAcc = play.xPos;
						boss.yAcc = play.yPos;
					}
					}
					else 
					{boss.state = STATE::WALK;}
					break;
					
				case 7:
				boss.state = STATE::STILL;
				
				//boss.direction = (jjLocalPlayers[0].xPos < boss.xPos) ? -1 : 1;
					boss.counter = 0;
					break;
				
				case 8:
				case 9:
					boss.state = STATE::WALK;
					boss.counter = 0;
					break;
				
			}
		
		break;
	case STATE::FADEOUT:
	if(++boss.counter == 1) 
	{jjSample(boss.xPos, boss.yPos, SOUND::DEVILDEVAN_VANISH1);}
		else if (++boss.counter < 50) {
			boss.frameID = boss.counter / 5;
			
			jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::TRANSLUCENT);
			
			boss.determineCurFrame();
			}
			else {
			boss.frameID = boss.counter = 0;
			boss.state = STATE::FADEIN;
			
			boss.determineCurAnim(ANIM::TWEEDLE, 1);
			boss.xPos = boss.xAcc;
			boss.yPos = boss.yAcc - 10;
			boss.direction = (jjLocalPlayers[0].xPos < boss.xPos) ? -1 : 1;
			boss.determineCurFrame();
			boss.putOnGround(true);
			return;
		}
		break;
	case STATE::FADEIN:
		if (++boss.counter < 40) {
			boss.frameID = boss.counter / 5;
			boss.determineCurFrame();
			jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::TRANSLUCENT);
		} else {
			boss.frameID = boss.counter = 0;
			boss.state = STATE::IDLE;
			boss.playerHandling = HANDLING::SPECIAL;
			boss.bulletHandling = HANDLING::HURTBYBULLET;
			boss.yAcc=boss.xAcc=0;
		}
		break;
	case STATE::ATTACK:

		if (++boss.counter < 36) {
			boss.frameID = boss.counter / 5;
			boss.determineCurFrame();
			if (boss.justHit == 0)
		jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::NORMAL);
		else jjDrawSpriteFromCurFrame(boss.xPos, boss.yPos, boss.curFrame, boss.direction, SPRITE::SINGLECOLOR,15);
		
			if (boss.counter == 30)
			{
		jjOBJ@ bullet = jjObjects[boss.fireBullet(OBJECT::SMOKERING)];
				//bullet.behave(BEHAVIOR::BULLET);
				//bullet.xSpeed = bullet.direction*2;   
	            bullet.ySpeed = 0;
				bullet.yAcc = 0;
				//bullet.xAcc = 0;
				bullet.xPos = boss.xPos;
				bullet.yPos = boss.yPos-7; 	
				jjSample(boss.xPos, boss.yPos, SOUND::INTRO_BLOW);
			}
			
		} else {
			boss.frameID = boss.counter = 0;
			boss.determineCurAnim(ANIM::TWEEDLE, 6);
			boss.state = STATE::IDLE;
		}
		break;
	}
}

void FlyingAmmo (jjOBJ@ obj) {
	if (obj.state == STATE::START) {
		u=(jjRandom() % 5);
		if (u==0)
			{obj.var[5] = obj.determineCurAnim(ANIM::AMMO, 57, false);}
		else if (u==1)
			{obj.var[5] = obj.determineCurAnim(ANIM::AMMO, 49, false);}
		else if (u==2)
			{obj.var[5] = obj.determineCurAnim(ANIM::AMMO, 24, false);}
		else
			{obj.var[5] = obj.determineCurAnim(ANIM::AMMO, 28, false);}
	}
	obj.behave(BEHAVIOR::SEEKERBULLET,false);
	jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, jjAnimations[obj.var[5]].firstFrame + ((jjGameTicks >> 2) & 7));
}



void NPC(jjOBJ@ obj) {
jjPLAYER@ play = jjLocalPlayers[0];
	if (obj.state == STATE::START) {
					if (play.charCurr == CHAR::JAZZ)
					
				{obj.determineCurAnim(ANIM::SPAZ, 102);
				obj.xSpeed = 2;}
				else 
				{obj.determineCurAnim(ANIM::JAZZ, 101);}
				obj.xSpeed = 2;
		
		
		obj.state = STATE::WALK;
	}
	obj.behave(BEHAVIOR::WALKINGENEMY);
}
	
	
	void apply(jjPAL pal = jjPalette) {
	jjSetFadeColors(
		pal.color[207].red,
		pal.color[207].green,
		pal.color[207].blue
	);
	pal.apply();
}

void onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) {
if (obj.eventID == OBJECT::SPARK) {
 if (play !is null) {
			if (force == 0) //normal collision, not using any buttstomps or whatever
				play.hurt();
				else if (force != 0)
				{obj.delete();}}
				}}