Downloads containing bossmrt.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Boss Test ShaddowBlack0 Test N/A Download file

File preview

float queen_x, queen_y, devan_x, devan_y;
int queen_id = -1;
int devan_id = -1;
void onLevelLoad(){
	if(jjObjectPresets[OBJECT::DEVILDEVAN].behavior == BEHAVIOR::DEVILDEVAN){
		jjObjectPresets[OBJECT::DEVILDEVAN].behavior = function(obj) { obj.behavior = DevanRewrite(); };
	}
	jjObjectPresets[OBJECT::ROBOT].behavior = function(obj) { obj.behavior = RobotRewrite(); };
	jjObjectPresets[OBJECT::BILSY].behavior = function(obj) { obj.behavior = BilsyRewrite(); };
	
	jjObjectPresets[OBJECT::BLASTERBULLET].behavior = function(obj) { obj.behavior = BulletRewrite(); };
	jjObjectPresets[OBJECT::SEEKERBULLET].behavior = function(obj) { obj.behavior = SeekerRewrite(); };
	jjObjectPresets[OBJECT::SEEKERBULLETPU].behavior = function(obj) { obj.behavior = SeekerRewrite(); };
	
	jjObjectPresets[OBJECT::BAT].behavior = function(obj) { obj.behavior = BatRewrite(); };
	jjObjectPresets[OBJECT::BAT].scriptedCollisions = true;
	jjObjectPresets[OBJECT::BAT].playerHandling = HANDLING::SPECIAL;
}
const array<SOUND::Sample> ButtstompSounds = {SOUND::COMMON_SPLAT1, SOUND::COMMON_SPLAT2, SOUND::COMMON_SPLAT3, SOUND::COMMON_SPLAT4};
class BatRewrite : jjBEHAVIORINTERFACE {
	bool deleted = false;
	int delay = -1;
	int count = 0;
	void onBehave(jjOBJ@ obj) { 
		if(!deleted){
			obj.behave(BEHAVIOR::BAT, true);
			obj.scriptedCollisions = true;
			obj.playerHandling = HANDLING::SPECIAL;
			if(delay == -1){
				if(jjEventGet(int(obj.xOrg/32), int(obj.yOrg/32)) == OBJECT::GENERATOR){
					delay = jjParameterGet(int(obj.xPos/32), int(obj.yPos/32), 8, 8);
					//jjAlert("delay: "+delay);
					if(delay == 0) delay = 5;
				}
			}
		}else{
			if(jjGameTicks%70 == 0){
				count++;
				if(count >= delay){
					//jjAlert("recreate bat", false);
					obj.xPos = obj.xOrg;
					obj.yPos = obj.yOrg;
					obj.state = STATE::START;
					deleted = false;
					count = 0;
				}
			}
		}
	}
	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(!deleted){
			if (bullet !is null) {
				//recreation of HANDLING::HURTBYBULLET with HANDLING::ENEMY
				if (obj.causesRicochet) {
					if ((bullet.var[6] & 6) == 0) //not fire-based, not a laser beam
						bullet.ricochet();
					else if ((bullet.var[6] & 4) == 0) //not a laser beam
						bullet.delete();
				} else if ((bullet.var[6] & 16) == 0) //not a fireball
					bullet.state = STATE::EXPLODE;
				if (obj.freeze > 0 && force < 3)
					force = 3;
				obj.energy -= force;
				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.
				if (obj.energy <= 0) { //killed
					obj.energy = 0;
					obj.state = STATE::FADEOUT;
					deleted = true;
					if (obj.freeze > 0)
						obj.unfreeze(0);
					else if ((bullet.var[6] & 2) == 0) //not fire-based
						obj.particlePixelExplosion(0);
					else {
						jjSample(obj.xPos, obj.yPos, SOUND::COMMON_BURN);
						if ((bullet.var[6] & 4) != 0) //laser beam
							obj.particlePixelExplosion(72); //gray
						else
							obj.particlePixelExplosion(((bullet.var[6] & 8) != 0) ? 32 : 40); //powered-up (blue) or not (orange)
					}
					if (player !is null) {
						obj.grantPickup(player, (uint(bullet.curAnim) == jjAnimSets[ANIM::AMMO].firstAnim + 17) ? 5 : 10);
						//givePlayerPointsForObject(player, obj);
					}
				} else
					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
					if (obj.energy <= 0) { //killed
						obj.energy = 0;
						//givePlayerPointsForObject(player, obj);
						obj.state = STATE::FADEOUT;
						deleted = true;
					} else { //only wounded
						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;
	}
}
array<int> kill(4,0);
void onMain(){
	for(int i=0; i<jjLocalPlayerCount; i++){
		//if(jjIsServer) jjAlert(jjLocalPlayers[i].xPos/32+" "+jjLocalPlayers[i].yPos/32);
		if(jjLocalPlayers[i].isInGame){
			if(jjLocalPlayers[i].xPos <= 17*32 && jjLocalPlayers[i].yPos <= 8*32){
				if(kill[i] == 0){
					jjAlert("You have been roasted automatically by the level's script in order to reset bosses!");
					if(jjIsServer){
						jjChat("/k "+(jjLocalPlayers[i].playerID+1));
					}else{
						jjSTREAM newStream;
						newStream.push(1);
						newStream.push(jjLocalPlayers[i].playerID+1);
						jjSendPacket(newStream);
					}
					jjLocalPlayers[i].activateBoss(true);
					jjObjects[queen_id].xPos = queen_x;
					jjObjects[queen_id].yPos = queen_y;
					kill[i] = 1;
				}
				
				if(devan_id!=-1){
					jjObjects[devan_id].delete();
					jjObjects[jjAddObject(OBJECT::DEVILDEVAN, devan_x, devan_y)].behavior = DevanRewrite();
					devan_id = -1;
					//jjAlert("here");
				}
			}else{
				jjLocalPlayers[i].activateBoss(true);
				if(queen_id == -1){
					for(int j=0; j<jjObjectCount; j++){
						jjOBJ@ obj = jjObjects[j];
						if(obj.eventID == OBJECT::QUEEN){
							queen_id = obj.objectID;
							queen_x = obj.xOrg;
							queen_y = obj.yOrg;
							break;
						}
					}
				}
				if(devan_id == -1){
					for(int j=0; j<jjObjectCount; j++){
						jjOBJ@ obj = jjObjects[j];
						if(obj.eventID == OBJECT::DEVILDEVAN){
							devan_x = obj.xOrg;
							devan_y = obj.yOrg;
							devan_id = obj.objectID;
							//jjAlert("found "+devan_id);
							break;
						}
					}
					if(devan_id == -1){
						devan_id = -2;
						jjObjects[jjAddObject(OBJECT::DEVILDEVAN, devan_x, devan_y)].behavior = DevanRewrite();
					}
					for(int j=0; j<jjObjectCount; j++){
						jjOBJ@ obj = jjObjects[j];
						if(obj.eventID == OBJECT::DEVILDEVAN){
							devan_x = obj.xOrg;
							devan_y = obj.yOrg;
							devan_id = obj.objectID;
							//jjAlert("found "+devan_id);
							break;
						}
					}
				}
				kill[i] = 0;
			}
		}
	}
}
void onReceive(jjSTREAM &in packet, int ClientID){
	int id;
	packet.pop(id);
	if(id == 1){
		int pID;
		packet.pop(pID);
		jjChat("/k "+pID);
	}
}
class DevanRewrite : jjBEHAVIORINTERFACE {
	bool dragon = false;
	void onBehave(jjOBJ@ obj) { 
		if(!dragon){
			obj.behave(BEHAVIOR::DEVILDEVAN, true);
			if(obj.state == STATE::FLY){ //state 8
				dragon = true;
				obj.playerHandling = HANDLING::ENEMY;
				obj.energy = 100;
			}
		}else{
			obj.playerHandling = HANDLING::ENEMY;
			obj.energy = 100;
			if(obj.state == STATE::FLY){
				cDEVILDEVAN(obj);
			}else{
				obj.behave(BEHAVIOR::DEVILDEVAN, true);
			}
		}
	}
}
class RobotRewrite : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) { 
		obj.behave(BEHAVIOR::ROBOT, true);
		obj.energy = 100;
	}
}
class BilsyRewrite : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) { 
		obj.behave(BEHAVIOR::BILSY, true);
		obj.energy = 100;
	}
}

