Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Stone Abyss | Bloody_Body | Single player | 9.6 |
//spikes from IC - tubelec can be inserted to the tileset as well.
//why not to add a moving (platform) spiky ball to the boss area?
//coins in crates?
//colored gem rings
//autobomb for that central crate can be a solution
//double ammo
jjPAL Boss;
bool final=false,devanactivated=false, devanisdefeated = false;
int b=0, i,d=0;
uint elapsed = 0;
const float DEVANBACKGROUNDSPEED = 2;
const array<OBJECT::Object> devanGoodies = {OBJECT::FIVEHUNDREDBUMP, OBJECT::APPLE, OBJECT::REDGEM, OBJECT::SEEKERAMMO3, OBJECT::CAKE, OBJECT::CHEESE, OBJECT::BURGER};
void onLevelLoad() {
//jjObjectPresets[OBJECT::DEVANROBOT].isBlastable = false;
jjObjectPresets[OBJECT::DEVANROBOT].ySpeed = 3.5; //Will be referenced later for how fast he moves up and down. Could have been an
//an external constant or something, but this is more semantic.
jjObjectPresets[OBJECT::DEVANROBOT].behavior = DevanBoss;
jjObjectPresets[OBJECT::DEVANROBOT].playerHandling = HANDLING::ENEMY;
jjObjectPresets[OBJECT::DEVANROBOT].energy = 100;
jjObjectPresets[OBJECT::SPIKEPLATFORM].behavior = MovingPlatform;
jjObjectPresets[OBJECT::SPIKEPLATFORM].state = STATE::WAIT;
jjObjectPresets[OBJECT::SPIKEPLATFORM].determineCurAnim(ANIM::SPIKEPLAT,0);
jjObjectPresets[OBJECT::SPIKEPLATFORM].isFreezable = false;
jjObjectPresets[OBJECT::SPIKEPLATFORM].deactivates = false;
jjObjectPresets[OBJECT::SPIKEBOLL].behavior = MovingSpikeboll;
jjObjectPresets[OBJECT::SPIKEBOLL].state = STATE::WAIT;
jjObjectPresets[OBJECT::SPIKEBOLL].determineCurAnim(ANIM::SPIKEBOLL,0);
jjObjectPresets[OBJECT::SPIKEBOLL].isFreezable = false;
jjObjectPresets[OBJECT::SPIKEBOLL].deactivates = false;
jjObjectPresets[OBJECT::SKELETON].behavior = TufturtleRic;//Tufturt itself (like some other enemies) doesn't cause ricochets. So I had to use sceleton instead.
jjObjectPresets[OBJECT::SKELETON].scriptedCollisions = true;
jjObjectPresets[OBJECT::SKELETON].determineCurAnim(ANIM::TUFTUR, 0);
jjObjectPresets[OBJECT::SKELETON].xSpeed = 1;
jjObjectPresets[OBJECT::SKELETON].energy = 8;
jjObjectPresets[OBJECT::SKELETON].points = 600;
jjPalette.gradient(255, 77, 77, 154, 17, 17, 112, 8, 1.0);
jjPalette.gradient(129, 9, 9, 0, 0, 0, 120, 8, 1.0);
//jjPalette.apply();
Boss.gradient(0, 0,0, 0, 0,0, 0, 10, 1.0);
Boss.gradient(255, 255,255, 255, 255,255, 10, 6, 1.0);
Boss.gradient(199, 255,0, 199, 255,0, 16, 1, 1.0);
Boss.gradient(143, 219,0, 0, 11,0, 17, 7, 1.0);
Boss.gradient(255, 0,0, 163, 0,0, 24, 4, 1.0);
Boss.gradient(135, 0,0, 11, 0,0, 28, 4, 1.0);
Boss.gradient(187, 227,255, 0, 139,255, 32, 4, 1.0);
Boss.gradient(0, 107,203, 0, 7,11, 36, 4, 1.0);
Boss.gradient(255, 255,0, 255, 199,0, 40, 2, 1.0);
Boss.gradient(255, 147,0, 255, 95,0, 42, 2, 1.0);
Boss.gradient(203, 55,0, 11, 0,0, 44, 4, 1.0);
Boss.gradient(251, 139,183, 239, 0,99, 48, 4, 1.0);
Boss.gradient(191, 0,71, 55, 0,19, 52, 4, 1.0);
Boss.gradient(220, 165,113, 154, 129,100, 56, 3, 1.0);
Boss.gradient(219, 195,0, 11, 7,0, 59, 5, 1.0);
Boss.gradient(255, 243,211, 255, 243,211, 64, 1, 1.0);
Boss.gradient(219, 207,175, 11, 7,7, 65, 7, 1.0);
Boss.gradient(211, 231,255, 211, 231,255, 72, 1, 1.0);
Boss.gradient(171, 195,219, 107, 127,155, 73, 3, 1.0);
Boss.gradient(75, 95,119, 7, 7,11, 76, 4, 1.0);
Boss.gradient(0, 255,195, 0, 11,7, 80, 8, 1.0);
Boss.gradient(231, 119,255, 11, 0,7, 88, 8, 1.0);
Boss.gradient(230, 200, 80, 30, 20, 0, 96, 16, 1.0);//metal platforms
Boss.gradient(255, 77, 77, 154, 17, 17, 112, 8, 1.0);//wire and carrot bump
Boss.gradient(129, 9, 9, 0, 0, 0, 120, 8, 1.0);//wire and carrot bump
Boss.gradient(200, 120, 0, 20, 0, 0, 128, 16, 1.0);//wood
Boss.gradient(210, 165, 140, 190, 152, 130, 144, 2, 1.0);
Boss.gradient(255, 150, 20, 25, 5, 0, 146, 14, 1.0);//windows on pipes, lamps
Boss.gradient(180, 180, 120, 20, 20, 0, 160, 16, 1.0);//board
Boss.gradient(100, 40, 0, 0, 0, 20, 176, 16, 1.0);//background
Boss.gradient(70, 40, 20, 0, 0, 0, 192, 16, 1.0);//background wall
Boss.gradient(170, 140, 120, 30, 10, 0, 225, 16, 1.0);//wall
//Boss.apply();
}
void onMain(){
//if (devanisdefeated = false)
//{jjAlert("jjGameTicks "+ formatInt(jjGameTicks, "1"));}
if (jjLocalPlayers[0].bossActivated) {
d++;}
if (b<=99 && final && (jjGameTicks % 5) == 0) {
b++;
jjPalette.reset();
jjPalette.copyFrom(
1,
254,
1,
Boss,
b/100.0
);
jjPalette.apply();
}
else if (b==99) {
Boss.apply();
}
else if (b>=1) {
++elapsed;
if (devanisdefeated == false)
{doDevanBattle();
//jjAlert("jjGameTicks "+ formatInt(jjGameTicks, "1"));
}
}
updateGems();
//jjAlert("d "+ formatInt(d, "1"));
}
void onLevelReload() {
jjSetLayerYSpeed(5,0,true);
jjSetLayerYSpeed(6,0,true);
jjSetLayerYSpeed(7,0,true);
jjSetLayerYSpeed(8,0,true);
devanisdefeated = false;
final=false;
b=0;
jjPalette.reset();
}
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 MovingPlatform(jjOBJ@ plat) {
// jjDrawTile(plat.xPos - 31, plat.yPos - 14, 854);
//jjDrawTile(plat.xPos + 1, plat.yPos - 14, 855);
switch (plat.state){
case STATE::WAIT:
plat.state = STATE::FADEIN;
break;
case STATE::DEACTIVATE:
plat.xOrg = plat.xAcc;
plat.yOrg = plat.yAcc;
break;
case STATE::FADEIN:
if (plat.yOrg<100*32&&plat.xOrg>51*32&&plat.xOrg<53*32&&jjTriggers[2])
plat.yOrg = (82*32) + jjSin(++plat.counter*(1+0.2*jjDifficulty))*(16*32);
else if (plat.xOrg>60*32&&plat.xOrg<62*32&&plat.yOrg<100*32)
plat.yOrg = (88*32) + abs(jjSin(++plat.counter*(1+jjDifficulty))*(8*32));
else if (plat.xOrg>73*32&&plat.xOrg<75*32&&plat.yOrg<40*32)
plat.yOrg = (28*32) + (jjSin(++plat.counter*(1+jjDifficulty))*(8*32));
else if (plat.xOrg>65*32&&plat.xOrg<67*32&&plat.yOrg<100*32)
plat.yOrg = (85*32) + abs(jjSin(++plat.counter*(1.2+jjDifficulty))*(11*32));
else if (plat.xOrg>80*32&&plat.xOrg<82*32&&plat.yOrg<100*32)
plat.yOrg = (85*32) + abs(jjSin(++plat.counter*(1.2+jjDifficulty))*(11*32));
else if (plat.xOrg>85*32&&plat.xOrg<87*32&&plat.yOrg<100*32)
plat.yOrg = (88*32) + abs(jjSin(++plat.counter*(1+jjDifficulty))*(8*32));
if (plat.yOrg>117*32&&plat.yOrg<130*32)
plat.yOrg = (118*32) + abs(jjSin(++plat.counter*(1+jjDifficulty))*(10*32));
if (plat.xSpeed!=0||plat.ySpeed<0){
if (jjGameTicks%10==0)
{jjSample(plat.xOrg, plat.yOrg, SOUND::BUBBA_BUBBAEXPLO);}
}
break;
}
plat.behave(BEHAVIOR::PLATFORM, true);
}
void MovingSpikeboll(jjOBJ@ plat) {
// jjDrawTile(plat.xPos - 31, plat.yPos - 14, 854);
//jjDrawTile(plat.xPos + 1, plat.yPos - 14, 855);
switch (plat.state){
case STATE::WAIT:
plat.state = STATE::FADEIN;
break;
case STATE::DEACTIVATE:
plat.xOrg = plat.xAcc;
plat.yOrg = plat.yAcc;
break;
case STATE::FADEIN:
if (plat.xOrg>73*32&&plat.xOrg<75*32)
plat.yOrg = (120*32) - jjSin(++plat.counter*(1+0.2*jjDifficulty))*(10*32);
if (plat.xSpeed!=0||plat.ySpeed<0){
if (jjGameTicks%10==0)
{jjSample(plat.xOrg, plat.yOrg, SOUND::BUBBA_BUBBAEXPLO);}
}
break;
}
// plat.behave(BEHAVIOR::SPIKEBOLL, true);
}
void TufturtleRic (jjOBJ@ enemy) {
jjPLAYER@ play = jjLocalPlayers[0];
if (enemy.state == STATE::START) {
enemy.direction = enemy.xSpeed = 1;
enemy.counter = (jjRandom()&45) + 70;
enemy.state = STATE::WALK;
}
enemy.behave(BEHAVIOR::WALKINGENEMY);
}
void RisingPickup(jjOBJ@ pickup) {
pickup.yPos = pickup.yPos - 3*DEVANBACKGROUNDSPEED;
pickup.xSpeed = pickup.ySpeed = 0; //don't want anyone shooting it out of the way
if (pickup.eventID != OBJECT::FIVEHUNDREDBUMP && pickup.eventID != OBJECT::CARROTBUMP) {
pickup.behave(BEHAVIOR::PICKUP, true); //mostly just handles the drawing, since it's not allowed to have speeds
}
else if (pickup.eventID == OBJECT::FIVEHUNDREDBUMP || pickup.eventID == OBJECT::CARROTBUMP) {
pickup.behave(BEHAVIOR::BUMP, true);}
}
void doDevanBattle() {
jjSetLayerYSpeed(5,4,true);
jjSetLayerYSpeed(6,3,true);
jjSetLayerYSpeed(7,2,true);
jjSetLayerYSpeed(8,1,true);
//jjLayerYOffset[5] = elapsed * 2;
//jjLayerYOffset[6] = elapsed * 1.5;
//jjLayerYOffset[7] = elapsed;
//jjLayerYOffset[8] = elapsed;//not using auto speeds because we want to be able to reset this whole thing afterwards
if (elapsed & 63 == 0) {
jjOBJ@ obj = jjObjects[jjAddObject(OBJECT::FIVEHUNDREDBUMP, 35 * 32 + jjRandom()%(32*24), 307*32)];
obj.lightType = LIGHT::BRIGHT;
obj.light = 10;
obj.behavior = RisingPickup;
}
if (elapsed & 511 == 0) {
jjOBJ@ obj = jjObjects[jjAddObject(OBJECT::CARROTBUMP, 35 * 32 + jjRandom()%(32*24), 307*32)];
obj.lightType = LIGHT::BRIGHT;
obj.light = 10;
obj.behavior = RisingPickup;
}
if (elapsed & 511 == 0) {
jjOBJ@ obj = jjObjects[jjAddObject(OBJECT::SPARK, 35 * 32 + jjRandom()%(32*24), 307*32)];
//obj.lightType = LIGHT::BRIGHT;
//obj.light = 10;
//obj.behavior = SPARK;
}
if (elapsed & 63 == 0) {
jjOBJ@ obj = jjObjects[jjAddObject(devanGoodies[jjRandom()%devanGoodies.length], 35 * 32 + jjRandom()%(32*24), 307*32)];
if (obj.eventID == OBJECT::APPLE) {
obj.determineCurAnim(ANIM::ROBOT,0); //The robot boss's spike ball.
obj.playerHandling = HANDLING::ENEMY; //hurts (one heart) to the touch, and bullets may potentially collide with it
obj.energy = 0; //undestroyable by bullets... could still be destroyed by buttstomps, but the player is flying, so that's not an issue
}
obj.lightType = LIGHT::BRIGHT;
obj.light = 10;
obj.behavior = RisingPickup; //see below
}
}
void DevanBoss(jjOBJ@ devan) {
jjPLAYER@ play = jjLocalPlayers[0];
if ( devan.energy==0)
play.cameraFreeze(36*32 + 320 - (jjResolutionWidth >> 1) + play.subscreenX, 289*32 + 240 - (jjResolutionHeight >> 1) + play.subscreenY, false, true);
{ devan.counter==0;
devan.counter += 1;
if (devan.energy==0&&++devan.counter>210)
{ //play.cameraFreeze(36*32 + 320 - (jjResolutionWidth >> 1) + play.subscreenX, 289*32 + 240 - (jjResolutionHeight >> 1) + play.subscreenY, false, true);
//jjEventSet(play.xPos / 32, play.yPos / 32, AREA::EOL);
jjTriggers[30]=true;
//play.cameraUnfreeze();
jjLocalPlayers[0].fly = FLIGHT::NONE;
devanisdefeated = true;
//play.showText("@@Don't you think you've defeated me?@See you in HELL!");
//if (++devan.counter>500)
//{play.cameraUnfreeze();}
//if (++devan.counter>450)
//{play.warpToID(29,true);}
}
}
if (d==1)
{devan.state == STATE::START;}
if (devan.energy <= 0 && devan.state != STATE::DONE) { //shot 100+ times; time to go flying away
devan.bulletHandling = HANDLING::IGNOREBULLET; //no more collisions
devan.playerHandling = HANDLING::EXPLOSION; //
devan.state = STATE::DONE;
devan.determineCurAnim(ANIM::DEVAN, 4); //rotating
devan.ySpeed = -5;
devan.xSpeed = -3 * devan.direction;
jjLocalPlayers[0].activateBoss(false);
jjLocalPlayers[0].boss = 0;
}
switch(devan.state) {
case STATE::DEACTIVATE:
//jjEventSet(play.xPos / 32, play.yPos / 32, AREA::EOL);
devan.delete(); //the xOrg and yOrg properties have changed at this point, so .deactivate() wouldn't be safe
jjParameterSet(52, 290, -1, 1, 0); //object no longer exists, so JJ2 will create it again next time it's wanted
return;
case STATE::START:
if (jjLocalPlayers[0].bossActivated) {
jjLocalPlayers[0].boss = devan.objectID;
devan.determineCurAnim(ANIM::BOSS, 0, false);
//There are no actual boss events in the level, so JJ2 doesn't know
//that it needs to load the sprites for the boss health meter.
devan.state = STATE::FLOAT;
devan.determineCurAnim(ANIM::DEVAN, 3); devan.var[1] = 6; devan.animSpeed = 15;
devan.noHit = 16;
//no break, so fall through to case STATE::FLOAT
} else return; //JJ2's real boss behaviors tend to switch to STATE::DELAYEDSTART
//immediately and do the waiting for some player to have .bossActivated
//equal true from there, but there's no harm in sticking with STATE::START
//if there aren't any properties that need to be set in it
case STATE::FLOAT:
{
int nearestPlayerID = devan.findNearestPlayer(512*512); //measures in square pixels
if (nearestPlayerID >= 0) //negative number means no players exist within that range
devan.direction = (devan.xPos > jjPlayers[nearestPlayerID].xPos) ? -1 : 1; //face you!
}
devan.yPos = devan.yOrg + jjSin(jjGameTicks*4)*10;
//Float up and down a little, try to make it look like it's falling.
if (++devan.counterEnd == 35) { //If Devan is idling, which is the whole point of STATE::FLOAT,
devan.counterEnd = 0; //every half second he randomly does something else! Sometimes
//that something else is nothing; sometimes it's shooting a bullet;
//other times he changes his state (state) to something else
//entirely and doesn't return to STATE::FLOAT for a while.
jjOBJ@ bullet;
switch(jjRandom()&31) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: //do nothing
break;
case 10: case 11: case 12: //fall up
devan.state = STATE::BOUNCE;
devan.var[0] = 1; //Call randomizeDevanTarget() once done bouncing.
devan.yOrg = 284*32; //Target yPos.
break;
case 13: case 14: case 15: //fall down
devan.state = STATE::FALL;
devan.var[0] = 1; //Call randomizeDevanTarget() once done falling.
devan.yOrg = 306*32; //Target yPos.
break;
case 16: case 17: case 18: case 19: //teleport
devan.state = STATE::FADEOUT;
jjSample(devan.xPos, devan.yPos, SOUND::COMMON_TELPORT1, 0, 0);
devan.determineCurAnim(ANIM::DEVAN, 2); devan.var[1] = 7; devan.animSpeed = 7;
devan.bulletHandling = HANDLING::IGNOREBULLET;
devan.frameID = 0;
break;
default: //shoot
@bullet = jjObjects[jjAddObject(OBJECT::BLASTERBULLETPU, devan.xPos, devan.yPos, devan.objectID, CREATOR::OBJECT)]; //BLASTERBULLET would work as well, but this saves us the labor of setting .animSpeed (damage dealt) to 2 manually
jjSample(devan.xPos, devan.yPos, SOUND::AMMO_FIREGUN1A);
bullet.determineCurAnim(ANIM::DEVAN, 0);
bullet.playerHandling = HANDLING::ENEMYBULLET;
bullet.xSpeed = devan.direction * 4.5;
bullet.counterEnd += 10; //lasts longer
break;
}
}
break;
case STATE::FADEOUT: //warp away
if (devan.frameID == 6) {
devan.state = STATE::FADEIN;
jjSample(devan.xPos, devan.yPos, SOUND::COMMON_TELPORT2, 0, 0);
devan.determineCurAnim(ANIM::DEVAN, 5); devan.var[1] = 7; devan.animSpeed = 7;
devan.frameID = 0;
randomizeDevanTarget(devan);
devan.yPos = devan.yOrg;
}
break;
case STATE::FADEIN: //finish warping
if (devan.frameID == 6) {
devan.state = STATE::FLOAT;
devan.determineCurAnim(ANIM::DEVAN, 3); devan.var[1] = 6; devan.animSpeed = 15;
devan.noHit = 16;
devan.frameID = 0;
}
break;
case STATE::FALL: //move down
devan.direction = (devan.xPos > jjLocalPlayers[0].xPos) ? -1 : 1; //Always look towards player 1.
if (devan.yPos < devan.yOrg) {
devan.yPos = devan.yPos + devan.ySpeed;
} else if (devan.var[0] == 1) { //Just fell offscreen; now bounce back somewhere else!
devan.state = STATE::BOUNCE;
devan.var[0] = 0;
randomizeDevanTarget(devan);
} else {
devan.state = STATE::FLOAT;
}
break;
case STATE::BOUNCE: //move up
devan.direction = (devan.xPos > jjLocalPlayers[0].xPos) ? -1 : 1; //Always look towards player 1.
if (devan.yPos > devan.yOrg) {
devan.yPos = devan.yPos - devan.ySpeed;
} else if (devan.var[0] == 1) { //Just bounced offscreen; now fall back somewhere else!
devan.state = STATE::FALL;
devan.var[0] = 0;
randomizeDevanTarget(devan);
} else {
devan.state = STATE::FLOAT;
}
break;
case STATE::FREEZE:
if (devan.freeze > 0) {
devan.draw();
devan.freeze -= 4;
}
if (devan.freeze < 4) {
devan.unfreeze(0);
devan.state = devan.oldState;
}
break;
case STATE::DONE: //defeated
//play.showText("@@Don't you think you've defeated me?@See you in HELL!");
if (devan.yPos < 306*32) { //still flying away
devan.xPos = devan.xPos + devan.xSpeed;
devan.yPos = devan.yPos + devan.ySpeed;
devan.ySpeed = devan.ySpeed + .1;
} else { //End the scene and set up the next one.
devan.deactivate(); //in case he's needed later
jjTriggers[0] = true;
//flags[fDevan] = false;
if (jjPlayerCount > 1 || jjGameMode != GAME::SP) { //No boat scene for cooperative play, just wouldn't work
jjLocalPlayers[0].fly = FLIGHT::NONE;
jjNxt();
} else {
//flags[fBoat] = true;
//reachedCheckpoint = true;
jjTriggers[31] = false; //so the bridges don't trigger themselves again
//when revisited before they're even visible
for (int i = 1; i < jjObjectCount; ++i) {
jjOBJ@ obj = jjObjects[i];
if (obj.isActive && obj.eventID == OBJECT::BRIDGE)
obj.deactivate();
}
}
}
break;
}
if ((jjGameTicks & devan.animSpeed) == 0) ++devan.frameID;
devan.frameID %= devan.var[1];
devan.determineCurFrame();
devan.draw();
}
void randomizeDevanTarget(jjOBJ@ devan) { //Used whenever Devan warps away or has fallen/bounced offscreen and is ready to come back
devan.xPos = 35 * 32 + (jjRandom()%(32*23)) + 16;
devan.yOrg = 287 * 32 + (jjRandom()%(32*18)) + 16;
}
void onFunction15(jjPLAYER@ play) {
jjTriggers[15]=true;
}
void onFunction31(jjPLAYER@ play) {
play.showText("@@Hey, rodent! You know... @I hate the rabbitkind!");
jjTriggers[31]=true;
}
void onFunction1(jjPLAYER@ play) {
jjPalette.reset();
}
void onFunction2(jjPLAYER@ play) {
//play.activateBoss();
jjTriggers[19]=true;
jjLocalPlayers[0].bossActivated;
play.cameraFreeze(36*32 + 320 - (jjResolutionWidth >> 1) + play.subscreenX, 289*32 + 240 - (jjResolutionHeight >> 1) + play.subscreenY, false, true);
final=true;
}
void onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ play, int force) {
if (obj.eventID == OBJECT::FASTFEET) {
play.timerStart(2000/(jjDifficulty+1));
play.jumpStrength = play.jumpStrength - 8;
play.showText("@Heigth of jumps @ temporarily increased!", STRING::SMALL);
obj.behavior = BEHAVIOR::EXPLOSION2; //this is ESSENTIAL. just like enemies die by getting their states set to STATE::KILL, and bullets die by getting their states set to STATE::EXPLODE, pickups die by getting their behavior set to BEHAVIOR::EXPLOSION2. yes, sometimes a little consistency is in fact too much to ask for.
obj.scriptedCollisions = false; //or obj.playerHandling = HANDLING::EXPLOSION; or something like that
obj.frameID = 0;
jjSample(obj.xPos, obj.yPos, SOUND::BUBBA_BUBBABOUNCE2);
}
else if (obj.eventID == OBJECT::SKELETON){
if (obj.energy <= 0) {
if (bullet !is null) {
if ((bullet.var[6] & 2) == 2) { //toaster and its ilk
obj.particlePixelExplosion(1); //burny explosion
jjSample(obj.xPos, obj.yPos, SOUND::COMMON_BURN);
} else {
obj.particlePixelExplosion(0);
}
obj.grantPickup(play, (bullet.eventID == OBJECT::BLASTERBULLET) ? 5 : 10);
//JJ2 only ever calls grantPickup for enemies/crates destroyed
//by bullets, but you can branch out a bit if you like
} else {
obj.particlePixelExplosion(2); //killed by physical contact
jjSample(obj.xPos, obj.yPos, SOUND::COMMON_SPLAT1);
}
obj.state = STATE::KILL; //let the object's behavior function take care of deleting it
play.score=play.score+600;
jjPARTICLE@ particle = jjAddParticle(PARTICLE::STRING);
if (particle !is null) {
particle.xPos = obj.xPos;
particle.yPos = obj.yPos;
particle.string.text = "600";
particle.ySpeed = -1.2;
particle.xSpeed = -1.1;
}
}
if (force == 0)
{play.hurt();}
else if (bullet.direction == obj.direction) {
bullet.ricochet();
//obj.bulletHandling = HANDLING::DESTROYBULLET;
obj.energy += 1;
}
else {
//play.showText("It works!", STRING::SMALL);
obj.energy -= 1;
obj.justHit = 5;
bullet.delete();
}
}
}
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.