Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Boss Test | ShaddowBlack0 | Test | N/A |
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);
}
Jazz2Online © 1999-INFINITY (Site Credits). We have a Privacy Policy. Jazz Jackrabbit, Jazz Jackrabbit 2, Jazz Jackrabbit Advance and all related trademarks and media are ™ and © Epic Games. Lori Jackrabbit is © Dean Dodrill. J2O development powered by Loops of Fury and Chemical Beats.
Eat your lima beans, Johnny.