Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Anniversary Bash 26 Battle | Jazz2Online | Battle | N/A | |||||
Anniversary Bash 25 Battle | Jazz2Online | Battle | N/A | |||||
Asteroid Armada | PurpleJazz | Battle | N/A | |||||
Spaceships (v1.01) | PurpleJazz | Custom / Concept | N/A |
#pragma require "Spaceship.j2a"
#pragma require "Spaceship v1-01.asc"
#pragma require "Silence.wav"
#include "Resize v11.asc"
#include "MLLE-Weapons.asc"
namespace Spaceship {
bool animsLoaded = false;
uint customAnimID = 0;
class SPACESHIP {
float xSpeed, ySpeed, xAcc, yAcc, xMomentum, yMomentum, fireAngle, momentum = 0;
float maxSpeed = 9.25;
float maxTurningSpeed = 7;
float maxSpeedRev = 6;
float maxTurningSpeedRev = 4.5;
float maxDiagonalSpeed = 8;
float rotationAcc = 0;
int health, anim, angle, rotationSpeed, sample, sample2, fireDelay, hitDelay, armor, damageAccumulated, accumulationTime;
int powerTime = 30*70;
int damageCalc(SPACESHIP@ ship, int animSpeed) {
if (ship.armor >= animSpeed) {
return (animSpeed / 3);
} else {
return (animSpeed - (ship.armor / 3 * 2));
}
}
bool thrust, reverse, rotating, preciseTurn, fire, justHit, wasHit, stopWeaponChange, powerUp, SDPunishment, tntPowerup = false;
bool hasShip = true;
SPACESHIP(){}
};
array<SPACESHIP> Ships(32);
const float PI = 3.1415926535f;
int xPos = 0, yPos = 0, cameraX = 0, cameraY = 0, radarX = 100, radarY = jjSubscreenHeight - 220;
array<int> closestPlayers(32, -1); //needed even for non-local players
uint8 currentWeapon = 1;
bool crosshairFlash = false;
int crosshairTime = 0;
bool gameIsActive() {
return jjGameState == GAME::STARTED || jjGameState == GAME::OVERTIME;
}
bool canBeHit(jjPLAYER@ play, jjPLAYER@ creator, jjOBJ@ obj) {
return play !is null && (play !is creator || obj.eventID == OBJECT::BULLET) && play.blink == 0 && play.health > 0 && creator.blink == 0 && obj.state != STATE::EXPLODE && (creator.isEnemy(play) || (play is creator && obj.eventID == OBJECT::BULLET)) && gameIsActive();
}
float recoilX(SPACESHIP@ ship, jjOBJ@ obj, float recoil) {
return ((obj.xSpeed / (ship.thrust? 16:128)) * recoil);
}
float recoilY(SPACESHIP@ ship, jjOBJ@ obj, float recoil) {
return ((obj.ySpeed / (ship.thrust? 16:128)) * recoil);
}
int teamColor(jjPLAYER@ play) {
if (play.team == TEAM::BLUE) return 32;
if (play.team == TEAM::RED) return 24;
if (play.team == TEAM::YELLOW) return 40;
if (play.team == TEAM::GREEN) return 16;
return 32;
}
bool isAlly(jjPLAYER@ creator, jjPLAYER@ play) {
return !creator.isLocal && jjGameMode == GAME::CTF && creator.team == play.team;
}
bool active = true;
int maxHealth;
bool showInstructions = false;
array<bool> pressOnce(3, false);
int currPage = 1;
void handleOnLevelLoad() {
if (!animsLoaded) {
animsLoaded = true;
while (jjAnimSets[ANIM::CUSTOM[customAnimID]] != 0)
++customAnimID;
customAnimID = ANIM::CUSTOM[customAnimID];
jjAnimSets[customAnimID].load(0, "Spaceship.j2a");
}
jjAnimSets[ANIM::DEVAN].load();
jjAnimSets[ANIM::MENU].load();
jjWeapons[WEAPON::BLASTER].infinite = false;
jjWeapons[WEAPON::BLASTER].maximum = 25;
jjWeapons[WEAPON::BLASTER].defaultSample = false;
jjObjectPresets[OBJECT::BLASTERBULLET].xSpeed = jjObjectPresets[OBJECT::BLASTERBULLET].xSpeed * -2.5;
jjObjectPresets[OBJECT::BLASTERBULLET].ySpeed = 0;
jjObjectPresets[OBJECT::BLASTERBULLET].xAcc = 0;
jjObjectPresets[OBJECT::BLASTERBULLET].yAcc = 0;
jjObjectPresets[OBJECT::BLASTERBULLET].counterEnd = 65;
jjObjectPresets[OBJECT::BLASTERBULLET].behavior = Blaster();
jjObjectPresets[OBJECT::BLASTERBULLET].special = jjObjectPresets[OBJECT::BLASTERBULLET].determineCurAnim(ANIM::DEVAN, 0);
jjObjectPresets[OBJECT::BLASTERBULLET].determineCurFrame();
jjObjectPresets[OBJECT::BLASTERBULLET].scriptedCollisions = true;
jjObjectPresets[OBJECT::BLASTERBULLET].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::BLASTERBULLET].animSpeed = 15;
jjObjectPresets[OBJECT::BLASTERBULLET].triggersTNT = true;
jjObjectPresets[OBJECT::BLASTERBULLETPU].xSpeed = jjObjectPresets[OBJECT::BLASTERBULLETPU].xSpeed * -2.5;
jjObjectPresets[OBJECT::BLASTERBULLETPU].ySpeed = 0;
jjObjectPresets[OBJECT::BLASTERBULLETPU].xAcc = 0;
jjObjectPresets[OBJECT::BLASTERBULLETPU].yAcc = 0;
jjObjectPresets[OBJECT::BLASTERBULLETPU].counterEnd = 65;
jjObjectPresets[OBJECT::BLASTERBULLETPU].behavior = Blaster();
jjObjectPresets[OBJECT::BLASTERBULLETPU].special = jjObjectPresets[OBJECT::BLASTERBULLETPU].determineCurAnim(ANIM::DEVAN, 0);
jjObjectPresets[OBJECT::BLASTERBULLETPU].determineCurFrame();
jjObjectPresets[OBJECT::BLASTERBULLETPU].scriptedCollisions = true;
jjObjectPresets[OBJECT::BLASTERBULLETPU].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::BLASTERBULLETPU].animSpeed = 30;
jjObjectPresets[OBJECT::BLASTERBULLETPU].triggersTNT = true;
jjWeapons[WEAPON::BOUNCER].maximum = 100;
jjWeapons[WEAPON::BOUNCER].defaultSample = false;
jjObjectPresets[OBJECT::BOUNCERBULLET].xSpeed = jjObjectPresets[OBJECT::BOUNCERBULLET].xSpeed * -3;
jjObjectPresets[OBJECT::BOUNCERBULLET].ySpeed = 0;
jjObjectPresets[OBJECT::BOUNCERBULLET].xAcc = 0;
jjObjectPresets[OBJECT::BOUNCERBULLET].yAcc = 0;
jjObjectPresets[OBJECT::BOUNCERBULLET].counterEnd = 70;
jjObjectPresets[OBJECT::BOUNCERBULLET].behavior = RapidBlaster();
jjObjectPresets[OBJECT::BOUNCERBULLET].special = jjObjectPresets[OBJECT::BOUNCERBULLET].determineCurAnim(ANIM::AMMO, 27);
jjObjectPresets[OBJECT::BOUNCERBULLET].determineCurFrame();
jjObjectPresets[OBJECT::BOUNCERBULLET].scriptedCollisions = true;
jjObjectPresets[OBJECT::BOUNCERBULLET].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::BOUNCERBULLET].animSpeed = 9;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].xSpeed = jjObjectPresets[OBJECT::BOUNCERBULLETPU].xSpeed * -3;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].ySpeed = 0;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].xAcc = 0;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].yAcc = 0;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].counterEnd = 70;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].behavior = RapidBlaster();
jjObjectPresets[OBJECT::BOUNCERBULLETPU].special = jjObjectPresets[OBJECT::BOUNCERBULLETPU].determineCurAnim(ANIM::AMMO, 60);
jjObjectPresets[OBJECT::BOUNCERBULLETPU].determineCurFrame();
jjObjectPresets[OBJECT::BOUNCERBULLETPU].scriptedCollisions = true;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::BOUNCERBULLETPU].animSpeed = 18;
jjWeapons[WEAPON::ICE].maximum = 25;
jjWeapons[WEAPON::ICE].defaultSample = false;
jjWeapons[WEAPON::ICE].spread = SPREAD::RFPU;
jjObjectPresets[OBJECT::ICEBULLET].xSpeed = jjObjectPresets[OBJECT::ICEBULLET].xSpeed * -3;
jjObjectPresets[OBJECT::ICEBULLET].ySpeed = 0;
jjObjectPresets[OBJECT::ICEBULLET].xAcc = 0;
jjObjectPresets[OBJECT::ICEBULLET].yAcc = 0;
jjObjectPresets[OBJECT::ICEBULLET].counterEnd = 30;
jjObjectPresets[OBJECT::ICEBULLET].freeze = 0;
jjObjectPresets[OBJECT::ICEBULLET].var[7] = 0;
jjObjectPresets[OBJECT::ICEBULLET].behavior = IceBurster();
jjObjectPresets[OBJECT::ICEBULLET].special = jjObjectPresets[OBJECT::ICEBULLET].determineCurAnim(ANIM::PICKUPS, 45);
jjObjectPresets[OBJECT::ICEBULLET].determineCurFrame();
jjObjectPresets[OBJECT::ICEBULLET].scriptedCollisions = true;
jjObjectPresets[OBJECT::ICEBULLET].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::ICEBULLET].animSpeed = 25;
jjObjectPresets[OBJECT::ICEBULLETPU].xSpeed = jjObjectPresets[OBJECT::ICEBULLETPU].xSpeed * -3;
jjObjectPresets[OBJECT::ICEBULLETPU].ySpeed = 0;
jjObjectPresets[OBJECT::ICEBULLETPU].xAcc = 0;
jjObjectPresets[OBJECT::ICEBULLETPU].yAcc = 0;
jjObjectPresets[OBJECT::ICEBULLETPU].counterEnd = 30;
jjObjectPresets[OBJECT::ICEBULLETPU].freeze = 0;
jjObjectPresets[OBJECT::ICEBULLETPU].var[7] = 0;
jjObjectPresets[OBJECT::ICEBULLETPU].behavior = IceBurster();
jjObjectPresets[OBJECT::ICEBULLETPU].special = jjObjectPresets[OBJECT::ICEBULLETPU].determineCurAnim(ANIM::PICKUPS, 45);
jjObjectPresets[OBJECT::ICEBULLETPU].determineCurFrame();
jjObjectPresets[OBJECT::ICEBULLETPU].scriptedCollisions = true;
jjObjectPresets[OBJECT::ICEBULLETPU].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::ICEBULLETPU].animSpeed = 50;
jjObjectPresets[OBJECT::ICEBULLETPU].killAnim = jjObjectPresets[OBJECT::RFBULLET].killAnim;
jjWeapons[WEAPON::SEEKER].maximum = 15;
jjObjectPresets[OBJECT::SEEKERBULLET].xSpeed = jjObjectPresets[OBJECT::SEEKERBULLET].xSpeed * -5;
jjObjectPresets[OBJECT::SEEKERBULLET].ySpeed = jjObjectPresets[OBJECT::SEEKERBULLET].ySpeed * 5;
jjObjectPresets[OBJECT::SEEKERBULLET].xAcc = 0;
jjObjectPresets[OBJECT::SEEKERBULLET].yAcc = 0;
jjObjectPresets[OBJECT::SEEKERBULLET].counterEnd = 160;
jjObjectPresets[OBJECT::SEEKERBULLET].lightType = jjObjectPresets[OBJECT::BLASTERBULLET].lightType;
jjObjectPresets[OBJECT::SEEKERBULLET].behavior = HomingMissile();
jjObjectPresets[OBJECT::SEEKERBULLET].special = jjObjectPresets[OBJECT::SEEKERBULLET].determineCurAnim(ANIM::AMMO, 37);
jjObjectPresets[OBJECT::SEEKERBULLET].determineCurFrame();
jjObjectPresets[OBJECT::SEEKERBULLET].killAnim = jjObjectPresets[OBJECT::SEEKERBULLET].killAnim;
jjObjectPresets[OBJECT::SEEKERBULLET].scriptedCollisions = true;
jjObjectPresets[OBJECT::SEEKERBULLET].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::SEEKERBULLET].animSpeed = 30;
jjObjectPresets[OBJECT::SEEKERBULLETPU].xSpeed = jjObjectPresets[OBJECT::SEEKERBULLETPU].xSpeed * -6;
jjObjectPresets[OBJECT::SEEKERBULLETPU].ySpeed = jjObjectPresets[OBJECT::SEEKERBULLETPU].ySpeed * 6;
jjObjectPresets[OBJECT::SEEKERBULLETPU].xAcc = 0;
jjObjectPresets[OBJECT::SEEKERBULLETPU].yAcc = 0;
jjObjectPresets[OBJECT::SEEKERBULLETPU].counterEnd = 180;
jjObjectPresets[OBJECT::SEEKERBULLETPU].lightType = jjObjectPresets[OBJECT::BLASTERBULLET].lightType;
jjObjectPresets[OBJECT::SEEKERBULLETPU].behavior = HomingMissile();
jjObjectPresets[OBJECT::SEEKERBULLETPU].special = jjObjectPresets[OBJECT::SEEKERBULLETPU].determineCurAnim(ANIM::AMMO, 42);
jjObjectPresets[OBJECT::SEEKERBULLETPU].determineCurFrame();
jjObjectPresets[OBJECT::SEEKERBULLETPU].killAnim = jjObjectPresets[OBJECT::SEEKERBULLETPU].killAnim;
jjObjectPresets[OBJECT::SEEKERBULLETPU].scriptedCollisions = true;
jjObjectPresets[OBJECT::SEEKERBULLETPU].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::SEEKERBULLETPU].animSpeed = 60;
jjWeapons[WEAPON::RF].maximum = 10;
jjWeapons[WEAPON::RF].spread = SPREAD::NORMAL;
jjWeapons[WEAPON::RF].defaultSample = false;
jjObjectPresets[OBJECT::RFBULLET].xSpeed = jjObjectPresets[OBJECT::RFBULLET].xSpeed * -10;
jjObjectPresets[OBJECT::RFBULLET].ySpeed = jjObjectPresets[OBJECT::RFBULLET].ySpeed * -10;
jjObjectPresets[OBJECT::RFBULLET].xAcc = 0;
jjObjectPresets[OBJECT::RFBULLET].yAcc = 0;
jjObjectPresets[OBJECT::RFBULLET].counterEnd = 180;
jjObjectPresets[OBJECT::RFBULLET].lightType = LIGHT::NONE;
jjObjectPresets[OBJECT::RFBULLET].behavior = SuperMissile();
jjObjectPresets[OBJECT::RFBULLET].special = jjObjectPresets[OBJECT::RFBULLET].determineCurAnim(ANIM::SONCSHIP, 0);
jjObjectPresets[OBJECT::RFBULLET].determineCurFrame();
jjObjectPresets[OBJECT::RFBULLET].killAnim = jjObjectPresets[OBJECT::SEEKERBULLET].killAnim;
jjObjectPresets[OBJECT::RFBULLET].scriptedCollisions = true;
jjObjectPresets[OBJECT::RFBULLET].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::RFBULLET].animSpeed = 100;
jjObjectPresets[OBJECT::RFBULLETPU].xSpeed = jjObjectPresets[OBJECT::RFBULLETPU].xSpeed * -10;
jjObjectPresets[OBJECT::RFBULLETPU].ySpeed = jjObjectPresets[OBJECT::RFBULLETPU].ySpeed * -10;
jjObjectPresets[OBJECT::RFBULLETPU].xAcc = 0;
jjObjectPresets[OBJECT::RFBULLETPU].yAcc = 0;
jjObjectPresets[OBJECT::RFBULLETPU].counterEnd = 180;
jjObjectPresets[OBJECT::RFBULLETPU].lightType = LIGHT::NONE;
jjObjectPresets[OBJECT::RFBULLETPU].behavior = SuperMissile();
jjObjectPresets[OBJECT::RFBULLETPU].special = jjObjectPresets[OBJECT::RFBULLETPU].determineCurAnim(ANIM::SONCSHIP, 0);
jjObjectPresets[OBJECT::RFBULLETPU].determineCurFrame();
jjObjectPresets[OBJECT::RFBULLETPU].killAnim = jjObjectPresets[OBJECT::SEEKERBULLET].killAnim;
jjObjectPresets[OBJECT::RFBULLETPU].scriptedCollisions = true;
jjObjectPresets[OBJECT::RFBULLETPU].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::RFBULLETPU].animSpeed = 200;
jjWeapons[WEAPON::TOASTER].maximum = 50;
jjWeapons[WEAPON::TOASTER].multiplier = 8;
jjObjectPresets[OBJECT::TOASTERBULLET].xAcc = 0;
jjObjectPresets[OBJECT::TOASTERBULLET].yAcc = 0;
jjObjectPresets[OBJECT::TOASTERBULLET].behavior = Flamethrower();
jjObjectPresets[OBJECT::TOASTERBULLET].determineCurFrame();
jjObjectPresets[OBJECT::TOASTERBULLET].scriptedCollisions = true;
jjObjectPresets[OBJECT::TOASTERBULLET].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::TOASTERBULLET].animSpeed = 6;
jjObjectPresets[OBJECT::TOASTERBULLETPU].xAcc = 0;
jjObjectPresets[OBJECT::TOASTERBULLETPU].yAcc = 0;
jjObjectPresets[OBJECT::TOASTERBULLETPU].behavior = Flamethrower();
jjObjectPresets[OBJECT::TOASTERBULLETPU].determineCurFrame();
jjObjectPresets[OBJECT::TOASTERBULLETPU].scriptedCollisions = true;
jjObjectPresets[OBJECT::TOASTERBULLETPU].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::TOASTERBULLETPU].animSpeed = 12;
jjWeapons[WEAPON::TNT].maximum = 10;
jjAnimSets[ANIM::ROBOT].load();
jjAnimations[jjAnimSets[ANIM::AMMO] + 59] = jjAnimations[jjAnimSets[ANIM::ROBOT] + 0];
jjObjectPresets[OBJECT::TNT].killAnim = jjObjectPresets[OBJECT::RFBULLET].killAnim;
jjObjectPresets[OBJECT::TNT].special = jjObjectPresets[OBJECT::TNT].determineCurAnim(ANIM::ROBOT, 0);
jjObjectPresets[OBJECT::TNT].determineCurFrame();
jjObjectPresets[OBJECT::TNT].lightType = LIGHT::NONE;
jjObjectPresets[OBJECT::TNT].behavior = SpikeMine();
jjObjectPresets[OBJECT::TNT].scriptedCollisions = true;
jjObjectPresets[OBJECT::TNT].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::TNT].animSpeed = 70;
jjObjectPresets[OBJECT::TNT].counterEnd = 245;
jjObjectPresets[OBJECT::TNT].isBlastable = false;
jjWeapons[WEAPON::GUN8].maximum = 25;
jjWeapons[WEAPON::GUN8].spread = SPREAD::NORMAL;
jjWeapons[WEAPON::GUN8].gradualAim = false;
jjWeapons[WEAPON::GUN8].defaultSample = false;
jjObjectPresets[OBJECT::FIREBALLBULLET].xSpeed = -15;
jjObjectPresets[OBJECT::FIREBALLBULLET].ySpeed = 0;
jjObjectPresets[OBJECT::FIREBALLBULLET].xAcc = 0;
jjObjectPresets[OBJECT::FIREBALLBULLET].yAcc = 0;
jjObjectPresets[OBJECT::FIREBALLBULLET].eventID = OBJECT::BLASTERBULLET;
jjObjectPresets[OBJECT::FIREBALLBULLET].behavior = Laser();
jjObjectPresets[OBJECT::FIREBALLBULLET].special = jjObjectPresets[OBJECT::FIREBALLBULLET].determineCurAnim(ANIM::AMMO, 30);
jjObjectPresets[OBJECT::FIREBALLBULLET].determineCurFrame();
jjObjectPresets[OBJECT::FIREBALLBULLET].scriptedCollisions = true;
jjObjectPresets[OBJECT::FIREBALLBULLET].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::FIREBALLBULLET].animSpeed = 40;
jjObjectPresets[OBJECT::FIREBALLBULLET].counterEnd = 140;
jjObjectPresets[OBJECT::FIREBALLBULLET].killAnim = jjObjectPresets[OBJECT::ICEBULLET].killAnim;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].xSpeed = -15;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].ySpeed = 0;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].xAcc = 0;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].yAcc = 0;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].eventID = OBJECT::BLASTERBULLETPU;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].behavior = Laser();
jjObjectPresets[OBJECT::FIREBALLBULLETPU].special = jjObjectPresets[OBJECT::FIREBALLBULLETPU].determineCurAnim(ANIM::AMMO, 30);
jjObjectPresets[OBJECT::FIREBALLBULLETPU].determineCurFrame();
jjObjectPresets[OBJECT::FIREBALLBULLETPU].scriptedCollisions = true;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].animSpeed = 80;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].counterEnd = 140;
jjObjectPresets[OBJECT::FIREBALLBULLETPU].killAnim = jjObjectPresets[OBJECT::ICEBULLET].killAnim;
jjWeapons[WEAPON::GUN9].maximum = 50;
jjObjectPresets[OBJECT::ELECTROBULLET].xSpeed = jjObjectPresets[OBJECT::ELECTROBULLET].xSpeed * -4;
jjObjectPresets[OBJECT::ELECTROBULLET].ySpeed = 0;
jjObjectPresets[OBJECT::ELECTROBULLET].counterEnd = 200;
jjObjectPresets[OBJECT::ELECTROBULLET].behavior = ElectroBlaster();
jjObjectPresets[OBJECT::ELECTROBULLET].scriptedCollisions = true;
jjObjectPresets[OBJECT::ELECTROBULLET].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::ELECTROBULLET].animSpeed = 15;
jjObjectPresets[OBJECT::ELECTROBULLETPU].xSpeed = jjObjectPresets[OBJECT::ELECTROBULLETPU].xSpeed * -4;
jjObjectPresets[OBJECT::ELECTROBULLETPU].ySpeed = 0;
jjObjectPresets[OBJECT::ELECTROBULLETPU].counterEnd = 210;
jjObjectPresets[OBJECT::ELECTROBULLETPU].behavior = ElectroBlaster();
jjObjectPresets[OBJECT::ELECTROBULLETPU].scriptedCollisions = true;
jjObjectPresets[OBJECT::ELECTROBULLETPU].playerHandling = HANDLING::SPECIAL;
jjObjectPresets[OBJECT::ELECTROBULLETPU].animSpeed = 30;
jjObjectPresets[OBJECT::BOUNCERAMMO3].behavior =
jjObjectPresets[OBJECT::ICEAMMO3].behavior =
jjObjectPresets[OBJECT::SEEKERAMMO3].behavior =
jjObjectPresets[OBJECT::RFAMMO3].behavior =
jjObjectPresets[OBJECT::TOASTERAMMO3].behavior =
jjObjectPresets[OBJECT::TNTAMMO3].behavior =
jjObjectPresets[OBJECT::GUN8AMMO3].behavior =
jjObjectPresets[OBJECT::GUN9AMMO3].behavior = AmmoPickup();
jjObjectPresets[OBJECT::BOUNCERAMMO3].scriptedCollisions =
jjObjectPresets[OBJECT::ICEAMMO3].scriptedCollisions =
jjObjectPresets[OBJECT::SEEKERAMMO3].scriptedCollisions =
jjObjectPresets[OBJECT::RFAMMO3].scriptedCollisions =
jjObjectPresets[OBJECT::TOASTERAMMO3].scriptedCollisions =
jjObjectPresets[OBJECT::TNTAMMO3].scriptedCollisions =
jjObjectPresets[OBJECT::GUN8AMMO3].scriptedCollisions =
jjObjectPresets[OBJECT::GUN9AMMO3].scriptedCollisions = true;
jjObjectPresets[OBJECT::BOUNCERAMMO3].var[4] = 2;
jjObjectPresets[OBJECT::ICEAMMO3].var[4] = 3;
jjObjectPresets[OBJECT::SEEKERAMMO3].var[4] = 4;
jjObjectPresets[OBJECT::RFAMMO3].var[4] = 5;
jjObjectPresets[OBJECT::TOASTERAMMO3].var[4] = 6;
jjObjectPresets[OBJECT::TNTAMMO3].var[4] = 7;
jjObjectPresets[OBJECT::GUN8AMMO3].var[4] = 8;
jjObjectPresets[OBJECT::GUN9AMMO3].var[4] = 9;
jjObjectPresets[OBJECT::BOUNCERAMMO3].var[5] = 5;
jjObjectPresets[OBJECT::ICEAMMO3].var[5] = 2;
jjObjectPresets[OBJECT::SEEKERAMMO3].var[5] = 2;
jjObjectPresets[OBJECT::RFAMMO3].var[5] = 1;
jjObjectPresets[OBJECT::TOASTERAMMO3].var[5] = 3;
jjObjectPresets[OBJECT::TNTAMMO3].var[5] = 1;
jjObjectPresets[OBJECT::GUN8AMMO3].var[5] = 2;
jjObjectPresets[OBJECT::GUN9AMMO3].var[5] = 3;
jjObjectPresets[OBJECT::CARROT].behavior = HealthPickup();
jjObjectPresets[OBJECT::CARROT].scriptedCollisions = true;
jjObjectPresets[OBJECT::CARROT].determineCurAnim(customAnimID, 6);
jjObjectPresets[OBJECT::CARROT].determineCurFrame();
jjObjectPresets[OBJECT::CARROT].light = 8;
jjObjectPresets[OBJECT::FULLENERGY].behavior = MegaHealthPickup();
jjObjectPresets[OBJECT::FULLENERGY].scriptedCollisions = true;
jjObjectPresets[OBJECT::FULLENERGY].determineCurAnim(customAnimID, 7);
jjObjectPresets[OBJECT::FULLENERGY].determineCurFrame();
jjObjectPresets[OBJECT::FIRESHIELD].behavior = PowerOrb();
jjObjectPresets[OBJECT::FIRESHIELD].scriptedCollisions = true;
jjObjectPresets[OBJECT::FIRESHIELD].playerHandling = HANDLING::PICKUP;
jjObjectPresets[OBJECT::FIRESHIELD].light = 8;
jjObjectPresets[OBJECT::FIRESHIELD].triggersTNT = false;
jjObjectPresets[OBJECT::FIRESHIELD].determineCurAnim(customAnimID, 5);
jjObjectPresets[OBJECT::FIRESHIELD].determineCurFrame();
jjObjectPresets[OBJECT::PURPLEGEM].determineCurAnim(customAnimID, 1);
jjObjectPresets[OBJECT::PURPLEGEM].determineCurFrame();
jjObjectPresets[OBJECT::PURPLEGEM].behavior = ShipExplosion();
jjObjectPresets[OBJECT::PURPLEGEM].playerHandling = HANDLING::PARTICLE;
jjObjectPresets[OBJECT::PURPLEGEM].bulletHandling = HANDLING::IGNOREBULLET;
jjObjectPresets[OBJECT::PURPLEGEM].frameID = 0;
jjObjectPresets[OBJECT::FULLENERGY].light = 8;
jjObjectPresets[OBJECT::PLASMASHIELD].behavior = ShieldPickup();
jjObjectPresets[OBJECT::PLASMASHIELD].scriptedCollisions = true;
jjObjectPresets[OBJECT::PLASMASHIELD].playerHandling = HANDLING::PICKUP;
jjObjectPresets[OBJECT::PLASMASHIELD].light = 8;
jjObjectPresets[OBJECT::PLASMASHIELD].triggersTNT = false;
jjObjectPresets[OBJECT::PLASMASHIELD].determineCurAnim(customAnimID, 3);
jjObjectPresets[OBJECT::PLASMASHIELD].determineCurFrame();
array<OBJECT::Object> Powerups = {OBJECT::BLASTERPOWERUP, OBJECT::BOUNCERPOWERUP, OBJECT::ICEPOWERUP, OBJECT::SEEKERPOWERUP, OBJECT::RFPOWERUP, OBJECT::TOASTERPOWERUP, OBJECT::TNTPOWERUP, OBJECT::GUN8POWERUP, OBJECT::GUN9POWERUP};
for (uint p = 0; p < Powerups.length(); p++) {
jjObjectPresets[Powerups[p]].behavior = ShieldPickup();
jjObjectPresets[Powerups[p]].scriptedCollisions = true;
jjObjectPresets[Powerups[p]].playerHandling = HANDLING::PICKUP;
jjObjectPresets[Powerups[p]].light = 8;
jjObjectPresets[Powerups[p]].triggersTNT = false;
jjObjectPresets[Powerups[p]].determineCurAnim(customAnimID, 3);
jjObjectPresets[Powerups[p]].determineCurFrame();
}
jjObjectPresets[OBJECT::WATERSHIELD].behavior = MegaShieldPickup();
jjObjectPresets[OBJECT::WATERSHIELD].scriptedCollisions = true;
jjObjectPresets[OBJECT::WATERSHIELD].playerHandling = HANDLING::PICKUP;
jjObjectPresets[OBJECT::WATERSHIELD].light = 8;
jjObjectPresets[OBJECT::WATERSHIELD].triggersTNT = false;
jjObjectPresets[OBJECT::WATERSHIELD].determineCurAnim(customAnimID, 4);
jjObjectPresets[OBJECT::WATERSHIELD].determineCurFrame();
}
jjOBJ@ assignHealthPickup(uint8 eventID) {
jjOBJ@ preset = jjObjectPresets[eventID];
preset.behavior = HealthPickup();
preset.scriptedCollisions = true;
preset.playerHandling = HANDLING::PICKUP;
preset.triggersTNT = false;
preset.determineCurAnim(customAnimID, 6);
preset.determineCurFrame();
preset.light = 8;
return preset;
}
jjOBJ@ assignMegaHealthPickup(uint8 eventID) {
jjOBJ@ preset = jjObjectPresets[eventID];
preset.behavior = MegaHealthPickup();
preset.scriptedCollisions = true;
preset.playerHandling = HANDLING::PICKUP;
preset.triggersTNT = false;
preset.determineCurAnim(customAnimID, 7);
preset.determineCurFrame();
preset.light = 8;
return preset;
}
jjOBJ@ assignShieldPickup(uint8 eventID) {
jjOBJ@ preset = jjObjectPresets[eventID];
preset.behavior = ShieldPickup();
preset.scriptedCollisions = true;
preset.playerHandling = HANDLING::PICKUP;
preset.triggersTNT = false;
preset.determineCurAnim(customAnimID, 3);
preset.determineCurFrame();
preset.light = 8;
return preset;
}
jjOBJ@ assignMegaShieldPickup(uint8 eventID) {
jjOBJ@ preset = jjObjectPresets[eventID];
preset.behavior = MegaShieldPickup();
preset.scriptedCollisions = true;
preset.playerHandling = HANDLING::PICKUP;
preset.triggersTNT = false;
preset.determineCurAnim(customAnimID, 4);
preset.determineCurFrame();
preset.light = 8;
return preset;
}
jjOBJ@ assignPowerOrb(uint8 eventID) {
jjOBJ@ preset = jjObjectPresets[eventID];
preset.behavior = PowerOrb();
preset.scriptedCollisions = true;
preset.playerHandling = HANDLING::PICKUP;
preset.triggersTNT = false;
preset.determineCurAnim(customAnimID, 5);
preset.determineCurFrame();
preset.light = 8;
return preset;
}
void assignPickupDefaults() {
jjObjectPresets[OBJECT::CARROT].behavior = HealthPickup();
jjObjectPresets[OBJECT::CARROT].scriptedCollisions = true;
jjObjectPresets[OBJECT::CARROT].determineCurAnim(customAnimID, 6);
jjObjectPresets[OBJECT::CARROT].determineCurFrame();
jjObjectPresets[OBJECT::CARROT].light = 8;
jjObjectPresets[OBJECT::FULLENERGY].behavior = MegaHealthPickup();
jjObjectPresets[OBJECT::FULLENERGY].scriptedCollisions = true;
jjObjectPresets[OBJECT::FULLENERGY].determineCurAnim(customAnimID, 7);
jjObjectPresets[OBJECT::FULLENERGY].determineCurFrame();
jjObjectPresets[OBJECT::SEEKERPOWERUP].behavior = MegaShieldPickup();
jjObjectPresets[OBJECT::SEEKERPOWERUP].scriptedCollisions = true;
jjObjectPresets[OBJECT::SEEKERPOWERUP].playerHandling = HANDLING::PICKUP;
jjObjectPresets[OBJECT::SEEKERPOWERUP].light = 8;
jjObjectPresets[OBJECT::SEEKERPOWERUP].triggersTNT = false;
jjObjectPresets[OBJECT::SEEKERPOWERUP].determineCurAnim(customAnimID, 4);
jjObjectPresets[OBJECT::SEEKERPOWERUP].determineCurFrame();
array<OBJECT::Object> Shields = {OBJECT::FIRESHIELD, OBJECT::WATERSHIELD, OBJECT::LIGHTNINGSHIELD, OBJECT::LASERSHIELD};
for (uint s = 0; s < Shields.length(); s++) {
jjObjectPresets[Shields[s]].behavior = PowerOrb();
jjObjectPresets[Shields[s]].scriptedCollisions = true;
jjObjectPresets[Shields[s]].playerHandling = HANDLING::PICKUP;
jjObjectPresets[Shields[s]].light = 8;
jjObjectPresets[Shields[s]].triggersTNT = false;
jjObjectPresets[Shields[s]].determineCurAnim(customAnimID, 5);
jjObjectPresets[Shields[s]].determineCurFrame();
}
array<OBJECT::Object> Powerups = {OBJECT::BLASTERPOWERUP, OBJECT::BOUNCERPOWERUP, OBJECT::ICEPOWERUP, OBJECT::RFPOWERUP, OBJECT::TOASTERPOWERUP, OBJECT::TNTPOWERUP, OBJECT::GUN8POWERUP, OBJECT::GUN9POWERUP};
for (uint p = 0; p < Powerups.length(); p++) {
jjObjectPresets[Powerups[p]].behavior = ShieldPickup();
jjObjectPresets[Powerups[p]].scriptedCollisions = true;
jjObjectPresets[Powerups[p]].playerHandling = HANDLING::PICKUP;
jjObjectPresets[Powerups[p]].light = 8;
jjObjectPresets[Powerups[p]].triggersTNT = false;
jjObjectPresets[Powerups[p]].determineCurAnim(customAnimID, 3);
jjObjectPresets[Powerups[p]].determineCurFrame();
}
jjObjectPresets[OBJECT::PURPLEGEM].determineCurAnim(customAnimID, 1);
jjObjectPresets[OBJECT::PURPLEGEM].determineCurFrame();
jjObjectPresets[OBJECT::PURPLEGEM].behavior = ShipExplosion();
jjObjectPresets[OBJECT::PURPLEGEM].playerHandling = HANDLING::PARTICLE;
jjObjectPresets[OBJECT::PURPLEGEM].bulletHandling = HANDLING::IGNOREBULLET;
jjObjectPresets[OBJECT::PURPLEGEM].frameID = 0;
}
void handleAnimationWork() {
Resize::Resize(
jjAnimations[jjAnimSets[ANIM::JAZZ] + 53],
3,
Resize::Method::Scale2x
);
Resize::Resize(
jjAnimations[jjAnimSets[ANIM::SPAZ] + 53],
3,
Resize::Method::Scale2x
);
Resize::Resize(
jjAnimations[jjAnimSets[ANIM::LORI] + 53],
3,
Resize::Method::Scale2x
);
Resize::Resize(
jjAnimations[jjAnimSets[ANIM::PICKUPS] + 41],
2,
Resize::Method::Scale2x
);
Resize::Resize(
jjAnimations[jjAnimSets[ANIM::AMMO] + 30],
2,
Resize::Method::Scale2x
);
Resize::Resize(
jjAnimations[jjAnimSets[ANIM::SONCSHIP] + 0],
1.5,
Resize::Method::Scale2x
);
Resize::Resize(
jjAnimations[jjAnimSets[ANIM::MENU] + 1],
3.5,
Resize::Method::Scale2x
);
jjANIMATION@ animBlaster = jjAnimations[jjAnimSets[ANIM::DEVAN] + 0];
for (uint i = 0; i < animBlaster.frameCount; i++) {
jjANIMFRAME@ frame = jjAnimFrames[animBlaster + i];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 32 && sprite[x,y] <= 39) sprite[x,y] -= 17;
}
}
sprite.save(frame);
}
jjANIMATION@ animBurst = jjAnimations[jjAnimSets[ANIM::PICKUPS] + 45];
for (uint i = 0; i < animBurst.frameCount; i++) {
jjANIMFRAME@ frame = jjAnimFrames[animBurst + i];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 32 && sprite[x,y] <= 39) sprite[x,y] += 56;
}
}
sprite.save(frame);
}
jjANIMATION@ animBurstAmmo = jjAnimations[jjAnimSets[ANIM::AMMO] + 29];
for (uint i = 0; i < animBurstAmmo.frameCount; i++) {
jjANIMFRAME@ frame = jjAnimFrames[animBurstAmmo + i];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 32 && sprite[x,y] <= 39) sprite[x,y] += 56;
}
}
sprite.save(frame);
}
jjANIMATION@ animBurstAmmoPU = jjAnimations[jjAnimSets[ANIM::AMMO] + 28];
for (uint i = 0; i < animBurstAmmoPU.frameCount; i++) {
jjANIMFRAME@ frame = jjAnimFrames[animBurstAmmoPU + i];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 88 && sprite[x,y] <= 95) sprite[x,y] -= 33;
}
}
sprite.save(frame);
}
jjANIMATION@ animMissile = jjAnimations[jjAnimSets[ANIM::SONCSHIP] + 0];
for (uint i = 0; i < animMissile.frameCount; i++) {
jjANIMFRAME@ frame = jjAnimFrames[animMissile + i];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 88 && sprite[x,y] <= 95) sprite[x,y] -= 72;
}
}
sprite.save(frame);
}
jjANIMATION@ animLaser = jjAnimations[jjAnimSets[ANIM::AMMO] + 30];
for (uint i = 0; i < animLaser.frameCount; i++) {
jjANIMFRAME@ frame = jjAnimFrames[animLaser + i];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 32 && sprite[x,y] <= 39) sprite[x,y] += 48;
}
}
sprite.save(frame);
}
jjANIMATION@ animLaserAmmo = jjAnimations[jjAnimSets[ANIM::AMMO] + 62];
for (uint i = 0; i < animLaserAmmo.frameCount; i++) {
jjANIMFRAME@ frame = jjAnimFrames[animLaserAmmo + i];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 88 && sprite[x,y] <= 95) sprite[x,y] -= 8;
}
}
sprite.save(frame);
}
jjANIMATION@ animLaserAmmoPU = jjAnimations[jjAnimSets[ANIM::AMMO] + 61];
for (uint i = 0; i < animLaserAmmoPU.frameCount; i++) {
jjANIMFRAME@ frame = jjAnimFrames[animLaserAmmoPU + i];
jjPIXELMAP sprite(frame);
for (uint x = 0; x < sprite.width; ++x) {
for (uint y = 0; y < sprite.height; ++y) {
if (sprite[x,y] >= 24 && sprite[x,y] <= 31) sprite[x,y] += 24;
}
}
sprite.save(frame);
}
}
void handleOnLevelBegin() {
jjAlert("|||Press |||||F2||| for instructions!");
jjSampleLoad(SOUND::COMMON_LANDPOP, "silence.wav");
}
void handleShipCollisions(jjOBJ@ obj, jjPLAYER@ creator) {
if (!jjLocalPlayers[0].isIdle) {
for (int i = 0; i < 32; i++) {
jjPLAYER@ play = jjPlayers[i];
SPACESHIP@ ship = Ships[i];
if (obj.doesCollide(play, true) && canBeHit(play,creator,obj) && (obj.var[8] & 1 << play.playerID == 0 || obj.eventID != OBJECT::FIREBALLBULLET)) {
if (obj.special != 100) {
ship.damageAccumulated += obj.animSpeed;
ship.accumulationTime = 0;
obj.special = 100;
}
if (obj.eventID == OBJECT::ICEBULLET || obj.eventID == OBJECT::ICEBULLETPU) damageNumber(creator, play, ship.damageCalc(ship, ship.damageAccumulated));
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
randomHurtSample(play, 48);
if (!play.isLocal && obj.eventID != OBJECT::ICEBULLET && obj.eventID != OBJECT::ICEBULLETPU) damageNumber(creator, play, ship.damageCalc(ship, ship.damageAccumulated));
if ((obj.eventID == OBJECT::SEEKERBULLET || obj.eventID == OBJECT::SEEKERBULLETPU) && creator.isLocal) obj.state = STATE::EXPLODE;
jjSample(
play.xPos, play.yPos,
(obj.eventID == OBJECT::TOASTERBULLET || obj.eventID == OBJECT::TOASTERBULLETPU)? SOUND::BILSBOSS_FIRE :
(obj.eventID == OBJECT::SEEKERBULLET || obj.eventID == OBJECT::SEEKERBULLETPU || obj.eventID == OBJECT::RFBULLET || obj.eventID == OBJECT::RFBULLETPU || obj.eventID == OBJECT::TNT)? SOUND::COMMON_EXPL_TNT :
(obj.eventID == OBJECT::ELECTROBULLET || obj.eventID == OBJECT::ELECTROBULLETPU)? SOUND::COMMON_ELECTRICHIT :
SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500
);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
}
}
}
}
}
class Blaster : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
obj.behave(BEHAVIOR::BULLET, obj.state == STATE::FLY && inView(obj)? false:true);
obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
if (obj.state == STATE::START) {
obj.state = STATE::FLY;
}
if (obj.state == STATE::FLY) {
if (obj.counter == 1 && jjPlayers[obj.creatorID].isLocal) jjSample(obj.xPos, obj.yPos, SOUND::DEVILDEVAN_PHASER2, 50, obj.eventID == OBJECT::BLASTERBULLETPU? 11500 : 0);
if (obj.counter > 1 && inView(obj)) jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.var[0], 1, 1, obj.eventID == OBJECT::BLASTERBULLETPU? SPRITE::SINGLEHUE : SPRITE::NORMAL, 49);
}
if (obj.findNearestPlayer(1000) > -1 && obj.findNearestPlayer(1000) != creator.playerID) handleShipCollisions(obj, creator);
if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
obj.xPos = creator.xPos;
obj.yPos = creator.yPos;
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj)) {
ship.xSpeed += recoilX(ship,obj,12);
ship.ySpeed += recoilY(ship,obj,12);
randomHurtSample(play, 0);
if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::BLASTERBULLETPU? jjObjectPresets[OBJECT::BLASTERBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::BLASTERBULLET].animSpeed * 1.3);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
jjSample(play.xPos, play.yPos, SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
obj.state = STATE::EXPLODE;
obj.scriptedCollisions = false;
}
return true;
}
}
class RapidBlaster : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
obj.behave(BEHAVIOR::BULLET, obj.state == STATE::FLY && inView(obj)? false:true);
obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
if (obj.state == STATE::START) {
obj.state = STATE::FLY;
}
if (obj.state == STATE::FLY) {
if (obj.counter == 1 && jjPlayers[obj.creatorID].isLocal) jjSample(obj.xPos, obj.yPos, SOUND::COMMON_PISTOL1, 50, obj.eventID == OBJECT::BOUNCERBULLETPU? 20000 : 0);
if (obj.counter > 1) jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.var[0], 1, 1, obj.eventID == OBJECT::BOUNCERBULLETPU? SPRITE::SINGLEHUE : SPRITE::NORMAL, 88);
}
if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
obj.xPos = creator.xPos;
obj.yPos = creator.yPos;
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj)) {
ship.xSpeed += recoilX(ship,obj,7.5);
ship.ySpeed += recoilY(ship,obj,7.5);
randomHurtSample(play, 0);
if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::BOUNCERBULLETPU? jjObjectPresets[OBJECT::BOUNCERBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::BOUNCERBULLET].animSpeed * 1.3);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
jjSample(play.xPos, play.yPos, SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
obj.state = STATE::EXPLODE;
obj.scriptedCollisions = false;
}
return true;
}
}
class IceBurster : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::BULLET, obj.state == STATE::FLY && inView(obj)? false:true);
obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
jjPLAYER@ creator = jjPlayers[obj.creatorID];
if (obj.state == STATE::START) {
obj.state = STATE::FLY;
}
if (obj.state == STATE::FLY) {
if (obj.counter == 2 && jjPlayers[obj.creatorID].isLocal) {
jjSample(obj.xPos, obj.yPos, SOUND::COMMON_ICECRUSH, 30, obj.eventID == OBJECT::ICEBULLETPU? 10500:0);
if (creator.ySpeed == 0) {
if (obj.ySpeed < - 12) obj.ySpeed = -12;
if (obj.ySpeed > 12) obj.ySpeed = 12;
}
}
if (obj.counter > 1 && inView(obj)) jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.var[0], 1, 1, obj.eventID == OBJECT::ICEBULLETPU? SPRITE::SINGLEHUE : SPRITE::NORMAL, 40);
if (obj.eventID == OBJECT::ICEBULLETPU && jjGameTicks % 3 == 0) {
jjPARTICLE@ cinders = jjAddParticle(PARTICLE::FIRE);
cinders.xPos = obj.xPos;
cinders.yPos = obj.yPos;
}
}
if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
obj.xPos = creator.xPos;
obj.yPos = creator.yPos;
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj)) {
ship.xSpeed += recoilX(ship,obj,17.5);
ship.ySpeed += recoilY(ship,obj,17.5);
randomHurtSample(play, 0);
if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::ICEBULLETPU? jjObjectPresets[OBJECT::ICEBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::ICEBULLET].animSpeed * 1.3);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (obj.special != 100) {
ship.damageAccumulated += obj.animSpeed;
ship.accumulationTime = 0;
obj.special = 100;
}
if (obj.eventID == OBJECT::ICEBULLET || obj.eventID == OBJECT::ICEBULLETPU) damageNumber(creator, play, ship.damageCalc(ship, ship.damageAccumulated));
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
jjSample(play.xPos, play.yPos, SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
obj.state = STATE::EXPLODE;
obj.scriptedCollisions = false;
}
return true;
}
}
class HomingMissile : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
obj.behave(BEHAVIOR::BULLET, obj.state == STATE::FLY && inView(obj)? false:true);
obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
++obj.age;
if (obj.state == STATE::FLY && obj.counter > 1 && inView(obj)) jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.var[0], 1, 1, SPRITE::NORMAL);
if (obj.state == STATE::START) {
obj.points = int(atan2(obj.xSpeed, obj.ySpeed) * 162.974636 /*+ (jjCos(jjRandom() % 512) * 10)*/); //angle
obj.state = STATE::FLY;
obj.xSpeed += obj.var[7] / 65536.f;
} else if (obj.age > 14) { //redirect
array<float>@ target = null;
if (obj.creatorType == CREATOR::PLAYER && jjGameMode > GAME::COOP) {
const int targetPlayerID = closestPlayers[obj.creatorID]; //closest to player who fired this
if (targetPlayerID >= 0)
@target = array<float> = { jjPlayers[targetPlayerID].xPos, jjPlayers[targetPlayerID].yPos };
}
if (target is null)
@target = MLLEWeapons::HelpfulBulletFunctions::GetNearestEnemyPosition(obj, 350); //closest to bullet itself... this part is new to the .asc reimplementation
if (target !is null) {
int difference = ((int(atan2(obj.xPos - target[0], obj.yPos - target[1]) * 162.974636) + 512 - obj.points) & 1023);
if (difference >= 512) difference -= 1024;
obj.points += difference / 8;
obj.xSpeed = 4.75 * jjSin(obj.points);
obj.ySpeed = 4.75 * jjCos(obj.points);
}
}
if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
obj.xPos = creator.xPos;
obj.yPos = creator.yPos;
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj) && obj.state != STATE::EXPLODE) {
ship.xSpeed += recoilX(ship,obj,55);
ship.ySpeed += recoilY(ship,obj,55);
randomHurtSample(play, 0);
if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::SEEKERBULLETPU? jjObjectPresets[OBJECT::SEEKERBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::SEEKERBULLET].animSpeed * 1.5);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
jjSample(play.xPos, play.yPos, SOUND::COMMON_EXPL_TNT, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
obj.state = STATE::EXPLODE;
obj.scriptedCollisions = false;
}
return true;
}
}
class SuperMissile : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::BULLET, false);
jjPLAYER@ creator = jjPlayers[obj.creatorID];
jjPLAYER@ play;
obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
switch (obj.state) {
case STATE::START:
obj.state = STATE::FLY;
obj.lightType = LIGHT::POINT;
obj.var[2] = 0;
break;
case STATE::FLY:
if (obj.counter == 1 && creator.isLocal) {
jjSample(creator.xPos, creator.yPos, SOUND::INTRO_SHOT1, 0, obj.eventID == OBJECT::RFBULLETPU? 35500 : 0);
}
if (obj.counter > 1 && inView(obj)) jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.var[0], 1, 1, obj.eventID == OBJECT::RFBULLETPU? SPRITE::PALSHIFT : SPRITE::NORMAL, 8);
if (obj.counter % 5 == 0 && !jjLowDetail) {
jjOBJ@ trail = jjObjects[jjAddObject(OBJECT::EXPLOSION, int(obj.xPos - jjCos(obj.var[0])), int(obj.yPos - jjSin(obj.var[0])))];
trail.determineCurAnim(ANIM::AMMO, 3);
trail.lightType = LIGHT::NONE;
trail.playerHandling = HANDLING::PARTICLE;
trail.bulletHandling = HANDLING::IGNOREBULLET;
trail.isBlastable = false;
}
break;
case STATE::EXPLODE:
jjDrawResizedSprite(obj.xPos, obj.yPos, ANIM::AMMO, 5, obj.curFrame + 1, obj.eventID == OBJECT::RFBULLETPU? 2.5:2, obj.eventID == OBJECT::RFBULLETPU? 2.5:2, SPRITE::NORMAL);
if (obj.var[2] == 0) {
jjSample(obj.xPos, obj.yPos, SOUND::COMMON_BENZIN1);
Shockwave temp;
jjOBJ@ blast = jjObjects[jjAddObject(OBJECT::BULLET, obj.xPos, obj.yPos, obj.creatorID, CREATOR::PLAYER, jjVOIDFUNCOBJ(temp.onBehave))];
obj.var[2] = 1;
blast.var[2] = 1;
blast.var[8] = obj.var[8];
blast.animSpeed = obj.animSpeed;
blast.eventID = OBJECT::BULLET;
}
break;
}
if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
obj.xPos = creator.xPos;
obj.yPos = creator.yPos;
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj) && obj.var[8] & 1 << play.playerID == 0) {
ship.xSpeed += recoilX(ship,obj,30);
ship.ySpeed += recoilY(ship,obj,30);
randomHurtSample(play, 0);
if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::RFBULLETPU? jjObjectPresets[OBJECT::RFBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::RFBULLET].animSpeed * 1.5);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
obj.var[8] = obj.var[8] | 1 << play.playerID;
jjSample(play.xPos, play.yPos, SOUND::COMMON_EXPL_TNT, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
obj.state = STATE::EXPLODE;
obj.scriptedCollisions = false;
}
return true;
}
}
class Shockwave : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
obj.playerHandling = HANDLING::PARTICLE;
obj.bulletHandling = HANDLING::IGNOREBULLET;
if (obj.var[2] == 1) {
obj.lightType = obj.var[2] == 1? LIGHT::RING2 : LIGHT::NONE;
obj.var[1] = obj.var[1] + 1;
obj.light += 2;
obj.var[4] = obj.light * 4;
obj.var[5] = obj.animSpeed - ((obj.var[4] * obj.animSpeed)/216);
if (obj.var[4] >= 200) obj.var[6] = 20;
else if (obj.var[4] >= 100 && obj.var[6] < 200) obj.var[6] = 30;
else if (obj.var[4] < 100) obj.var[6] = 40;
for (int i = 1; i < jjObjectCount; i++) {
jjOBJ@ target = jjObjects[i];
float dx = target.xPos - obj.xPos, dy = target.yPos - obj.yPos;
if ((target.eventID == OBJECT::TNT || target.behavior == BEHAVIOR::MONITOR || target.behavior == BEHAVIOR::AMMO15 || target.eventID == OBJECT::GUNCRATE || target.eventID == OBJECT::GEMCRATE || target.eventID == OBJECT::CARROTCRATE || target.playerHandling == HANDLING::ENEMY || target.eventID == OBJECT::DESTRUCTSCENERY) && target.var[4] == 0) {
if (dx * dx + dy * dy < obj.var[4] * obj.var[4]) {
if (target.eventID != OBJECT::TNT) {
obj.objectHit(target, target.playerHandling == HANDLING::ENEMY? HANDLING::ENEMY : HANDLING::SPECIAL);
if (target.playerHandling != HANDLING::ENEMY) target.state = STATE::KILL;
} else {
target.state = STATE::EXPLODE;
target.counter = 18;
}
if (target.playerHandling != HANDLING::ENEMY) target.var[4] = 1;
}
else target.var[4] = 0;
}
}
if (gameIsActive()) {
for (int i = 0; i < 32; i++) {
jjPLAYER@ play = jjPlayers[i];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj) && obj.var[4] > 0) {
float dx = play.xPos - obj.xPos, dy = play.yPos - obj.yPos;
if (dx * dx + dy * dy < obj.var[4] * obj.var[4]) {
if (obj.var[8] & 1 << i == 0 && play.blink == 0 && obj.var[5] > 0) {
obj.var[8] = obj.var[8] | 1 << i;
jjSample(play.xPos, play.yPos, SOUND::ROBOT_HYDROPUF, 63, 12500 + jjRandom()%2500);
if ((ship.health - ship.damageCalc(ship, obj.var[5])) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.var[5]);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.var[5]) * 2;
}
randomHurtSample(play, 0);
ship.damageAccumulated += obj.var[5];
ship.accumulationTime = 0;
if (!play.isLocal) damageNumber(creator, play, ship.damageCalc(ship, obj.var[5]));
int angle = int(atan2(play.yPos - obj.yPos, play.xPos - obj.xPos) * (512 / PI));
obj.ySpeed = jjSin(angle) * 32;
obj.xSpeed = jjCos(angle) * 32;
ship.xSpeed += recoilX(ship,obj,obj.var[6]);
ship.ySpeed += recoilY(ship,obj,obj.var[6]);
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
if (creator.isLocal) {
ship.SDPunishment = true;
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
}
}
}
}
}
}
if (obj.var[1] == 27) {
obj.var[1] = 0;
obj.var[2] = 0;
obj.var[4] = 0;
obj.delete();
}
}
}
class Flamethrower : jjBEHAVIORINTERFACE {
float xSpeed, ySpeed, xPos, yPos;
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::TOASTERBULLET, false);
jjPLAYER@ creator = jjPlayers[obj.creatorID];
if (obj.state == STATE::FLY) {
obj.var[0] = int(creator.xSpeed);
if (obj.counter <= 3) {
xSpeed = obj.xSpeed;
ySpeed = obj.ySpeed;
}
if (obj.counter <= 7) {
obj.xSpeed = xSpeed * 2;
obj.ySpeed = ySpeed * 2;
}
obj.counter++;
if (obj.counter > 1 && inView(obj)) {
jjDrawSprite(obj.xPos, obj.yPos, ANIM::AMMO, 13, jjGameTicks >> 2, obj.direction, obj.eventID == OBJECT::TOASTERBULLETPU? SPRITE::SINGLEHUE : SPRITE::NORMAL, 32);
}
if (obj.counter >= 200) obj.delete();
}
if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj) && obj.state != STATE::EXPLODE) {
ship.xSpeed += recoilX(ship,obj,8);
ship.ySpeed += recoilY(ship,obj,8);
randomHurtSample(play, 0);
if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::TOASTERBULLETPU? jjObjectPresets[OBJECT::TOASTERBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::TOASTERBULLET].animSpeed * 1.5);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
obj.state = STATE::EXPLODE;
obj.scriptedCollisions = false;
jjSample(play.xPos, play.yPos, SOUND::BILSBOSS_FIRE, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
}
return true;
}
}
class SpikeMine : jjBEHAVIORINTERFACE {
bool isPowerup = false;
void onBehave(jjOBJ@ obj) {
obj.behave(obj.state == STATE::EXPLODE && obj.counter >= 18 && inView(obj)? BEHAVIOR::BULLET : BEHAVIOR::TNT, false);
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[creator.playerID];
obj.animSpeed = creator is jjTokenOwner? (isPowerup? 210:105) : (isPowerup? 140:70);
if (obj.state != STATE::EXPLODE) {
obj.xPos = obj.xPos + obj.xSpeed;
obj.yPos = obj.yPos + obj.ySpeed;
jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, isPowerup? SPRITE::SINGLEHUE : SPRITE::NORMAL, 40);
if (obj.counter == 1) {
if (ship.tntPowerup) isPowerup = true;
else isPowerup = false;
if (creator.isLocal) jjSample(obj.xPos, obj.yPos, SOUND::ROBOT_SHOOT, 0, isPowerup? 17500 : 0);
obj.xSpeed = creator.xSpeed / -4;
obj.ySpeed = (creator.ySpeed < 0.2 && creator.ySpeed > -0.2)? 0 : creator.ySpeed / -4;
}
if (obj.counter >= 175) {
if (obj.counter % 20 > 9) jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::TRANSLUCENTSINGLEHUE, 24);
obj.var[0] = jjSampleLooped(obj.xPos, obj.yPos, SOUND::COMMON_CLOCK, obj.var[0], 0, 0);
}
if (jjMaskedPixel(int(obj.xPos), int(obj.yPos))) {
obj.counter = 18;
obj.state = STATE::EXPLODE;
}
} else {
if (obj.counter == 18) {
jjDrawResizedSprite(obj.xPos, obj.yPos, ANIM::AMMO, 5, obj.curFrame, 2, 2, SPRITE::NORMAL);
obj.behavior = BEHAVIOR::BULLET;
if (obj.var[2] == 0) {
jjSample(obj.xPos, obj.yPos, SOUND::COMMON_BENZIN1);
Shockwave temp;
jjOBJ@ blast = jjObjects[jjAddObject(OBJECT::BULLET, obj.xPos, obj.yPos, obj.creatorID, CREATOR::PLAYER, jjVOIDFUNCOBJ(temp.onBehave))];
obj.var[2] = 1;
blast.var[2] = 1;
blast.var[8] = obj.var[8];
blast.animSpeed = obj.animSpeed;
blast.eventID = OBJECT::BULLET;
}
} else {
jjDrawResizedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, (1 + (obj.counter/4)), (1 + (obj.counter/4)), isPowerup? SPRITE::SINGLEHUE : SPRITE::NORMAL, 40);
}
}
if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
obj.xPos = creator.xPos;
obj.yPos = creator.yPos;
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj) && obj.var[8] & 1 << play.playerID == 0) {
ship.xSpeed += recoilX(ship,obj,20);
ship.ySpeed += recoilY(ship,obj,20);
randomHurtSample(play, 0);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
obj.var[8] = obj.var[8] | 1 << play.playerID;
obj.counter = 18;
obj.state = STATE::EXPLODE;
obj.scriptedCollisions = false;
jjSample(play.xPos, play.yPos, SOUND::COMMON_EXPL_TNT, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
}
return true;
}
}
class Laser : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
obj.behave(BEHAVIOR::BULLET, obj.state == STATE::EXPLODE && inView(obj)? true:false);
obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
if (obj.state == STATE::FLY) {
if (obj.counter == 1 && jjPlayers[obj.creatorID].isLocal) jjSample(obj.xPos, obj.yPos, SOUND::AMMO_LASER, 0, obj.eventID == OBJECT::BLASTERBULLETPU? 12500:0);
if (obj.ySpeed < -15) obj.ySpeed = -15;
if (obj.ySpeed > 15) obj.ySpeed = 15;
}
if (obj.counter > 1 && inView(obj)) jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.var[0], 1, 1, obj.eventID == OBJECT::BLASTERBULLETPU? SPRITE::SINGLEHUE : SPRITE::NORMAL, 48);
if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
obj.xPos = creator.xPos;
obj.yPos = creator.yPos;
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj) && obj.var[8] & 1 << play.playerID == 0) {
ship.xSpeed += recoilX(ship,obj,40);
ship.ySpeed += recoilY(ship,obj,40);
randomHurtSample(play, 0);
if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::FIREBALLBULLETPU? jjObjectPresets[OBJECT::FIREBALLBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::FIREBALLBULLET].animSpeed * 1.5);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
obj.var[8] = obj.var[8] | 1 << play.playerID;
jjSample(play.xPos, play.yPos, SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
}
return true;
}
}
class ElectroBlaster : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
obj.behave(BEHAVIOR::ELECTROBULLET, obj.counter > 1 && inView(obj)? true:false);
obj.xPos += jjCos(obj.counter*36)*(obj.ySpeed/3);
obj.yPos += jjSin(obj.counter*36)*(obj.xSpeed/3);
if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
obj.xPos = creator.xPos;
obj.yPos = creator.yPos;
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
jjPLAYER@ creator = jjPlayers[obj.creatorID];
SPACESHIP@ ship = Ships[play.playerID];
if (canBeHit(play,creator,obj) && obj.state != STATE::EXPLODE) {
ship.xSpeed += recoilX(ship,obj,15);
ship.ySpeed += recoilY(ship,obj,15);
randomHurtSample(play, 0);
if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::ELECTROBULLETPU? jjObjectPresets[OBJECT::ELECTROBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::ELECTROBULLET].animSpeed * 1.5);
if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
if (play.isLocal) {
ship.health -= ship.damageCalc(ship, obj.animSpeed);
if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
}
} else {
if (play.isLocal) {
play.hurt(7, true, creator);
}
}
if (!ship.justHit) {
ship.justHit = true;
ship.hitDelay = 0;
}
jjSample(play.xPos, play.yPos, SOUND::COMMON_ELECTRICHIT, 63, 12500 + jjRandom()%2500);
if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
obj.state = STATE::EXPLODE;
obj.scriptedCollisions = false;
}
return true;
}
}
bool inView(const jjOBJ@ obj) {
for (int i = 0; i < jjLocalPlayerCount; i++) {
const jjPLAYER@ play = jjLocalPlayers[i];
if (obj.xPos > play.cameraX - 64 && obj.yPos > play.cameraY - 64 && obj.xPos < play.cameraX + jjSubscreenWidth + 64 && obj.yPos < play.cameraY + jjSubscreenHeight + 64)
return true;
}
return false;
}
bool shipInView(jjPLAYER@ play) {
for (int i = 0; i < jjLocalPlayerCount; i++) {
const jjPLAYER@ player = jjLocalPlayers[i];
if (play.xPos > player.cameraX - 64 && play.yPos > player.cameraY - 64 && play.xPos < player.cameraX + jjSubscreenWidth + 64 && play.yPos < player.cameraY + jjSubscreenHeight + 64)
return true;
}
return false;
}
void damageNumber(jjPLAYER@ creator, jjPLAYER@ play, int num) {
if (creator.isLocal) {
jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
if (text !is null) {
text.xPos = play.xPos;
text.yPos = play.yPos;
text.ySpeed = -0.25;
text.string.text = "" + num;
}
jjSample(creator.xPos, creator.yPos, SOUND::MENUSOUNDS_TYPE, 63, 28500 - (num * 50));
crosshairFlash = true;
crosshairTime = 0;
}
}
class AmmoPickup : jjBEHAVIORINTERFACE {
float getY(const ::jjOBJ@ obj) const {
int arg = (((obj.objectID << 3) + ::jjGameTicks) << (obj.yPos > ::jjWaterLevel ? 1 : 4)) + (int(obj.xPos) << 4);
return obj.yPos + ::jjSin(arg) * 4.f;
}
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::PICKUP, obj.eventID == OBJECT::TNTAMMO3? false:true);
if (obj.eventID == OBJECT::TNTAMMO3) {
jjDrawSprite(obj.xPos, getY(obj), ANIM::ROBOT, 0, 0, 0, SPRITE::SINGLEHUE, (jjLocalPlayers[0].powerup[WEAPON::TNT]? 40:72));
}
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
if (play.ammo[obj.var[4]] < jjWeapons[obj.var[4]].maximum) {
if (play.ammo[obj.var[4]] + obj.var[5] > jjWeapons[obj.var[4]].maximum) {
play.ammo[obj.var[4]] = jjWeapons[obj.var[4]].maximum;
} else {
if (jjAutoWeaponChange && play.ammo[obj.var[4]] == 0) play.currWeapon = obj.var[4];
play.ammo[obj.var[4]] = play.ammo[obj.var[4]] + obj.var[5];
}
if (play.isLocal) jjSample(play.xPos, play.yPos, SOUND::COMMON_PICKUPW1);
obj.behavior = BEHAVIOR::EXPLOSION2;
obj.scriptedCollisions = false;
obj.frameID = 0;
}
return true;
}
}
class HealthPickup : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::PICKUP);
obj.direction = 1;
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
SPACESHIP@ ship = Ships[play.playerID];
int amount = ship.health > (maxHealth - int(maxHealth/5))? maxHealth - ship.health : int(maxHealth/5);
if (ship.health < maxHealth && play.blink == 0) {
sendShipRotationPacket(ship);
ship.health += amount;
if (play.isLocal) {
jjSample(play.xPos, play.yPos, SOUND::COMMON_MONITOR);
jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
if (text !is null) {
text.xPos = play.xPos;
text.yPos = play.yPos;
text.ySpeed = -0.25;
text.string.text = "|||||+" + amount;
}
}
play.invincibility = 70;
obj.behavior = BEHAVIOR::EXPLOSION2;
obj.scriptedCollisions = false;
obj.frameID = 0;
}
return true;
}
}
class MegaHealthPickup : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::PICKUP);
obj.direction = 1;
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
SPACESHIP@ ship = Ships[play.playerID];
int amount = ship.health > maxHealth? (maxHealth*2) - ship.health : maxHealth;
if (ship.health < (maxHealth*2) && play.blink == 0) {
sendShipRotationPacket(ship);
ship.health += amount;
if (play.isLocal) {
jjSample(play.xPos, play.yPos, SOUND::COMMON_ITEMTRE);
jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
if (text !is null) {
text.xPos = play.xPos;
text.yPos = play.yPos;
text.ySpeed = -0.25;
text.string.text = "|||||+" + amount;
}
playHappySample(play);
}
play.invincibility = 210;
obj.behavior = BEHAVIOR::EXPLOSION2;
obj.scriptedCollisions = false;
obj.frameID = 0;
}
return true;
}
}
class ShieldPickup : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::PICKUP);
obj.direction = 1;
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
SPACESHIP@ ship = Ships[play.playerID];
int amount = (ship.armor > (maxHealth / 2))? maxHealth - ship.armor : int(maxHealth/2);
if (ship.armor < maxHealth) {
sendShipRotationPacket(ship);
ship.armor += amount;
if (play.isLocal) {
jjSample(play.xPos, play.yPos, SOUND::INTRO_SHOTGRN);
jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
if (text !is null) {
text.xPos = play.xPos;
text.yPos = play.yPos;
text.ySpeed = -0.25;
text.string.text = "|+" + amount;
}
}
obj.behavior = BEHAVIOR::EXPLOSION2;
obj.scriptedCollisions = false;
obj.frameID = 0;
}
return true;
}
}
class MegaShieldPickup : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::PICKUP);
obj.direction = 1;
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
SPACESHIP@ ship = Ships[play.playerID];
int amount = ship.armor > maxHealth? (maxHealth*2) - ship.armor : maxHealth;
if (ship.armor < (maxHealth * 2)) {
sendShipRotationPacket(ship);
ship.armor += amount;
if (play.isLocal) {
jjSample(play.xPos, play.yPos, SOUND::INTRO_SHOTGRN, 0, 18000);
jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
if (text !is null) {
text.xPos = play.xPos;
text.yPos = play.yPos;
text.ySpeed = -0.25;
text.string.text = "|+" + amount;
}
playHappySample(play);
}
obj.behavior = BEHAVIOR::EXPLOSION2;
obj.scriptedCollisions = false;
obj.frameID = 0;
}
return true;
}
}
class PowerOrb : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
obj.behave(BEHAVIOR::PICKUP);
obj.direction = 1;
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
SPACESHIP@ ship = Ships[play.playerID];
sendShipRotationPacket(ship);
ship.powerUp = true;
ship.powerTime = 30*70;
if (play.isLocal) {
jjSample(play.xPos, play.yPos, SOUND::BILSBOSS_FIRESTART, 0, 0);
playWarCry(play);
}
obj.behavior = BEHAVIOR::EXPLOSION2;
obj.scriptedCollisions = false;
obj.frameID = 0;
return true;
}
}
class ShipExplosion : jjBEHAVIORINTERFACE {
void onBehave(jjOBJ@ obj) {
obj.frameID++;
if (obj.frameID == 2 && jjGameTicks > 70) {
obj.particlePixelExplosion(1);
jjSample(obj.xPos, obj.yPos, SOUND::INTRO_BOEM2);
}
if (obj.frameID == 84) obj.delete();
jjDrawResizedSprite(obj.xPos, obj.yPos, ANIM::AMMO, 5, obj.frameID / 7, 2, 2, SPRITE::NORMAL);
}
}
void playHappySample(jjPLAYER@ play) {
switch (play.charCurr) {
case CHAR::JAZZ: jjSample(play.xPos, play.yPos, SOUND::JAZZSOUNDS_JUMMY, 0, 0); break;
case CHAR::SPAZ: jjSample(play.xPos, play.yPos, SOUND::SPAZSOUNDS_HAPPY, 0, 0); break;
case CHAR::LORI: jjSample(play.xPos, play.yPos, SOUND::LORISOUNDS_WEHOO, 0, 0); break;
default: break;
}
}
void playWarCry(jjPLAYER@ play) {
switch (play.charCurr) {
case CHAR::JAZZ: jjSample(play.xPos, play.yPos, SOUND::JAZZSOUNDS_IDLE, 0, 0); break;
case CHAR::SPAZ: jjSample(play.xPos, play.yPos, SOUND::SPAZSOUNDS_HAHAHA, 0, 0); break;
case CHAR::LORI: jjSample(play.xPos, play.yPos, SOUND::LORISOUNDS_LORIBOOM, 0, 0); break;
default: break;
}
}
void handleOnPlayer(jjPLAYER@ play) {
SPACESHIP@ ship = Ships[play.playerID];
if (jjKey[0x71]) {
if (!showInstructions) {
if (!pressOnce[0]) {
showInstructions = true;
pressOnce[0] = true;
}
} else {
if (!pressOnce[0]) {
showInstructions = false;
pressOnce[0] = true;
}
}
} else {
pressOnce[0] = false;
}
if (showInstructions) {
if (jjKey[0xBC]) {
if (!pressOnce[1]) {
if (currPage == 1) {
currPage = 3;
} else {
currPage--;
}
pressOnce[1] = true;
}
} else {
pressOnce[1] = false;
}
if (jjKey[0xBE]) {
if (!pressOnce[2]) {
if (currPage == 3) {
currPage = 1;
} else {
currPage++;
}
pressOnce[2] = true;
}
} else {
pressOnce[2] = false;
}
}
if (ship.hasShip) {
play.spriteMode = SPRITE::INVISIBLE;
play.ballTime = 1;
play.direction = 1;
play.fly = FLIGHT::NONE;
play.jumpStrength = 0;
jjCharacters[play.charCurr].airJump = AIR::NONE;
if (play.blink != 0) {
ship.health = ship.SDPunishment? 1:maxHealth;
} else ship.SDPunishment = false;
if (play.health == 0) {
ship.health = ship.SDPunishment? 1:maxHealth;
ship.armor = 0;
}
if (ship.health > maxHealth && jjGameTicks % (ship.health > int(maxHealth*1.5) && ship.health < (maxHealth*2)? 28:70) == 0 && play.blink == 0 && jjGameState != GAME::STOPPED) {
ship.health--;
}
if (ship.armor < 0) ship.armor = 0;
if (ship.armor > maxHealth && jjGameTicks % (ship.armor > int(maxHealth*1.5) && ship.armor < (maxHealth*2)? 28:70) == 0 && play.blink == 0 && jjGameState != GAME::STOPPED) {
ship.armor--;
}
if (jjMaxHealth == 1) {
ship.health = 1;
ship.armor = 0;
}
if (ship.health > (maxHealth*2)) {
ship.health = (maxHealth*2);
}
if (ship.armor > (maxHealth*2)) {
ship.armor = (maxHealth*2);
}
switch (play.currWeapon) {
case WEAPON::BLASTER:
if (currentWeapon == 1) play.fastfire = jjMaxHealth == 1? 45:14;
break;
case WEAPON::BOUNCER:
if (currentWeapon == 2) play.fastfire = 6;
break;
case WEAPON::ICE:
if (currentWeapon == 3) play.fastfire = 55;
break;
case WEAPON::SEEKER:
if (currentWeapon == 4) play.fastfire = 73;
break;
case WEAPON::RF:
if (currentWeapon == 5) play.fastfire = 110;
break;
case WEAPON::TOASTER:
if (currentWeapon == 6) play.fastfire = 4;
break;
case WEAPON::TNT:
if (currentWeapon == 7) play.fastfire = 70;
break;
case WEAPON::GUN8:
if (currentWeapon == 8) play.fastfire = 32;
break;
case WEAPON::GUN9:
if (currentWeapon == 9) play.fastfire = 12;
break;
default: break;
}
while (play.ammo[currentWeapon] == 0 && play.currWeapon != WEAPON::BLASTER) {
currentWeapon--;
play.currWeapon = currentWeapon;
}
if (ship.powerUp) {
if (jjGameState != GAME::STOPPED) ship.powerTime--;
for (int i = 1; i <= 9; i++) {
play.powerup[i] = true;
}
} else {
for (int i = 1; i <= 9; i++) {
play.powerup[i] = false;
}
}
if (ship.powerTime <= 0 && ship.powerUp) {
ship.powerTime = 0;
ship.powerUp = false;
if (play.isLocal) jjSample(play.xPos, play.yPos, SOUND::COMMON_SHLDOF3, 0, 0);
}
play.xAcc = play.yAcc = 0;
if (jjMaxHealth == 1) {
for (int i = 2; i <= 9; i++) {
play.ammo[i] = 0;
}
}
if (play.health > 0) {
play.xSpeed = ship.xSpeed;
play.ySpeed = ship.ySpeed;
if (ship.ySpeed < 0.05 && ship.ySpeed > -0.05) {
ship.ySpeed = 0;
}
if (ship.ySpeed == 0) {
play.ySpeed = 0;
play.yPos -= 0.125f;
}
if (ship.xSpeed < 0.05 && ship.xSpeed > -0.05) {
ship.xSpeed = 0;
}
if (ship.xSpeed == 0) {
play.xSpeed = 0;
if (play.keyRight && !jjMaskedPixel(int(play.xPos-16), int(play.yPos))) play.xPos -= (play.keyRun? 0.368f : 0.183f);
if (play.keyLeft && !jjMaskedPixel(int(play.xPos+16), int(play.yPos))) play.xPos += (play.keyRun? 0.368f : 0.183f);
}
}
if (jjGameTicks % 70 < 69) {
if (ship.rotationSpeed != 0) {
ship.rotating = true;
}
}
if (jjGameTicks % 70 == 69 && (ship.rotating || play.health == 0 || ship.wasHit)) {
sendShipRotationPacket(ship);
ship.rotating = false;
ship.wasHit = false;
}
if (play.ySpeed > (play.keyRun? 8:6)) play.ySpeed = (play.keyRun? 8:6);
if (play.ySpeed < -6 && !play.keyRun) play.ySpeed = -6;
if (!ship.reverse) {
if (ship.xAcc < 0) ship.xAcc = 0;
if (ship.yAcc < 0) ship.yAcc = 0;
}
if (ship.thrust && !ship.reverse) {
if (!ship.justHit) {
ship.xSpeed = (jjCos(ship.angle) * ship.xAcc) + ship.xMomentum;
ship.ySpeed = (-jjSin(ship.angle) * ship.yAcc) + ship.yMomentum;
}
if (ship.xMomentum > 0) ship.xMomentum -= 0.05;
if (ship.xMomentum < 0) ship.xMomentum += 0.05;
if (ship.yMomentum > 0) ship.yMomentum -= 0.05;
if (ship.yMomentum < 0) ship.yMomentum += 0.05;
if (ship.xAcc < (play.keyRun? ship.maxSpeed:ship.maxTurningSpeed)) ship.xAcc += 0.2;
if (ship.yAcc < (play.keyRun? ship.maxSpeed:ship.maxTurningSpeed)) ship.yAcc += 0.2;
if (ship.rotationSpeed != 0) {
if (ship.xAcc > (play.keyRun? ship.maxTurningSpeed:4)) ship.xAcc -= 0.25;
if (ship.yAcc > (play.keyRun? ship.maxTurningSpeed:4)) ship.yAcc -= 0.25;
}
} else {
if (ship.reverse && !ship.thrust) {
if (!ship.justHit) {
ship.xSpeed = (jjCos(ship.angle) * ship.xAcc) + ship.xMomentum;
ship.ySpeed = (-jjSin(ship.angle) * ship.yAcc) + ship.yMomentum;
}
if (ship.xMomentum > 0) ship.xMomentum -= 0.1;
if (ship.xMomentum < 0) ship.xMomentum += 0.1;
if (ship.yMomentum > 0) ship.yMomentum -= 0.1;
if (ship.yMomentum < 0) ship.yMomentum += 0.1;
if (ship.xAcc > (play.keyRun? -ship.maxSpeedRev:-ship.maxTurningSpeedRev)) ship.xAcc -= 0.085;
if (ship.yAcc > (play.keyRun? -ship.maxSpeedRev:-ship.maxTurningSpeedRev)) ship.yAcc -= 0.085;
if (ship.rotationSpeed != 0) {
if (ship.xAcc < (play.keyRun? -ship.maxTurningSpeedRev:-3)) ship.xAcc += 0.25;
if (ship.yAcc < (play.keyRun? -ship.maxTurningSpeedRev:-3)) ship.yAcc += 0.25;
}
} else {
ship.xMomentum = play.xSpeed * 0.75;
ship.yMomentum = play.ySpeed * 0.75;
if (jjMaskedHLine(int(play.xPos + ship.xSpeed), -32, int(play.yPos)) || jjMaskedHLine(int(play.xPos - ship.xSpeed), 32, int(play.yPos))) {
ship.xSpeed = ship.xAcc = ship.xMomentum = 0;
}
if (jjMaskedVLine(int(play.xPos), int(play.yPos + ship.ySpeed), -32) || jjMaskedVLine(int(play.xPos), int(play.yPos - ship.ySpeed), 32)) {
ship.ySpeed = ship.yAcc = ship.yMomentum = 0;
}
if (ship.xMomentum > ship.maxSpeed) ship.xMomentum = ship.maxSpeed;
if (ship.xMomentum < -ship.maxSpeed) ship.xMomentum = -ship.maxSpeed;
if (ship.yMomentum > ship.maxSpeed) ship.yMomentum = ship.maxSpeed;
if (ship.yMomentum < -ship.maxSpeed) ship.yMomentum = -ship.maxSpeed;
if (ship.xSpeed > 0) ship.xSpeed -= 0.05;
else if (ship.xSpeed < 0) ship.xSpeed += 0.05;
if (ship.ySpeed > 0) ship.xSpeed -= 0.05;
else if (ship.ySpeed < 0) ship.ySpeed += 0.05;
if (ship.xAcc > (ship.xSpeed * (ship.xSpeed > 0? -1:1))) {
ship.xAcc -= 0.25;
}
if (ship.yAcc > (ship.ySpeed * (ship.ySpeed > 0? -1:1))) {
ship.yAcc -= 0.25;
}
if (ship.ySpeed > 0 && ship.ySpeed < ship.maxSpeed && ship.yAcc <= 0 ) {
ship.ySpeed -= 0.025;
}
if (play.keyDown) {
ship.xAcc = ship.yAcc = 0;
}
}
}
play.buttstomp = 100;
if (play.xSpeed > ship.maxSpeed) play.xSpeed = ship.maxSpeed;
if (play.xSpeed < -ship.maxSpeed) play.xSpeed = -ship.maxSpeed;
if (play.ySpeed > ship.maxSpeed) play.ySpeed = ship.maxSpeed;
if (play.ySpeed < -ship.maxSpeed) play.ySpeed = -ship.maxSpeed;
if (play.xSpeed > ship.maxDiagonalSpeed && play.ySpeed > ship.maxDiagonalSpeed) {
play.xSpeed = ship.maxDiagonalSpeed;
play.ySpeed = ship.maxDiagonalSpeed;
}
if (play.xSpeed > ship.maxDiagonalSpeed && play.ySpeed < -ship.maxDiagonalSpeed) {
play.xSpeed = ship.maxDiagonalSpeed;
play.ySpeed = -ship.maxDiagonalSpeed;
}
if (play.xSpeed < -ship.maxDiagonalSpeed && play.ySpeed > ship.maxDiagonalSpeed) {
play.xSpeed = -ship.maxDiagonalSpeed;
play.ySpeed = ship.maxDiagonalSpeed;
}
if (play.xSpeed < -ship.maxDiagonalSpeed && play.ySpeed < -ship.maxDiagonalSpeed) {
play.xSpeed = -ship.maxDiagonalSpeed;
play.ySpeed = -ship.maxDiagonalSpeed;
}
if (jjMaskedPixel(int(play.xPos) + int(ship.xSpeed), int(play.yPos) + int(ship.ySpeed)) && !ship.thrust) {
ship.xAcc = ship.yAcc = ship.xMomentum = ship.yMomentum = 0;
}
if (jjMouseAim && jjAllowsMouseAim) {
int screenLimitX = (jjLayerWidth[4]*32)-400;
int screenLimitY = (jjLayerHeight[4]*32)-400;
int screenCentreX = (int(play.xPos) <= 400)? int(play.xPos) : int(play.xPos) >= screenLimitX? int(jjSubscreenWidth / 2) + int(abs(screenLimitX - int(play.xPos))) : int(jjSubscreenWidth / 2);
int screenCentreY = (int(play.yPos) <= 400)? int(play.yPos) : int(play.yPos) >= screenLimitY? int(jjSubscreenHeight / 2) + int(abs(screenLimitY - int(play.yPos))) : int(jjSubscreenHeight / 2);
ship.fireAngle = int(atan2(jjMouseY - screenCentreY, -(jjMouseX - screenCentreX)) * (512 / PI)) - 512;
} else {
ship.fireAngle = ship.angle;
}
if (play.keyFire && !ship.fire) {
play.fireBullet(WEAPON::CURRENT, true, true, ((ship.fireAngle+256+(play.currWeapon == WEAPON::TOASTER? 512:0))/512) * -PI);
ship.fire = true;
currentWeapon = play.currWeapon;
}
if (play.keyFire && play.currWeapon == WEAPON::TOASTER && play.ammo[WEAPON::TOASTER] > 0) {
ship.sample2 = jjSampleLooped(play.xPos, play.yPos, SOUND::COMMON_FLAMER, ship.sample2);
}
if (ship.fire) {
ship.fireDelay++;
if (ship.fireDelay >= play.fastfire) {
ship.fire = false;
ship.fireDelay = 0;
ship.stopWeaponChange = false;
}
if (play.currWeapon != currentWeapon) {
play.currWeapon = currentWeapon;
ship.stopWeaponChange = true;
}
} else {
ship.stopWeaponChange = false;
if (jjGameTicks % 18 == 0) {
if (play.ammo[WEAPON::BLASTER] < jjWeapons[WEAPON::BLASTER].maximum) {
play.ammo[WEAPON::BLASTER] = play.ammo[WEAPON::BLASTER] + 1;
}
}
}
if (play.ammo[WEAPON::BLASTER] < 1 && play.currWeapon != WEAPON::BLASTER) {
play.ammo[WEAPON::BLASTER] = 1;
}
if (jjKey[0x01] && jjKey[0x12]) {
radarX = int(jjMouseX);
radarY = int(jjMouseY);
}
if (jjKey[0x02] && jjKey[0x12]) {
radarX = 100;
radarY = jjSubscreenHeight - 220;
}
if (crosshairFlash) {
crosshairTime++;
if (crosshairTime > 21) crosshairFlash = false;
}
} else {
play.spriteMode = SPRITE::PLAYER;
jjCharacters[play.charCurr].airJump = AIR::DOUBLEJUMP;
play.jumpStrength = -10;
}
active = play.isInGame;
if (jjMaxHealth == 1) {
play.currWeapon = currentWeapon = 1;
}
}
void spawnFireTrail(jjPLAYER@ play, SPACESHIP@ ship) {
jjOBJ@ trail = jjObjects[jjAddObject(OBJECT::EXPLOSION, int(play.xPos - jjCos(ship.angle)), int(play.yPos - jjSin(ship.angle)))];
trail.determineCurAnim(ANIM::AMMO, !ship.reverse? 3:2);
trail.lightType = ship.reverse? LIGHT::NONE : LIGHT::POINT;
trail.playerHandling = HANDLING::PARTICLE;
trail.bulletHandling = HANDLING::IGNOREBULLET;
trail.isBlastable = false;
}
void damagedShipTrail(jjPLAYER@ play) {
jjPARTICLE@ cinders = jjAddParticle(PARTICLE::SMOKE);
cinders.xPos = (play.xPos - 16) + jjRandom()%32;
cinders.yPos = (play.yPos - 16) + jjRandom()%32;
cinders.ySpeed = -1;
}
void randomHurtSample(jjPLAYER@ play, int volume) {
SOUND::Sample sample = SOUND::JAZZSOUNDS_HEY2;
switch (jjRandom()%4) {
case 0: sample = play.charCurr == CHAR::JAZZ? SOUND::JAZZSOUNDS_HEY2 : play.charCurr == CHAR::SPAZ? SOUND::SPAZSOUNDS_AUTSCH1 : SOUND::LORISOUNDS_HURT0; break;
case 1: sample = play.charCurr == CHAR::JAZZ? SOUND::JAZZSOUNDS_HEY3 : play.charCurr == CHAR::SPAZ? SOUND::SPAZSOUNDS_AUTSCH2 : SOUND::LORISOUNDS_HURT1; break;
case 2: sample = play.charCurr == CHAR::JAZZ? SOUND::JAZZSOUNDS_HEY4 : play.charCurr == CHAR::SPAZ? SOUND::SPAZSOUNDS_AUTSCH1 : SOUND::LORISOUNDS_HURT2; break;
case 3: sample = play.charCurr == CHAR::JAZZ? SOUND::JAZZSOUNDS_JAZZV4 : play.charCurr == CHAR::SPAZ? SOUND::SPAZSOUNDS_OOOH : SOUND::LORISOUNDS_HURT7; break;
}
jjSample(play.xPos, play.yPos, sample, volume, 0);
}
void handleOnMain() {
for (int i = 1; i <= 9; i++) {
if (jjWeapons[i].allowed)
jjWeapons[i].allowedPowerup = true;
}
switch (jjMaxHealth) {
case 1: maxHealth = 1; break;
case 2: maxHealth = 50; break;
case 3: maxHealth = jjGameMode == GAME::CTF? 100:70; break;
case 4: maxHealth = jjGameMode == GAME::CTF? 125:85; break;
case 5: maxHealth = jjGameMode == GAME::CTF? 150:100; break;
case 6: maxHealth = jjGameMode == GAME::CTF? 175:150; break;
case 7: maxHealth = 200; break;
}
if (!jjLocalPlayers[0].isIdle) {
for (int i = 0; i < 32; i++) {
jjPLAYER@ play = jjPlayers[i];
if (!play.isInGame)
continue;
SPACESHIP@ ship = Ships[i];
if (ship.justHit) {
ship.hitDelay++;
if (ship.hitDelay >= 7) {
ship.justHit = false;
ship.wasHit = true;
}
}
if (ship.hasShip) {
if (play.powerup[WEAPON::TNT]) {
ship.tntPowerup = true;
} else {
if (!ship.powerUp) {
ship.tntPowerup = false;
}
}
if (ship.damageAccumulated > 0) {
ship.accumulationTime++;
if (ship.accumulationTime == 210) {
ship.damageAccumulated = ship.accumulationTime = 0;
}
}
play.lightType = ship.health > maxHealth? LIGHT::LASER : (ship.armor > maxHealth? LIGHT::BRIGHT : LIGHT::PLAYER);
play.light = 12;
if (ship.powerUp) {
jjDrawRotatedSprite(play.xPos, play.yPos, customAnimID, ship.anim, 0, ship.angle - 256, 1.25, 1.25, ship.justHit? SPRITE::SINGLECOLOR : SPRITE::TRANSLUCENTCOLOR, ship.justHit? 15 : 24 + (jjGameTicks % 7), 4, 4);
}
if (ship.thrust || ship.reverse) {
if (!ship.reverse) {
if (jjGameTicks % (play.keyRun? 4:8) == 0) spawnFireTrail(play, ship);
} else {
if (jjGameTicks % (play.keyRun? 8:12) == 0) spawnFireTrail(play, ship);
}
if (play.isLocal) ship.sample = jjSampleLooped(play.xPos, play.yPos, SOUND::FAN_FAN, ship.sample, 24, (play.keyRun? 8000:7500));
}
if (jjGameTicks % 3 == 0 && ship.health <= int(maxHealth*0.3)) damagedShipTrail(play);
ship.thrust = play.keyUp;
ship.reverse = play.keyDown;
ship.angle = ship.angle + ship.rotationSpeed;
if (ship.angle >= 1024) ship.angle = 0;
else if (ship.angle <= -1024) ship.angle = 0;
if (play.keyRight) {
ship.rotationSpeed = (ship.preciseTurn || play.keyJump? 0 : int(ship.rotationAcc)) + (play.keyRun && jjGameTicks % 2 == 0? -4 : -3);
if (ship.rotationAcc > -12) ship.rotationAcc -= 0.5;
if (ship.rotationAcc > 0) ship.rotationAcc = 0;
} else if (play.keyLeft) {
ship.rotationSpeed = (ship.preciseTurn || play.keyJump? 0 : int(ship.rotationAcc)) + (play.keyRun && jjGameTicks % 2 == 0? 4 : 3);
if (ship.rotationAcc < 12) ship.rotationAcc += 0.5;
if (ship.rotationAcc < 0) ship.rotationAcc = 0;
}
else {
ship.rotationSpeed = 0;
ship.rotationAcc = 0;
}
switch (play.charCurr) {
case CHAR::JAZZ: ship.anim = 0; break;
case CHAR::SPAZ: ship.anim = 1; break;
case CHAR::LORI: ship.anim = 2; break;
default: ship.anim = 0; break;
}
if (play.health > 0 && play.isInGame) {
if (jjGameTicks % 7 == 0 || play.blink == 0) {
jjDrawRotatedSprite(play.xPos, play.yPos, customAnimID, ship.anim, 0, ship.angle - 256, 1, 1, ship.justHit? SPRITE::SINGLECOLOR : SPRITE::PLAYER, ship.justHit? 15 : play.playerID, 4, 4);
if (ship.armor > 0) {
jjDrawSprite(play.xPos, play.yPos, ANIM::MENU, 1, (ship.armor <= int(maxHealth*0.3)? 0 : ship.armor >= int(maxHealth*0.7)? 8 : 3), 0, SPRITE::ALPHAMAP, ship.armor > maxHealth? 34 : ship.armor >= int(maxHealth*0.7)? 80 : ship.armor > int(maxHealth*0.3)? 41 : 24);
}
}
} else if (play.health == 0 && play.isInGame) {
if (play.blink <= 0) {
play.blink = 210;
jjOBJ@ dummy = jjObjects[jjAddObject(OBJECT::PURPLEGEM, play.xPos, play.yPos)];
}
}
}
}
}
if (jjGameMode <= GAME::COOP)
return;
jjOBJ@ bogus = jjObjects[0];
bogus.creator = CREATOR::PLAYER;
for (uint playerID = 0; playerID < 32; ++playerID, ++bogus.creator) {
const jjPLAYER@ p = jjPlayers[playerID];
if (p.isInGame) {
bogus.xPos = p.xPos;
bogus.yPos = p.yPos;
closestPlayers[playerID] = MLLEWeapons::HelpfulBulletFunctions::GetNearestEnemyPlayer(bogus, 350);
}
}
}
void handleOnPlayerInput(jjPLAYER@ play) {
SPACESHIP@ ship = Ships[play.playerID];
if (play.keyJump) {
ship.preciseTurn = true;
play.keyJump = false;
} else {
ship.preciseTurn = false;
}
}
void handleOnReceive(jjSTREAM &in packet, int clientID) {
if (jjIsServer) {
int angle, health, armor;
bool hasShip, powerUp, preciseTurn;
packet.pop(angle);
packet.pop(health);
packet.pop(armor);
packet.pop(hasShip);
packet.pop(powerUp);
packet.pop(preciseTurn);
jjPLAYER@ play = jjPlayers[clientID];
Ships[play.playerID].angle = angle;
Ships[play.playerID].health = health;
Ships[play.playerID].armor = armor;
Ships[play.playerID].hasShip = hasShip;
Ships[play.playerID].powerUp = powerUp;
Ships[play.playerID].preciseTurn = preciseTurn;
updateShipAnglesForClients(clientID, angle, health, armor, hasShip, powerUp, preciseTurn);
} else {
int id, angle, health, armor;
bool hasShip, powerUp, preciseTurn;
packet.pop(id);
packet.pop(angle);
packet.pop(health);
packet.pop(armor);
packet.pop(hasShip);
packet.pop(powerUp);
packet.pop(preciseTurn);
jjPLAYER@ play = jjPlayers[id];
if (!play.isLocal) {
Ships[id].angle = angle;
Ships[id].health = health;
Ships[id].armor = armor;
Ships[id].hasShip = hasShip;
Ships[id].powerUp = powerUp;
Ships[id].preciseTurn = preciseTurn;
}
}
}
void sendShipRotationPacket(SPACESHIP@ ship) {
if (!jjIsServer) {
jjSTREAM packet;
packet.push(ship.angle);
packet.push(ship.health);
packet.push(ship.armor);
packet.push(ship.hasShip);
packet.push(ship.powerUp);
packet.push(ship.preciseTurn);
jjSendPacket(packet);
} else {
updateShipAnglesForClients(0, ship.angle, ship.health, ship.armor, ship.hasShip, ship.powerUp, ship.preciseTurn);
}
}
void updateShipAnglesForClients(int id, int angle, int health, int armor, bool hasShip, bool powerUp, bool preciseTurn) {
jjSTREAM packet;
packet.push(id);
packet.push(angle);
packet.push(health);
packet.push(armor);
packet.push(hasShip);
packet.push(powerUp);
packet.push(preciseTurn);
jjSendPacket(packet);
}
bool handleOnDrawAmmo(jjPLAYER@ play, jjCANVAS@ canvas) {
SPACESHIP@ ship = Ships[play.playerID];
int box_X = 64, box_Y = 64;
int boxWidth = jjSubscreenWidth - (box_X * 2);
int boxHeight = jjSubscreenHeight - (box_Y * 2);
array<string> controls = {
"||||Press |||||LEFT||| or |||||RIGHT||| to steer your ship and aim your weapon",
"",
"||||Press and hold |||||UP||| to activate your ship's thrusters",
"",
"||||Press and hold |||||DOWN||| to go into reverse",
"",
"||||Press and hold |||||RUN||| to move faster",
"",
"||||Press |||||FIRE||| to shoot",
"",
"||||Press and hold |||||JUMP||| while turning for more precise control",
"",
"||||Click and drag |||||LEFT MOUSE||| while holding |||||ALT||| to reposition",
"||||the ship's radar HUD",
"",
"||||Click |||||RIGHT MOUSE||| while holding |||||ALT||| to reset the ",
"||||ship's radar HUD position to default"
};
array<string> weaponNames = {
"|1. Blaster",
"|2. Rapid Blaster",
"|3. Burster",
"|4. Homing Missile",
"|5. Super Missile",
"|6. Flamethrower",
"|7. Spike Mine",
"|8. Laser Cannon",
"|9. Electro Blaster"
};
array<string> weaponDamages = {
"Damage: 15",
"Damage: 9",
"Damage: 25-75",
"Damage: 30",
"Damage: 100 (1-99 for explosion)",
"Damage: 6",
"Damage: 70 (1-69 for explosion)",
"Damage: 40",
"Damage: 15"
};
array<string> weaponMaxAmmo = {
"Max Ammo: 25 (regenerates)",
"Max Ammo: 100 (+5 per pickup)",
"Max Ammo: 25 (+2 per pickup)",
"Max Ammo: 15 (+2 per pickup)",
"Max Ammo: 10 (+1 per pickup)",
"Max Ammo: 50 (+3 per pickup)",
"Max Ammo: 10 (+1 per pickup)",
"Max Ammo: 25 (+2 per pickup)",
"Max Ammo: 50 (+3 per pickup)"
};
array<string> itemNames = {
"|||||Health Pack",
"|||||Mega Health Pack",
"|Shield",
"|Mega Shield",
"||Power Orb"
};
array<string> itemDescriptions = {
"Restores " + (maxHealth / 5) + " HP, but not beyond your maximum.",
"Restores " + maxHealth + " HP, up to twice your normal maximum HP.",
"Adds " + maxHealth / 2 + " Shield Points (SP), but not beyond your maximum.",
"Adds " + maxHealth + " SP, up to twice your normal maximum SP.",
"Temporarily powers up all of your weapons for 30 seconds (x2)."
};
array<int> itemSprites = {
6,7,3,4,5
};
canvas.drawSprite(
radarX,
radarY,
customAnimID,
8,
0,
0,
SPRITE::TRANSLUCENT
);
canvas.drawString(
radarX - 26,
radarY + 68,
"" + int(play.xPos)/32 + "," + int(play.yPos)/32,
STRING::SMALL,
STRING::PALSHIFT,
16
);
for (int i = 0; i < 32; i++) {
jjPLAYER@ player = jjPlayers[i];
uint8 teamColor;
uint8 radarColor;
switch (player.team) {
case TEAM::BLUE: teamColor = 34; break;
case TEAM::RED: teamColor = 24; break;
case TEAM::GREEN: teamColor = 18; break;
case TEAM::YELLOW: teamColor = 40; break;
default: teamColor = 24; break;
}
switch (jjGameMode) {
case GAME::CTF: radarColor = teamColor; break;
case GAME::BATTLE: radarColor = jjGameCustom == GAME::PEST? (player.isZombie? (play.isZombie? 73 : 24) : jjDoZombiesAlreadyExist? (play.isZombie? 24:73):24) : jjGameCustom == GAME::RT? (player is jjTokenOwner? 18 : player is jjBottomFeeder? 24 : 73) : 24; break;
default: radarColor = 24; break;
}
int radarOffsetX = int(play.xPos - player.xPos) / 30;
int radarOffsetY = int(play.yPos - player.yPos) / 30;
float dx = player.xPos - play.xPos, dy = player.yPos - play.yPos;
if (dx * dx + dy * dy < 1800 * 1800) {
if (radarOffsetX < 70 && radarOffsetX > -63 && radarOffsetY < 70 && radarOffsetY > -63 && player.xPos > 0 && player.yPos > 0 && !play.isSpectating && !play.isOut && !play.isConnecting) {
if (player.flag != 0) {
canvas.drawResizedSprite(
((radarX + 2) - radarOffsetX),
((radarY + 2) - radarOffsetY),
ANIM::FLAG,
3,
jjGameTicks >> 2,
radarOffsetX > 0? 0.4:-0.4,
0.4,
SPRITE::SINGLECOLOR,
player.team == TEAM::BLUE? 24 : 34
);
canvas.drawRectangle(
((radarX - 4) - radarOffsetX),
((radarY - 4) - radarOffsetY),
player.isLocal? 8:6,
player.isLocal? 8:6,
player.isLocal? 80 : radarColor,
SPRITE::NORMAL
);
}
else if (player.flag == 0) {
canvas.drawRectangle(
((radarX - 4) - radarOffsetX),
((radarY - 4) - radarOffsetY),
player.isLocal? 8:5,
player.isLocal? 8:5,
player.isLocal? 80 : radarColor,
SPRITE::NORMAL
);
}
}
}
}
if (showInstructions) {
canvas.drawRectangle(
box_X,
box_Y,
boxWidth,
boxHeight,
95,
SPRITE::TRANSLUCENT
);
canvas.drawString(
box_X + 12,
box_Y + 32,
"|||Spaceships: A Guide",
STRING::LARGE,
STRING::NORMAL
);
if (currPage == 1) {
canvas.drawString(
box_X + 12,
box_Y + 96,
"Script written by PurpleJazz",
STRING::MEDIUM,
STRING::PALSHIFT,
24
);
canvas.drawString(
box_X + 12,
box_Y + 128,
"Controls",
STRING::MEDIUM,
STRING::NORMAL
);
for (uint i = 0; i < controls.length(); i++) {
canvas.drawString(
box_X + 12,
box_Y + 160 + (16*i),
controls[i],
STRING::SMALL,
STRING::NORMAL
);
}
}
if (currPage == 2) {
canvas.drawString(
box_X + 12,
box_Y + 96,
"Weapons",
STRING::MEDIUM,
STRING::NORMAL
);
for (uint i = 0; i < 5; i++) {
canvas.drawString(
[preview ends here]
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.