Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Holiday Hare '18 | SmokeNC | Single player | 8.9 |
#pragma require "HH18E1.j2a"
#include "HH18savegems.asc"
/*Ice Knight by Smoke , made for HappyGreenFrog's HH18 level. sprites ripped by Rasgar */
const int _jjDifficulty = 4 - jjDifficulty;
bool FreezeInput = false;
const array<int> KnightHP={-5,26,26,26};
namespace SMOKE {
jjOBJ @ ICEKNIGHT(uint8 eventID, int minX = 0, int maxX = 4, int minY = 6, int maxY = 12, int jumpDelay = 35, int minDistance = 224, int hp = 3) {
//Kangaroo::Private::loadAnims();
jjAnimSets[ANIM::CUSTOM[27]].load(12, "HH18E1.j2a");
jjAnimSets[ANIM::CUSTOM[17]].load(8, "HH18E1.j2a");
jjOBJ @ preset = jjObjectPresets[eventID];
preset.behavior = IceKnight();
preset.playerHandling = HANDLING::SPECIAL;
preset.bulletHandling = HANDLING::DETECTBULLET;
preset.causesRicochet = false;
preset.isBlastable = false;
preset.triggersTNT = false;
preset.isFreezable = true;
preset.isTarget = true;
preset.scriptedCollisions = true;
preset.direction = 1;
preset.freeze = 0;
preset.frameID = 0;
preset.determineCurFrame();
preset.determineCurAnim(ANIM::CUSTOM[27], 1);
preset.deactivates = false;
preset.energy = 100+KnightHP[jjDifficulty];
preset.points = 200;
preset.yAcc = 0.3;
preset.counter = 0;
int height = jjAnimFrames[jjAnimations[jjAnimSets[ANIM::CUSTOM[27]].firstAnim + 0].firstFrame + 0].height;
int hotY = jjAnimFrames[jjAnimations[jjAnimSets[ANIM::CUSTOM[27]].firstAnim + 0].firstFrame + 0].hotSpotY;
jjAnimFrames[jjAnimations[jjAnimSets[ANIM::CUSTOM[27]].firstAnim + 4].firstFrame + 0].hotSpotY += 40;
jjAnimFrames[jjAnimations[jjAnimSets[ANIM::CUSTOM[27]].firstAnim + 4].firstFrame + 0].coldSpotY += 40;
int distanceFromGround = height + hotY;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < jjAnimations[jjAnimSets[ANIM::CUSTOM[27]].firstAnim + i].frameCount; j++) {
jjANIMFRAME @ frame = jjAnimFrames[jjAnimations[jjAnimSets[ANIM::CUSTOM[27]].firstAnim + i].firstFrame + j];
frame.hotSpotY = -(frame.height - distanceFromGround);
}
}
return preset;
}
bool GravityField(jjOBJ @ obj) {
bool airborne = false;
int width = jjAnimFrames[obj.curFrame].width;
int height = jjAnimFrames[obj.curFrame].height;
int hotY = jjAnimFrames[obj.curFrame].hotSpotY;
int newXPos = int(obj.xPos + obj.xSpeed) + (width * obj.direction) / 2;
int newYPos = int(obj.yPos - obj.ySpeed);
//Check horizontal collision, flip horizontal speed if hit barrier
if ((newXPos < 0) || (newXPos > jjLayerWidth[4] * 32) || jjMaskedVLine(newXPos, int(obj.yPos + hotY), height - 8)) {
obj.xSpeed = -obj.xSpeed;
if (obj.xSpeed != 0)
obj.direction = -obj.direction;
}
//move horizontally
obj.xPos += obj.xSpeed;
//update horizonal speed
obj.xSpeed+=obj.xAcc;
//Check ceiling collision, set vertical speed to 0 if going to hit
if ((newYPos < 0) || jjMaskedHLine(int(obj.xPos) - 20 / 2, 20, newYPos + hotY))
obj.ySpeed = 0;
//Move vertically
obj.yPos -= obj.ySpeed;
//Check ground collision, if airborne start accelerating
if ((newYPos > jjLayerHeight[4] * 32) || jjMaskedHLine(int(obj.xPos) - 20 / 2, 20, newYPos + height + hotY - 3 * obj.ySpeed)) {
//obj on ground
airborne = false;
obj.ySpeed = 0;
} else { //obj airborne
airborne = true;
}
obj.determineCurFrame();
if (airborne == false) { //if object is on ground / landed
//obj.frameID = 0;
//obj.yPos -= 10;
putEnemyOnGround(obj);
// jjPrint("speed: "+obj.ySpeed+" acc: "+ obj.yAcc+" special: " +obj.special+" totalacc :"+obj.special * obj.yAcc);
return true;
}
if (airborne == true)
obj.ySpeed -= obj.yAcc; //update vertical speed
// jjPrint("speed: "+obj.ySpeed+" acc: "+ obj.yAcc+" special: " +obj.special+" totalacc :"+obj.special * obj.yAcc);
return false;
}
class IceKnight: jjBEHAVIORINTERFACE {
bool done = false;
void onBehave(jjOBJ @ obj) {
float X = jjLocalPlayers[0].xPos - obj.xPos;
float Y = jjLocalPlayers[0].yPos - obj.yPos;
// const int width = obj.var[kvWIDTH];
// const int height = obj.var[kvHEIGHT];
switch (obj.state) {
case STATE::START:
{
jjMusicLoad("TheIncredibleMachine3_Progressive.ogg");
obj.frameID = 0;
obj.counter = 0;
obj.energy = 0;
obj.determineCurFrame();
obj.state = STATE::STILL;
putEnemyOnGround(obj);
liftEnemyFromGround(obj);
obj.direction = -1;
// obj.xSpeed = 0.01 * obj.direction;
jjLocalPlayers[0].boss = obj.objectID;
jjLocalPlayers[0].activateBoss();
FreezeInput = true;
}
break;
case STATE::STILL:
{
if(obj.counter==1)
jjAlert("The Jailer: You will pay for this!", false, STRING::SMALL);
if(obj.counter==135)
jjAlert("Defeat The Jailer", false, STRING::MEDIUM);
obj.counter++;
if (obj.counter % 3 == 0)
obj.energy++;
if (obj.energy > 100+KnightHP[jjDifficulty]) {
FreezeInput = false;
obj.state = STATE::IDLE;
obj.counter = 100;
}
}
break;
case STATE::IDLE:
obj.yAcc = 0.3;
//obj.direction = (obj.xPos >= jjLocalPlayers[0].xPos) ? -1 : 1;
obj.frameID = int((jjGameTicks / 7) % 2);
if (obj.counter == -30+7*jjDifficulty || --obj.counter == -30+7*jjDifficulty ) {
RandomKnightAttack(obj);
//jjSample(obj.xPos, obj.yPos, ((jjRandom() & 1) == 0) ? SOUND::BUBBA_BUBBABOUNCE1 : SOUND::BUBBA_BUBBABOUNCE2);
}
obj.determineCurFrame();
if (obj.state == STATE::IDLE)
GravityField(obj);
break;
case STATE::DUCK:
{
obj.age++;obj.determineCurAnim(ANIM::CUSTOM[27], 2);
if (obj.frameID != 6) obj.frameID = int((obj.age / 7) % 7);
if (obj.age > 8 * 7 && obj.ySpeed == 0) {
/* if(jjDifficulty>1)
{
// obj.yAcc = 0;
obj.xAcc = 0;
obj.direction = X / abs(X);
obj.state = STATE::BOUNCE;
obj.xSpeed = (7) * X / sqrt(X * X + Y * Y);
obj.ySpeed = -7 * Y / sqrt(X * X + Y * Y);
obj.age = 0;
jjSamplePriority(SOUND::INTRO_SWISH3);
}
else*/ {
obj.determineCurAnim(ANIM::CUSTOM[27], 0);
obj.direction = (obj.xPos < jjLocalPlayers[0].xPos) ? 1 : -1;
obj.age = 0;
obj.state = STATE::IDLE;
obj.xSpeed = obj.direction;
obj.ySpeed = 0;
obj.counter = 100;
}
}
GravityField(obj);
break;
}
case STATE::PUSH:
{
obj.age++;obj.determineCurAnim(ANIM::CUSTOM[27], 2);
if(abs(obj.xSpeed)<7)
{
if(obj.ySpeed==0)
obj.xAcc=(0.2+0.05*jjDifficulty)*obj.direction;
else
obj.xAcc=(0.1+0.05*jjDifficulty)*obj.direction;
}
else obj.xAcc=0;
if (obj.frameID != 6) obj.frameID = int((obj.age / 7) % 7);
if (obj.age%5==0) {
int bulletID3 = jjAddObject(OBJECT::TOASTERBULLET, obj.xPos - obj.direction * 32, obj.yPos, obj.objectID, CREATOR::OBJECT);
jjOBJ @ o = jjObjects[bulletID3];
o.behavior = IceCloud;
o.direction = obj.direction;
o.xSpeed = 0;
o.ySpeed = 0;
o.curAnim = o.determineCurAnim(ANIM::AMMO, 82, true);
o.frameID=5;
o.determineCurFrame();
o.counterEnd=20;
o.freeze = 210;
o.playerHandling = HANDLING::ENEMYBULLET;
}
if (obj.age > (14+jjDifficulty) * 7 && obj.ySpeed == 0) {
obj.determineCurAnim(ANIM::CUSTOM[27], 0);
obj.direction = (obj.xPos < jjLocalPlayers[0].xPos) ? 1 : -1;
obj.age = 0;
obj.xAcc=0;
obj.state = STATE::IDLE;
obj.xSpeed = obj.direction;
obj.ySpeed = 0;
obj.counter = 100;
}
GravityField(obj);
break;
}
case STATE::FIRE:
{
GravityField(obj);
//jjPrint("speed: "+obj.ySpeed+" acc: "+ obj.yAcc+" special: " +obj.special+" totalacc :"+obj.special * obj.yAcc);
obj.ySpeed = 0;
obj.determineCurAnim(ANIM::CUSTOM[27], 2);
obj.age++;
Frame(obj);
if (CurrFrame(obj, 3) == true || CurrFrame(obj, 9) == true || (CurrFrame(obj, 15) == true &&jjDifficulty>0)) { //Fire IceWolf
int bulletID2 = jjAddObject(OBJECT::BLASTERBULLET, obj.xPos + obj.direction * 20, obj.yPos);
jjOBJ @ bull2 = jjObjects[bulletID2];
bull2.determineCurAnim(ANIM::CUSTOM[27], 5);
bull2.behavior = SMOKE::IceWolf;
bull2.counterEnd = 70;
bull2.killAnim = jjObjectPresets[OBJECT::ICEBULLET].killAnim;
// bull2.xSpeed = obj.direction * 4;
bull2.xSpeed = obj.direction * abs(X) / 38 + jjDifficulty * obj.direction;
bull2.ySpeed = -1.5;
bull2.yAcc = 0;
bull2.xAcc = 0;
// bull2.yAcc=-0.1;
bull2.playerHandling = HANDLING::ENEMYBULLET;
jjSamplePriority(SOUND::AMMO_ICEGUNPU);
jjSamplePriority(SOUND::DOG_AGRESSIV);
if(CurrFrame(obj, 15) == true && jjDifficulty>1)
{
int bulletID2 = jjAddObject(OBJECT::BLASTERBULLET, obj.xPos + obj.direction * 20, obj.yPos);
jjOBJ @ bull2 = jjObjects[bulletID2];
bull2.determineCurAnim(ANIM::CUSTOM[27], 5);
bull2.behavior = SMOKE::IceWolf;
bull2.counterEnd = 220;
bull2.killAnim = jjObjectPresets[OBJECT::ICEBULLET].killAnim;
// bull2.xSpeed = obj.direction * 4;
bull2.xSpeed = (3-obj.counter*0.5)*obj.direction;
bull2.ySpeed = -9;
bull2.yAcc = 0;
bull2.xAcc = 0;
// bull2.yAcc=-0.1;
bull2.playerHandling = HANDLING::ENEMYBULLET;
jjSamplePriority(SOUND::AMMO_ICEGUNPU);
jjSamplePriority(SOUND::DOG_AGRESSIV);
obj.counter++;
}
}
if ((CurrFrame(obj,12)&&jjDifficulty==0)||CurrFrame(obj, 18) == true) {
obj.state = STATE::IDLE;
obj.age = 0;
obj.counter = 150;
obj.determineCurAnim(ANIM::CUSTOM[27], 1);
}
break;
}
case STATE::HIT:
{
obj.determineCurAnim(ANIM::CUSTOM[27], 2);
obj.age++;
Frame(obj);
if (CurrFrame(obj, 3) == true || CurrFrame(obj, 9) == true || (CurrFrame(obj, 15) == true && jjDifficulty>1)) { //Fire IceWolf
int bulletID2 = jjAddObject(OBJECT::BOUNCERBULLET, obj.xPos + 50 * obj.direction, obj.yPos);
jjOBJ @ bull2 = jjObjects[bulletID2];
bull2.determineCurAnim(ANIM::CUSTOM[17], 2);
bull2.counterEnd = 150+10*jjDifficulty;
bull2.behavior = SMOKE::KnightSpikeBall;
// bull2.xSpeed = obj.direction * 4;
bull2.xSpeed = 4 * obj.direction;
bull2.ySpeed = 0;
bull2.yAcc = 0;
bull2.xAcc = 0;
// bull2.yAcc=-0.1;
bull2.playerHandling = HANDLING::ENEMYBULLET;
jjSamplePriority(SOUND::AMMO_ICEGUNPU);
}
if (CurrFrame(obj, 6) == true) {
if(jjDifficulty<=1)
{
obj.state = STATE::IDLE;
obj.ySpeed=0;
obj.yAcc=0;
obj.age = 0;
obj.counter = 150;
obj.determineCurAnim(ANIM::CUSTOM[27], 1);
}
else
{
obj.age = 0;
obj.yAcc = 0.3;
obj.xSpeed = (7 + jjDifficulty) * obj.direction;
obj.ySpeed = 9;
obj.determineCurAnim(ANIM::CUSTOM[27], 2);
obj.state = STATE::DUCK;
jjSamplePriority(SOUND::INTRO_SWISH3);
}
}
GravityField(obj);
break;
}
case STATE::ACTION:
obj.age++;
obj.determineCurAnim(ANIM::CUSTOM[27], 3);
if (obj.frameID != 6) obj.frameID = int((obj.age / 7) % 7);
if (abs(obj.ySpeed) < 2) {
// jjPrint("lol");
obj.counter--;
obj.yAcc = 0;
obj.xAcc = 0;
obj.direction = X / abs(X);
obj.state = STATE::BOUNCE;
obj.xSpeed = (9+jjDifficulty) * X / sqrt(X * X + Y * Y);
obj.ySpeed = -10 * Y / sqrt(X * X + Y * Y);
obj.age = 0;
jjSamplePriority(SOUND::INTRO_SWISH3);
}
GravityField(obj);
break;
case STATE::BOUNCE:
//jjPrint("lol");
obj.age++;
obj.determineCurAnim(ANIM::CUSTOM[27], 2);
if (obj.frameID != 6) obj.frameID = int((obj.age / 7) % 7);
if (obj.age%5==0) {
int bulletID3 = jjAddObject(OBJECT::TOASTERBULLET, obj.xPos - obj.direction * 32, obj.yPos, obj.objectID, CREATOR::OBJECT);
jjOBJ @ o = jjObjects[bulletID3];
o.behavior = IceCloud;
o.direction = obj.direction;
o.xSpeed = 0;
o.ySpeed = 0;
o.curAnim = o.determineCurAnim(ANIM::AMMO, 82, true);
o.frameID=5;
o.determineCurFrame();
o.counterEnd=20;
o.freeze = 210;
o.playerHandling = HANDLING::ENEMYBULLET;
}
if (CurrFrame(obj, 6) == true) {
//jjPrint("lol");
obj.determineCurAnim(ANIM::CUSTOM[27], 0);
obj.direction = (obj.xPos < jjLocalPlayers[0].xPos) ? 1 : -1;
obj.age = 0;
obj.state = STATE::IDLE;
obj.xSpeed = obj.direction;
obj.ySpeed = 0;
obj.counter = 100;
obj.yAcc = 0.3;
}
GravityField(obj);
break;
case STATE::FREEZE:
if (obj.freeze > 0)
--obj.freeze;
if (obj.freeze <= 0) {
obj.state = obj.oldState;
obj.unfreeze(0);
}
break;
case STATE::DEACTIVATE:
obj.deactivate();
break;
case STATE::KILL:
obj.counter = 0;
obj.state = STATE::DONE;
obj.determineCurAnim(ANIM::CUSTOM[27], 4);
// obj.delete();
break;
case STATE::DONE:
obj.xSpeed = 0;
obj.determineCurAnim(ANIM::CUSTOM[27], 4);
obj.frameID = 0;
obj.determineCurFrame();
obj.counter++;
if(obj.counter==80)
jjAlert("The Jailer:", false, STRING::MEDIUM);
if(obj.counter==300)
jjAlert("You may have defeated me...", false, STRING::MEDIUM);
if(obj.counter==530)
jjAlert("But your journey won't last long...", false, STRING::MEDIUM);
if (obj.counter == 820) {
obj.particlePixelExplosion(31); //loops for scrubs
obj.particlePixelExplosion(31);
obj.particlePixelExplosion(31);
obj.particlePixelExplosion(31);
obj.particlePixelExplosion(31);
obj.particlePixelExplosion(31);
obj.delete();
gem::saveGemData();
jjNxt();
}
GravityField(obj);
break;
default:
obj.draw();
break;
}
obj.draw();
}
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 (obj.energy <= 0 && done==false && obj.state != STATE::START && obj.state != STATE::STILL) { //killed
done=true;
obj.counter = 0;
obj.xSpeed = 0;
obj.ySpeed = 0;
obj.yAcc = 0.3;
obj.state = STATE::DONE;
obj.determineCurAnim(ANIM::CUSTOM[27], 4);
obj.frameID = 0;
obj.bulletHandling = HANDLING::IGNOREBULLET;
return true;
//obj.particlePixelExplosion(2);
}
if(done==true)
return true;
else 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::KILL;
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
player.hurt(); //constant amount of damage for special attacks
if (obj.energy <= 0) { //killed
obj.energy = 0;
obj.state = STATE::KILL;
} /*else { //only wounded
obj.justHit = 5;
}*/
if (obj.freeze > 0) {
obj.unfreeze(1);
}
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;
}
}
void KnightSpikeBall(jjOBJ @ obj) {
obj.behave(BEHAVIOR::BOUNCERBULLET, true);
if (obj.state == STATE::EXPLODE && obj.isActive) {
obj.unfreeze(1);
obj.delete();
}
}
void IceWolf(jjOBJ @ obj) {
float X = jjLocalPlayers[0].xPos - obj.xPos;
float Y = jjLocalPlayers[0].yPos - obj.yPos;
if (obj.state == STATE::EXPLODE && obj.isActive) {
// obj.particlePixelExplosion(31);
obj.xPos-=5*obj.xSpeed;
obj.yPos-=5*obj.ySpeed;
obj.unfreeze(1);
obj.delete();
}
obj.behave(BEHAVIOR::BULLET, true);
obj.xAcc=(obj.xSpeed*obj.xAcc>0 ? 0.1 : 0.3 )*X/abs(X);
obj.yAcc = (obj.ySpeed*obj.yAcc>0 ? 0.1 : 0.3 ) * Y / abs(Y);
}
void Icicle(jjOBJ @ obj) {
if (obj.state == STATE::EXPLODE && obj.isActive) {
//obj.xPos-=8*obj.xSpeed;
//obj.yPos-=8*obj.ySpeed;
obj.unfreeze(1);
obj.delete();
}
//obj.frameID=3;
obj.behave(BEHAVIOR::BULLET, true);
if (obj.counter == 7 * 2) {
obj.determineCurAnim(ANIM::CUSTOM[27], 7);
obj.frameID = 0;
obj.determineCurFrame();
}
if (obj.counter == 7 * 3)
obj.xAcc = 0.15 * obj.xSpeed / abs(obj.xSpeed);
int width = jjAnimFrames[obj.curFrame].width;
int height = jjAnimFrames[obj.curFrame].height;
int hotY = jjAnimFrames[obj.curFrame].hotSpotY;
int newXPos = int(obj.xPos + obj.xSpeed) + (width * obj.direction) / 2;
//Check horizonal collision
if ((newXPos < 0) || (newXPos > jjLayerWidth[4] * 32) || jjMaskedVLine(newXPos, int(obj.yPos + hotY), height - 8)) {
obj.state = STATE::EXPLODE;
}
}
}
void Frame(jjOBJ @ obj) {
obj.frameID = int((obj.age / 7) % (jjAnimations[obj.curAnim].frameCount));
obj.determineCurFrame();
}
bool CurrFrame(jjOBJ @ obj, int id) {
return obj.age == 7 * id + 6;
}
void RandomKnightAttack(jjOBJ @ obj,int attack=(jjRandom()%4)) {
int rand = jjRandom() % 4;
obj.direction = (obj.xPos < jjLocalPlayers[0].xPos) ? 1 : -1;
switch (attack%4) {
case 0:
obj.yAcc = 0.3;
obj.xSpeed = 0*(4 + jjDifficulty) * obj.direction;
obj.ySpeed = jjDifficulty==0 ? 0 : (jjRandom()%2)*10;
obj.determineCurAnim(ANIM::CUSTOM[27], 2);
obj.state = STATE::PUSH;
jjSamplePriority(SOUND::INTRO_SWISH3);
break;
case 1:
obj.determineCurAnim(ANIM::CUSTOM[27], 2);
obj.xSpeed = 0;
obj.ySpeed = 0;
obj.state = STATE::FIRE;
break;
case 2:
obj.determineCurAnim(ANIM::CUSTOM[27], 2);
obj.xSpeed = 0;
obj.ySpeed = 10;
obj.state = STATE::HIT;
break;
case 3:
obj.determineCurAnim(ANIM::CUSTOM[27], 3);
obj.xSpeed = 0;
obj.ySpeed = 10;
obj.state = STATE::ACTION;
break;
}
obj.frameID = 0;
//jjPrint("State: " +obj.state);
obj.age = obj.counter = 0;
}
void IceCloud(jjOBJ @ obj) {
obj.behave(BEHAVIOR::TOASTERBULLET, true);
int playerID = obj.findNearestPlayer(30000);
if (obj.state == STATE::FLY && obj.doesCollide(jjPlayers[playerID], true)) {
jjPlayers[playerID].freeze(true);
jjPlayers[playerID].xSpeed -= (obj.xSpeed / (obj.direction == -1 ? 8 : -8)) * obj.direction;
}
}
void putEnemyOnGround(jjOBJ @ obj) {
int width = jjAnimFrames[obj.curFrame].width;
int height = jjAnimFrames[obj.curFrame].height;
int hotY = jjAnimFrames[obj.curFrame].hotSpotY;
while (!jjMaskedHLine(int(obj.xPos) - width / 2, width, int(obj.yPos) + height + hotY))
obj.yPos += 1;
}
void liftEnemyFromGround(jjOBJ @ obj) {
int width = jjAnimFrames[obj.curFrame].width;
int height = jjAnimFrames[obj.curFrame].height;
int hotY = jjAnimFrames[obj.curFrame].hotSpotY;
while (jjMaskedHLine(int(obj.xPos) - width / 2, width, int(obj.yPos) + height + hotY))
obj.yPos -= 1;
}
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.