class BulletRewrite : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) { 
		obj.behave(BEHAVIOR::BULLET, true);
		if(!jjPlayers[obj.creatorID].isLocal){
			obj.delete();
		}
	}
}
class SeekerRewrite : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) { 
		obj.behave(BEHAVIOR::SEEKERBULLET, true);
		if(!jjPlayers[obj.creatorID].isLocal){
			obj.delete();
		}
	}
}

int findNearestLocalPlayer(){
	float min = 99999999.9;
	int poz = -1;
	for(int i=0; i<4; i++){
		jjPLAYER@ p = jjLocalPlayers[i];
		if(min > (p.xPos*p.xPos + p.yPos*p.yPos)){
			min = p.xPos*p.xPos + p.yPos*p.yPos;
			poz = p.playerID;
		}
	}
	return poz;
}
void cDEVILDEVAN(jjOBJ@ obj) {
	switch (obj.state) {
		case STATE::FLY:
			if (obj.counter == 0) {
				obj.curAnim = jjAnimSets[ANIM::DEVILDEVAN].firstAnim + 5;
				obj.frameID = 0;
				obj.var[5] = findNearestLocalPlayer();
				if (obj.var[5] < 0)
					obj.var[5] = 0;
				if (obj.xPos >= jjPlayers[obj.var[5]].xPos) {
					obj.var[4] = 40;
					obj.direction = -1;
				} else {
					obj.var[4] = -40;
					obj.direction = 1;
				}
				obj.var[3] = -4 * int(jjRandom()&15);//RandFac(15);
			}
			obj.counter++;
			if (obj.counter % 5 == 0) {
				obj.frameID++;
				if (obj.frameID == 1){
					//PlaySample(obj.xPos, obj.yPos, sDEVILDEVAN_FLAP, 200, 0);
				}
				if (uint(obj.frameID) >= jjAnimations[obj.curAnim].frameCount){
					obj.frameID = 0;
				}
			}
			if (obj.counter >= 128) {
				obj.state = STATE::ATTACK;
				obj.curAnim = jjAnimSets[ANIM::DEVILDEVAN].firstAnim;
				obj.frameID = 0;
				obj.counter = 0;
			} else {
				int xDist = int((jjPlayers[obj.var[5]].xPos + obj.var[4] - obj.xPos) / (129 - obj.counter));
				if (xDist < -3)
					xDist = -3;
				else if (xDist > 3)
					xDist = 3;
				int yDist = int((obj.var[3] + jjPlayers[obj.var[5]].yPos - obj.yPos) / (129 - obj.counter));
				if (yDist < -2)
					yDist = -2;
				else if (yDist > 2)
					yDist = 2;
				obj.xSpeed = (obj.xSpeed + 3 * xDist) / 4;
				obj.ySpeed = (obj.ySpeed + 3 * yDist) / 4;
				obj.xPos += obj.xSpeed;
				obj.yPos += obj.ySpeed;
				if (obj.xPos < jjPlayers[obj.var[5]].xPos - 20)
					obj.direction = 1;
				else if (obj.xPos > jjPlayers[obj.var[5]].xPos + 20)
					obj.direction = -1;
			}
			obj.curFrame = jjAnimations[obj.curAnim].firstFrame + obj.frameID;
			break;
	}
	SPRITE::Mode sprite_mode = obj.freeze == 0 ? SPRITE::NORMAL : SPRITE::FROZEN;
	jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, sprite_mode);
}