Downloads containing Spaceship v1-00.asc

Downloads
Name Author Game Mode Rating
JJ2+ Only: Spaceships (v1.00) PurpleJazz Custom / Concept N/A Download file

File preview

  1. #pragma require "Spaceship.j2a"
  2. #pragma require "Spaceship v1-00.asc"
  3. #pragma require "Silence.wav"
  4. #include "Resize v11.asc"
  5. #include "MLLE-Weapons.asc"
  6.  
  7. namespace Spaceship {
  8.         bool animsLoaded = false;
  9.         uint customAnimID = 0;
  10.  
  11.         class SPACESHIP {
  12.                 float xSpeed, ySpeed, xAcc, yAcc, xMomentum, yMomentum, fireAngle, momentum = 0;
  13.                 float maxSpeed = 9.5;
  14.                 float maxTurningSpeed = 7;
  15.                 float maxSpeedRev = 6;
  16.                 float maxTurningSpeedRev = 4.5;
  17.                 float maxDiagonalSpeed = 8;
  18.                 float rotationAcc = 0;
  19.                
  20.                 int health, anim, angle, rotationSpeed, sample, sample2, fireDelay, hitDelay, armor, damageAccumulated, accumulationTime;
  21.                 int powerTime = 30*70;
  22.                
  23.                 int damageCalc(SPACESHIP@ ship, int animSpeed) {
  24.                         if (ship.armor >= animSpeed) {
  25.                                 return (animSpeed / 3);
  26.                         } else {
  27.                                 return (animSpeed - (ship.armor / 3 * 2));
  28.                         }
  29.                 }
  30.                
  31.                 bool thrust, reverse, rotating, preciseTurn, fire, justHit, wasHit, stopWeaponChange, powerUp, SDPunishment, tntPowerup = false;
  32.                 bool hasShip = true;
  33.  
  34.                 SPACESHIP(){}
  35.         };
  36.         array<SPACESHIP> Ships(32);
  37.  
  38.         const float PI = 3.1415926535f;
  39.         int xPos = 0, yPos = 0, cameraX = 0, cameraY = 0, radarX = 100, radarY = jjSubscreenHeight - 220;
  40.         array<int> closestPlayers(32, -1); //needed even for non-local players
  41.         uint8 currentWeapon = 1;
  42.  
  43.         bool crosshairFlash = false;
  44.         int crosshairTime = 0;
  45.  
  46.         bool gameIsActive() {
  47.                 return jjGameState == GAME::STARTED || jjGameState == GAME::OVERTIME;
  48.         }
  49.  
  50.         bool canBeHit(jjPLAYER@ play, jjPLAYER@ creator, jjOBJ@ obj) {
  51.                 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();
  52.         }
  53.  
  54.         float recoilX(SPACESHIP@ ship, jjOBJ@ obj, float recoil) {
  55.                 return ((obj.xSpeed / (ship.thrust? 16:128)) * recoil);
  56.         }
  57.  
  58.         float recoilY(SPACESHIP@ ship, jjOBJ@ obj, float recoil) {
  59.                 return ((obj.ySpeed / (ship.thrust? 16:128)) * recoil);
  60.         }
  61.  
  62.         int teamColor(jjPLAYER@ play) {
  63.                 if (play.team == TEAM::BLUE) return 32;
  64.                 if (play.team == TEAM::RED) return 24;
  65.                 if (play.team == TEAM::YELLOW) return 40;
  66.                 if (play.team == TEAM::GREEN) return 16;
  67.                
  68.                 return 32;
  69.         }
  70.  
  71.         bool isAlly(jjPLAYER@ creator, jjPLAYER@ play) {
  72.                 return !creator.isLocal && jjGameMode == GAME::CTF && creator.team == play.team;
  73.         }
  74.  
  75.         bool active = true;
  76.        
  77.         int maxHealth;
  78.        
  79.         bool showInstructions = false;
  80.         array<bool> pressOnce(3, false);
  81.         int currPage = 1;
  82.  
  83.         void handleOnLevelLoad() {
  84.                 if (!animsLoaded) {
  85.                         animsLoaded = true;
  86.                         while (jjAnimSets[ANIM::CUSTOM[customAnimID]] != 0)
  87.                                 ++customAnimID;
  88.                         customAnimID = ANIM::CUSTOM[customAnimID];
  89.                         jjAnimSets[customAnimID].load(0, "Spaceship.j2a");
  90.                 }
  91.                
  92.                 jjAnimSets[ANIM::DEVAN].load();
  93.                 jjAnimSets[ANIM::MENU].load();
  94.                
  95.                 jjWeapons[WEAPON::BLASTER].infinite = false;
  96.                 jjWeapons[WEAPON::BLASTER].maximum = 25;
  97.                 jjWeapons[WEAPON::BLASTER].defaultSample = false;
  98.                
  99.                 jjObjectPresets[OBJECT::BLASTERBULLET].xSpeed = jjObjectPresets[OBJECT::BLASTERBULLET].xSpeed * -2.5;
  100.                 jjObjectPresets[OBJECT::BLASTERBULLET].ySpeed = 0;
  101.                 jjObjectPresets[OBJECT::BLASTERBULLET].xAcc = 0;
  102.                 jjObjectPresets[OBJECT::BLASTERBULLET].yAcc = 0;
  103.                 jjObjectPresets[OBJECT::BLASTERBULLET].counterEnd = 65;
  104.                 jjObjectPresets[OBJECT::BLASTERBULLET].behavior = Blaster();
  105.                 jjObjectPresets[OBJECT::BLASTERBULLET].special = jjObjectPresets[OBJECT::BLASTERBULLET].determineCurAnim(ANIM::DEVAN, 0);
  106.                 jjObjectPresets[OBJECT::BLASTERBULLET].determineCurFrame();
  107.                 jjObjectPresets[OBJECT::BLASTERBULLET].scriptedCollisions = true;
  108.                 jjObjectPresets[OBJECT::BLASTERBULLET].playerHandling = HANDLING::SPECIAL;
  109.                 jjObjectPresets[OBJECT::BLASTERBULLET].animSpeed = 15;
  110.                 jjObjectPresets[OBJECT::BLASTERBULLET].triggersTNT = true;
  111.                
  112.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].xSpeed = jjObjectPresets[OBJECT::BLASTERBULLETPU].xSpeed * -2.5;
  113.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].ySpeed = 0;
  114.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].xAcc = 0;
  115.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].yAcc = 0;
  116.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].counterEnd = 65;
  117.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].behavior = Blaster();
  118.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].special = jjObjectPresets[OBJECT::BLASTERBULLETPU].determineCurAnim(ANIM::DEVAN, 0);
  119.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].determineCurFrame();
  120.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].scriptedCollisions = true;
  121.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].playerHandling = HANDLING::SPECIAL;
  122.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].animSpeed = 30;
  123.                 jjObjectPresets[OBJECT::BLASTERBULLETPU].triggersTNT = true;
  124.                
  125.                 jjWeapons[WEAPON::BOUNCER].maximum = 100;
  126.                 jjWeapons[WEAPON::BOUNCER].defaultSample = false;
  127.                
  128.                 jjObjectPresets[OBJECT::BOUNCERBULLET].xSpeed = jjObjectPresets[OBJECT::BOUNCERBULLET].xSpeed * -3;
  129.                 jjObjectPresets[OBJECT::BOUNCERBULLET].ySpeed = 0;
  130.                 jjObjectPresets[OBJECT::BOUNCERBULLET].xAcc = 0;
  131.                 jjObjectPresets[OBJECT::BOUNCERBULLET].yAcc = 0;
  132.                 jjObjectPresets[OBJECT::BOUNCERBULLET].counterEnd = 70;
  133.                 jjObjectPresets[OBJECT::BOUNCERBULLET].behavior = RapidBlaster();
  134.                 jjObjectPresets[OBJECT::BOUNCERBULLET].special = jjObjectPresets[OBJECT::BOUNCERBULLET].determineCurAnim(ANIM::AMMO, 27);
  135.                 jjObjectPresets[OBJECT::BOUNCERBULLET].determineCurFrame();
  136.                 jjObjectPresets[OBJECT::BOUNCERBULLET].scriptedCollisions = true;
  137.                 jjObjectPresets[OBJECT::BOUNCERBULLET].playerHandling = HANDLING::SPECIAL;
  138.                 jjObjectPresets[OBJECT::BOUNCERBULLET].animSpeed = 9;
  139.                
  140.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].xSpeed = jjObjectPresets[OBJECT::BOUNCERBULLETPU].xSpeed * -3;
  141.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].ySpeed = 0;
  142.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].xAcc = 0;
  143.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].yAcc = 0;
  144.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].counterEnd = 70;
  145.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].behavior = RapidBlaster();
  146.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].special = jjObjectPresets[OBJECT::BOUNCERBULLETPU].determineCurAnim(ANIM::AMMO, 60);
  147.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].determineCurFrame();
  148.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].scriptedCollisions = true;
  149.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].playerHandling = HANDLING::SPECIAL;
  150.                 jjObjectPresets[OBJECT::BOUNCERBULLETPU].animSpeed = 18;
  151.                
  152.                 jjWeapons[WEAPON::ICE].maximum = 25;
  153.                 jjWeapons[WEAPON::ICE].defaultSample = false;
  154.                 jjWeapons[WEAPON::ICE].spread = SPREAD::RFPU;
  155.                
  156.                 jjObjectPresets[OBJECT::ICEBULLET].xSpeed = jjObjectPresets[OBJECT::ICEBULLET].xSpeed * -3;
  157.                 jjObjectPresets[OBJECT::ICEBULLET].ySpeed = 0;
  158.                 jjObjectPresets[OBJECT::ICEBULLET].xAcc = 0;
  159.                 jjObjectPresets[OBJECT::ICEBULLET].yAcc = 0;
  160.                 jjObjectPresets[OBJECT::ICEBULLET].counterEnd = 30;
  161.                 jjObjectPresets[OBJECT::ICEBULLET].freeze = 0;
  162.                 jjObjectPresets[OBJECT::ICEBULLET].var[7] = 0;
  163.                 jjObjectPresets[OBJECT::ICEBULLET].behavior = IceBurster();
  164.                 jjObjectPresets[OBJECT::ICEBULLET].special = jjObjectPresets[OBJECT::ICEBULLET].determineCurAnim(ANIM::PICKUPS, 45);
  165.                 jjObjectPresets[OBJECT::ICEBULLET].determineCurFrame();
  166.                 jjObjectPresets[OBJECT::ICEBULLET].scriptedCollisions = true;
  167.                 jjObjectPresets[OBJECT::ICEBULLET].playerHandling = HANDLING::SPECIAL;
  168.                 jjObjectPresets[OBJECT::ICEBULLET].animSpeed = 25;
  169.                
  170.                 jjObjectPresets[OBJECT::ICEBULLETPU].xSpeed = jjObjectPresets[OBJECT::ICEBULLETPU].xSpeed * -3;
  171.                 jjObjectPresets[OBJECT::ICEBULLETPU].ySpeed = 0;
  172.                 jjObjectPresets[OBJECT::ICEBULLETPU].xAcc = 0;
  173.                 jjObjectPresets[OBJECT::ICEBULLETPU].yAcc = 0;
  174.                 jjObjectPresets[OBJECT::ICEBULLETPU].counterEnd = 30;
  175.                 jjObjectPresets[OBJECT::ICEBULLETPU].freeze = 0;
  176.                 jjObjectPresets[OBJECT::ICEBULLETPU].var[7] = 0;
  177.                 jjObjectPresets[OBJECT::ICEBULLETPU].behavior = IceBurster();
  178.                 jjObjectPresets[OBJECT::ICEBULLETPU].special = jjObjectPresets[OBJECT::ICEBULLETPU].determineCurAnim(ANIM::PICKUPS, 45);
  179.                 jjObjectPresets[OBJECT::ICEBULLETPU].determineCurFrame();
  180.                 jjObjectPresets[OBJECT::ICEBULLETPU].scriptedCollisions = true;
  181.                 jjObjectPresets[OBJECT::ICEBULLETPU].playerHandling = HANDLING::SPECIAL;
  182.                 jjObjectPresets[OBJECT::ICEBULLETPU].animSpeed = 50;
  183.                 jjObjectPresets[OBJECT::ICEBULLETPU].killAnim = jjObjectPresets[OBJECT::RFBULLET].killAnim;
  184.                
  185.                 jjWeapons[WEAPON::SEEKER].maximum = 15;
  186.                
  187.                 jjObjectPresets[OBJECT::SEEKERBULLET].xSpeed = jjObjectPresets[OBJECT::SEEKERBULLET].xSpeed * -5;
  188.                 jjObjectPresets[OBJECT::SEEKERBULLET].ySpeed = jjObjectPresets[OBJECT::SEEKERBULLET].ySpeed * 5;
  189.                 jjObjectPresets[OBJECT::SEEKERBULLET].xAcc = 0;
  190.                 jjObjectPresets[OBJECT::SEEKERBULLET].yAcc = 0;
  191.                 jjObjectPresets[OBJECT::SEEKERBULLET].counterEnd = 160;
  192.                 jjObjectPresets[OBJECT::SEEKERBULLET].lightType = jjObjectPresets[OBJECT::BLASTERBULLET].lightType;
  193.                 jjObjectPresets[OBJECT::SEEKERBULLET].behavior = HomingMissile();
  194.                 jjObjectPresets[OBJECT::SEEKERBULLET].special = jjObjectPresets[OBJECT::SEEKERBULLET].determineCurAnim(ANIM::AMMO, 37);
  195.                 jjObjectPresets[OBJECT::SEEKERBULLET].determineCurFrame();
  196.                 jjObjectPresets[OBJECT::SEEKERBULLET].killAnim = jjObjectPresets[OBJECT::SEEKERBULLET].killAnim;
  197.                 jjObjectPresets[OBJECT::SEEKERBULLET].scriptedCollisions = true;
  198.                 jjObjectPresets[OBJECT::SEEKERBULLET].playerHandling = HANDLING::SPECIAL;
  199.                 jjObjectPresets[OBJECT::SEEKERBULLET].animSpeed = 30;
  200.                
  201.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].xSpeed = jjObjectPresets[OBJECT::SEEKERBULLETPU].xSpeed * -6;
  202.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].ySpeed = jjObjectPresets[OBJECT::SEEKERBULLETPU].ySpeed * 6;
  203.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].xAcc = 0;
  204.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].yAcc = 0;
  205.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].counterEnd = 180;
  206.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].lightType = jjObjectPresets[OBJECT::BLASTERBULLET].lightType;
  207.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].behavior = HomingMissile();
  208.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].special = jjObjectPresets[OBJECT::SEEKERBULLETPU].determineCurAnim(ANIM::AMMO, 42);
  209.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].determineCurFrame();
  210.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].killAnim = jjObjectPresets[OBJECT::SEEKERBULLETPU].killAnim;
  211.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].scriptedCollisions = true;
  212.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].playerHandling = HANDLING::SPECIAL;
  213.                 jjObjectPresets[OBJECT::SEEKERBULLETPU].animSpeed = 60;
  214.                
  215.                 jjWeapons[WEAPON::RF].maximum = 10;
  216.                 jjWeapons[WEAPON::RF].spread = SPREAD::NORMAL;
  217.                 jjWeapons[WEAPON::RF].defaultSample = false;
  218.                
  219.                 jjObjectPresets[OBJECT::RFBULLET].xSpeed = jjObjectPresets[OBJECT::RFBULLET].xSpeed * -10;
  220.                 jjObjectPresets[OBJECT::RFBULLET].ySpeed = jjObjectPresets[OBJECT::RFBULLET].ySpeed * -10;
  221.                 jjObjectPresets[OBJECT::RFBULLET].xAcc = 0;
  222.                 jjObjectPresets[OBJECT::RFBULLET].yAcc = 0;
  223.                 jjObjectPresets[OBJECT::RFBULLET].counterEnd = 180;
  224.                 jjObjectPresets[OBJECT::RFBULLET].lightType = LIGHT::NONE;
  225.                 jjObjectPresets[OBJECT::RFBULLET].behavior = SuperMissile();
  226.                 jjObjectPresets[OBJECT::RFBULLET].special = jjObjectPresets[OBJECT::RFBULLET].determineCurAnim(ANIM::SONCSHIP, 0);
  227.                 jjObjectPresets[OBJECT::RFBULLET].determineCurFrame();
  228.                 jjObjectPresets[OBJECT::RFBULLET].killAnim = jjObjectPresets[OBJECT::SEEKERBULLET].killAnim;
  229.                 jjObjectPresets[OBJECT::RFBULLET].scriptedCollisions = true;
  230.                 jjObjectPresets[OBJECT::RFBULLET].playerHandling = HANDLING::SPECIAL;
  231.                 jjObjectPresets[OBJECT::RFBULLET].animSpeed = 100;
  232.                
  233.                 jjObjectPresets[OBJECT::RFBULLETPU].xSpeed = jjObjectPresets[OBJECT::RFBULLETPU].xSpeed * -10;
  234.                 jjObjectPresets[OBJECT::RFBULLETPU].ySpeed = jjObjectPresets[OBJECT::RFBULLETPU].ySpeed * -10;
  235.                 jjObjectPresets[OBJECT::RFBULLETPU].xAcc = 0;
  236.                 jjObjectPresets[OBJECT::RFBULLETPU].yAcc = 0;
  237.                 jjObjectPresets[OBJECT::RFBULLETPU].counterEnd = 180;
  238.                 jjObjectPresets[OBJECT::RFBULLETPU].lightType = LIGHT::NONE;
  239.                 jjObjectPresets[OBJECT::RFBULLETPU].behavior = SuperMissile();
  240.                 jjObjectPresets[OBJECT::RFBULLETPU].special = jjObjectPresets[OBJECT::RFBULLETPU].determineCurAnim(ANIM::SONCSHIP, 0);
  241.                 jjObjectPresets[OBJECT::RFBULLETPU].determineCurFrame();
  242.                 jjObjectPresets[OBJECT::RFBULLETPU].killAnim = jjObjectPresets[OBJECT::SEEKERBULLET].killAnim;
  243.                 jjObjectPresets[OBJECT::RFBULLETPU].scriptedCollisions = true;
  244.                 jjObjectPresets[OBJECT::RFBULLETPU].playerHandling = HANDLING::SPECIAL;
  245.                 jjObjectPresets[OBJECT::RFBULLETPU].animSpeed = 200;
  246.                
  247.                 jjWeapons[WEAPON::TOASTER].maximum = 50;
  248.                 jjWeapons[WEAPON::TOASTER].multiplier = 8;
  249.                
  250.                 jjObjectPresets[OBJECT::TOASTERBULLET].xAcc = 0;
  251.                 jjObjectPresets[OBJECT::TOASTERBULLET].yAcc = 0;
  252.                 jjObjectPresets[OBJECT::TOASTERBULLET].behavior = Flamethrower();
  253.                 jjObjectPresets[OBJECT::TOASTERBULLET].determineCurFrame();
  254.                 jjObjectPresets[OBJECT::TOASTERBULLET].scriptedCollisions = true;
  255.                 jjObjectPresets[OBJECT::TOASTERBULLET].playerHandling = HANDLING::SPECIAL;
  256.                 jjObjectPresets[OBJECT::TOASTERBULLET].animSpeed = 6;
  257.                
  258.                 jjObjectPresets[OBJECT::TOASTERBULLETPU].xAcc = 0;
  259.                 jjObjectPresets[OBJECT::TOASTERBULLETPU].yAcc = 0;
  260.                 jjObjectPresets[OBJECT::TOASTERBULLETPU].behavior = Flamethrower();
  261.                 jjObjectPresets[OBJECT::TOASTERBULLETPU].determineCurFrame();
  262.                 jjObjectPresets[OBJECT::TOASTERBULLETPU].scriptedCollisions = true;
  263.                 jjObjectPresets[OBJECT::TOASTERBULLETPU].playerHandling = HANDLING::SPECIAL;
  264.                 jjObjectPresets[OBJECT::TOASTERBULLETPU].animSpeed = 12;
  265.                
  266.                 jjWeapons[WEAPON::TNT].maximum = 10;
  267.                
  268.                 jjAnimSets[ANIM::ROBOT].load();
  269.                 jjAnimations[jjAnimSets[ANIM::AMMO] + 59] = jjAnimations[jjAnimSets[ANIM::ROBOT] + 0];
  270.                
  271.                 jjObjectPresets[OBJECT::TNT].killAnim = jjObjectPresets[OBJECT::RFBULLET].killAnim;
  272.                 jjObjectPresets[OBJECT::TNT].special = jjObjectPresets[OBJECT::TNT].determineCurAnim(ANIM::ROBOT, 0);
  273.                 jjObjectPresets[OBJECT::TNT].determineCurFrame();
  274.                 jjObjectPresets[OBJECT::TNT].lightType = LIGHT::NONE;
  275.                 jjObjectPresets[OBJECT::TNT].behavior = SpikeMine();
  276.                 jjObjectPresets[OBJECT::TNT].scriptedCollisions = true;
  277.                 jjObjectPresets[OBJECT::TNT].playerHandling = HANDLING::SPECIAL;
  278.                 jjObjectPresets[OBJECT::TNT].animSpeed = 70;
  279.                 jjObjectPresets[OBJECT::TNT].counterEnd = 245;
  280.                 jjObjectPresets[OBJECT::TNT].isBlastable = false;
  281.                
  282.                 jjWeapons[WEAPON::GUN8].maximum = 25;
  283.                 jjWeapons[WEAPON::GUN8].spread = SPREAD::NORMAL;
  284.                 jjWeapons[WEAPON::GUN8].gradualAim = false;
  285.                 jjWeapons[WEAPON::GUN8].defaultSample = false;
  286.                
  287.                 jjObjectPresets[OBJECT::FIREBALLBULLET].xSpeed = -15;
  288.                 jjObjectPresets[OBJECT::FIREBALLBULLET].ySpeed = 0;
  289.                 jjObjectPresets[OBJECT::FIREBALLBULLET].xAcc = 0;
  290.                 jjObjectPresets[OBJECT::FIREBALLBULLET].yAcc = 0;
  291.                 jjObjectPresets[OBJECT::FIREBALLBULLET].eventID = OBJECT::BLASTERBULLET;
  292.                 jjObjectPresets[OBJECT::FIREBALLBULLET].behavior = Laser();
  293.                 jjObjectPresets[OBJECT::FIREBALLBULLET].special = jjObjectPresets[OBJECT::FIREBALLBULLET].determineCurAnim(ANIM::AMMO, 30);
  294.                 jjObjectPresets[OBJECT::FIREBALLBULLET].determineCurFrame();
  295.                 jjObjectPresets[OBJECT::FIREBALLBULLET].scriptedCollisions = true;
  296.                 jjObjectPresets[OBJECT::FIREBALLBULLET].playerHandling = HANDLING::SPECIAL;
  297.                 jjObjectPresets[OBJECT::FIREBALLBULLET].animSpeed = 40;
  298.                 jjObjectPresets[OBJECT::FIREBALLBULLET].counterEnd = 140;
  299.                 jjObjectPresets[OBJECT::FIREBALLBULLET].killAnim = jjObjectPresets[OBJECT::ICEBULLET].killAnim;
  300.                
  301.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].xSpeed = -15;
  302.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].ySpeed = 0;
  303.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].xAcc = 0;
  304.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].yAcc = 0;
  305.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].eventID = OBJECT::BLASTERBULLETPU;
  306.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].behavior = Laser();
  307.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].special = jjObjectPresets[OBJECT::FIREBALLBULLETPU].determineCurAnim(ANIM::AMMO, 30);
  308.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].determineCurFrame();
  309.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].scriptedCollisions = true;
  310.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].playerHandling = HANDLING::SPECIAL;
  311.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].animSpeed = 80;
  312.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].counterEnd = 140;
  313.                 jjObjectPresets[OBJECT::FIREBALLBULLETPU].killAnim = jjObjectPresets[OBJECT::ICEBULLET].killAnim;
  314.                
  315.                 jjWeapons[WEAPON::GUN9].maximum = 50;
  316.                 jjObjectPresets[OBJECT::ELECTROBULLET].xSpeed = jjObjectPresets[OBJECT::ELECTROBULLET].xSpeed * -4;
  317.                 jjObjectPresets[OBJECT::ELECTROBULLET].ySpeed = 0;
  318.                 jjObjectPresets[OBJECT::ELECTROBULLET].counterEnd = 200;
  319.                 jjObjectPresets[OBJECT::ELECTROBULLET].behavior = ElectroBlaster();
  320.                 jjObjectPresets[OBJECT::ELECTROBULLET].scriptedCollisions = true;
  321.                 jjObjectPresets[OBJECT::ELECTROBULLET].playerHandling = HANDLING::SPECIAL;
  322.                 jjObjectPresets[OBJECT::ELECTROBULLET].animSpeed = 15;
  323.                
  324.                 jjObjectPresets[OBJECT::ELECTROBULLETPU].xSpeed = jjObjectPresets[OBJECT::ELECTROBULLETPU].xSpeed * -4;
  325.                 jjObjectPresets[OBJECT::ELECTROBULLETPU].ySpeed = 0;
  326.                 jjObjectPresets[OBJECT::ELECTROBULLETPU].counterEnd = 210;
  327.                 jjObjectPresets[OBJECT::ELECTROBULLETPU].behavior = ElectroBlaster();
  328.                 jjObjectPresets[OBJECT::ELECTROBULLETPU].scriptedCollisions = true;
  329.                 jjObjectPresets[OBJECT::ELECTROBULLETPU].playerHandling = HANDLING::SPECIAL;
  330.                 jjObjectPresets[OBJECT::ELECTROBULLETPU].animSpeed = 30;
  331.                
  332.                 jjObjectPresets[OBJECT::BOUNCERAMMO3].behavior =
  333.                 jjObjectPresets[OBJECT::ICEAMMO3].behavior =
  334.                 jjObjectPresets[OBJECT::SEEKERAMMO3].behavior =
  335.                 jjObjectPresets[OBJECT::RFAMMO3].behavior =
  336.                 jjObjectPresets[OBJECT::TOASTERAMMO3].behavior =
  337.                 jjObjectPresets[OBJECT::TNTAMMO3].behavior =
  338.                 jjObjectPresets[OBJECT::GUN8AMMO3].behavior =
  339.                 jjObjectPresets[OBJECT::GUN9AMMO3].behavior = AmmoPickup();
  340.                
  341.                 jjObjectPresets[OBJECT::BOUNCERAMMO3].scriptedCollisions =
  342.                 jjObjectPresets[OBJECT::ICEAMMO3].scriptedCollisions =
  343.                 jjObjectPresets[OBJECT::SEEKERAMMO3].scriptedCollisions =
  344.                 jjObjectPresets[OBJECT::RFAMMO3].scriptedCollisions =
  345.                 jjObjectPresets[OBJECT::TOASTERAMMO3].scriptedCollisions =
  346.                 jjObjectPresets[OBJECT::TNTAMMO3].scriptedCollisions =
  347.                 jjObjectPresets[OBJECT::GUN8AMMO3].scriptedCollisions =
  348.                 jjObjectPresets[OBJECT::GUN9AMMO3].scriptedCollisions = true;
  349.                
  350.                 jjObjectPresets[OBJECT::BOUNCERAMMO3].var[4] = 2;
  351.                 jjObjectPresets[OBJECT::ICEAMMO3].var[4] = 3;
  352.                 jjObjectPresets[OBJECT::SEEKERAMMO3].var[4] = 4;
  353.                 jjObjectPresets[OBJECT::RFAMMO3].var[4] = 5;
  354.                 jjObjectPresets[OBJECT::TOASTERAMMO3].var[4] = 6;
  355.                 jjObjectPresets[OBJECT::TNTAMMO3].var[4] = 7;
  356.                 jjObjectPresets[OBJECT::GUN8AMMO3].var[4] = 8;
  357.                 jjObjectPresets[OBJECT::GUN9AMMO3].var[4] = 9;
  358.                
  359.                 jjObjectPresets[OBJECT::BOUNCERAMMO3].var[5] = 5;
  360.                 jjObjectPresets[OBJECT::ICEAMMO3].var[5] = 2;
  361.                 jjObjectPresets[OBJECT::SEEKERAMMO3].var[5] = 2;
  362.                 jjObjectPresets[OBJECT::RFAMMO3].var[5] = 1;
  363.                 jjObjectPresets[OBJECT::TOASTERAMMO3].var[5] = 3;
  364.                 jjObjectPresets[OBJECT::TNTAMMO3].var[5] = 1;
  365.                 jjObjectPresets[OBJECT::GUN8AMMO3].var[5] = 2;
  366.                 jjObjectPresets[OBJECT::GUN9AMMO3].var[5] = 3;
  367.                
  368.                 jjObjectPresets[OBJECT::CARROT].behavior = HealthPickup();
  369.                 jjObjectPresets[OBJECT::CARROT].scriptedCollisions = true;
  370.                 jjObjectPresets[OBJECT::CARROT].determineCurAnim(customAnimID, 6);
  371.                 jjObjectPresets[OBJECT::CARROT].determineCurFrame();
  372.                 jjObjectPresets[OBJECT::CARROT].light = 8;
  373.                
  374.                 jjObjectPresets[OBJECT::FULLENERGY].behavior = MegaHealthPickup();
  375.                 jjObjectPresets[OBJECT::FULLENERGY].scriptedCollisions = true;
  376.                 jjObjectPresets[OBJECT::FULLENERGY].determineCurAnim(customAnimID, 7);
  377.                 jjObjectPresets[OBJECT::FULLENERGY].determineCurFrame();
  378.                
  379.                 jjObjectPresets[OBJECT::FIRESHIELD].behavior = PowerOrb();
  380.                 jjObjectPresets[OBJECT::FIRESHIELD].scriptedCollisions = true;
  381.                 jjObjectPresets[OBJECT::FIRESHIELD].playerHandling = HANDLING::PICKUP;
  382.                 jjObjectPresets[OBJECT::FIRESHIELD].light = 8;
  383.                 jjObjectPresets[OBJECT::FIRESHIELD].triggersTNT = false;
  384.                 jjObjectPresets[OBJECT::FIRESHIELD].determineCurAnim(customAnimID, 5);
  385.                 jjObjectPresets[OBJECT::FIRESHIELD].determineCurFrame();
  386.                
  387.                 jjObjectPresets[OBJECT::PURPLEGEM].determineCurAnim(customAnimID, 1);
  388.                 jjObjectPresets[OBJECT::PURPLEGEM].determineCurFrame();
  389.                 jjObjectPresets[OBJECT::PURPLEGEM].behavior = ShipExplosion();
  390.                 jjObjectPresets[OBJECT::PURPLEGEM].playerHandling = HANDLING::PARTICLE;
  391.                 jjObjectPresets[OBJECT::PURPLEGEM].bulletHandling = HANDLING::IGNOREBULLET;
  392.                 jjObjectPresets[OBJECT::PURPLEGEM].frameID = 0;
  393.                
  394.                 jjObjectPresets[OBJECT::FULLENERGY].light = 8;
  395.                
  396.                 jjObjectPresets[OBJECT::PLASMASHIELD].behavior = ShieldPickup();
  397.                 jjObjectPresets[OBJECT::PLASMASHIELD].scriptedCollisions = true;
  398.                 jjObjectPresets[OBJECT::PLASMASHIELD].playerHandling = HANDLING::PICKUP;
  399.                 jjObjectPresets[OBJECT::PLASMASHIELD].light = 8;
  400.                 jjObjectPresets[OBJECT::PLASMASHIELD].triggersTNT = false;
  401.                 jjObjectPresets[OBJECT::PLASMASHIELD].determineCurAnim(customAnimID, 3);
  402.                 jjObjectPresets[OBJECT::PLASMASHIELD].determineCurFrame();
  403.                
  404.                 array<OBJECT::Object> Powerups = {OBJECT::BLASTERPOWERUP, OBJECT::BOUNCERPOWERUP, OBJECT::ICEPOWERUP, OBJECT::SEEKERPOWERUP, OBJECT::RFPOWERUP, OBJECT::TOASTERPOWERUP, OBJECT::TNTPOWERUP, OBJECT::GUN8POWERUP, OBJECT::GUN9POWERUP};
  405.                 for (uint p = 0; p < Powerups.length(); p++) {
  406.                         jjObjectPresets[Powerups[p]].behavior = ShieldPickup();
  407.                         jjObjectPresets[Powerups[p]].scriptedCollisions = true;
  408.                         jjObjectPresets[Powerups[p]].playerHandling = HANDLING::PICKUP;
  409.                         jjObjectPresets[Powerups[p]].light = 8;
  410.                         jjObjectPresets[Powerups[p]].triggersTNT = false;
  411.                         jjObjectPresets[Powerups[p]].determineCurAnim(customAnimID, 3);
  412.                         jjObjectPresets[Powerups[p]].determineCurFrame();
  413.                 }
  414.                
  415.                 jjObjectPresets[OBJECT::WATERSHIELD].behavior = MegaShieldPickup();
  416.                 jjObjectPresets[OBJECT::WATERSHIELD].scriptedCollisions = true;
  417.                 jjObjectPresets[OBJECT::WATERSHIELD].playerHandling = HANDLING::PICKUP;
  418.                 jjObjectPresets[OBJECT::WATERSHIELD].light = 8;
  419.                 jjObjectPresets[OBJECT::WATERSHIELD].triggersTNT = false;
  420.                 jjObjectPresets[OBJECT::WATERSHIELD].determineCurAnim(customAnimID, 4);
  421.                 jjObjectPresets[OBJECT::WATERSHIELD].determineCurFrame();
  422.         }
  423.  
  424.         jjOBJ@ assignHealthPickup(uint8 eventID) {     
  425.                 jjOBJ@ preset = jjObjectPresets[eventID];
  426.                 preset.behavior = HealthPickup();
  427.                 preset.scriptedCollisions = true;
  428.                 preset.playerHandling = HANDLING::PICKUP;
  429.                 preset.triggersTNT = false;
  430.                 preset.determineCurAnim(customAnimID, 6);
  431.                 preset.determineCurFrame();
  432.                 preset.light = 8;
  433.                
  434.                 return preset;
  435.         }
  436.        
  437.         jjOBJ@ assignMegaHealthPickup(uint8 eventID) { 
  438.                 jjOBJ@ preset = jjObjectPresets[eventID];
  439.                 preset.behavior = MegaHealthPickup();
  440.                 preset.scriptedCollisions = true;
  441.                 preset.playerHandling = HANDLING::PICKUP;
  442.                 preset.triggersTNT = false;
  443.                 preset.determineCurAnim(customAnimID, 7);
  444.                 preset.determineCurFrame();
  445.                 preset.light = 8;
  446.                
  447.                 return preset;
  448.         }
  449.        
  450.         jjOBJ@ assignShieldPickup(uint8 eventID) {     
  451.                 jjOBJ@ preset = jjObjectPresets[eventID];
  452.                 preset.behavior = ShieldPickup();
  453.                 preset.scriptedCollisions = true;
  454.                 preset.playerHandling = HANDLING::PICKUP;
  455.                 preset.triggersTNT = false;
  456.                 preset.determineCurAnim(customAnimID, 3);
  457.                 preset.determineCurFrame();
  458.                 preset.light = 8;
  459.                
  460.                 return preset;
  461.         }
  462.        
  463.         jjOBJ@ assignMegaShieldPickup(uint8 eventID) { 
  464.                 jjOBJ@ preset = jjObjectPresets[eventID];
  465.                 preset.behavior = MegaShieldPickup();
  466.                 preset.scriptedCollisions = true;
  467.                 preset.playerHandling = HANDLING::PICKUP;
  468.                 preset.triggersTNT = false;
  469.                 preset.determineCurAnim(customAnimID, 4);
  470.                 preset.determineCurFrame();
  471.                 preset.light = 8;
  472.                
  473.                 return preset;
  474.         }
  475.        
  476.         jjOBJ@ assignPowerOrb(uint8 eventID) { 
  477.                 jjOBJ@ preset = jjObjectPresets[eventID];
  478.                 preset.behavior = PowerOrb();
  479.                 preset.scriptedCollisions = true;
  480.                 preset.playerHandling = HANDLING::PICKUP;
  481.                 preset.triggersTNT = false;
  482.                 preset.determineCurAnim(customAnimID, 5);
  483.                 preset.determineCurFrame();
  484.                 preset.light = 8;
  485.                
  486.                 return preset;
  487.         }
  488.  
  489.         void assignPickupDefaults() {
  490.                 jjObjectPresets[OBJECT::CARROT].behavior = HealthPickup();
  491.                 jjObjectPresets[OBJECT::CARROT].scriptedCollisions = true;
  492.                 jjObjectPresets[OBJECT::CARROT].determineCurAnim(customAnimID, 6);
  493.                 jjObjectPresets[OBJECT::CARROT].determineCurFrame();
  494.                 jjObjectPresets[OBJECT::CARROT].light = 8;
  495.                
  496.                 jjObjectPresets[OBJECT::FULLENERGY].behavior = MegaHealthPickup();
  497.                 jjObjectPresets[OBJECT::FULLENERGY].scriptedCollisions = true;
  498.                 jjObjectPresets[OBJECT::FULLENERGY].determineCurAnim(customAnimID, 7);
  499.                 jjObjectPresets[OBJECT::FULLENERGY].determineCurFrame();
  500.                
  501.                 jjObjectPresets[OBJECT::SEEKERPOWERUP].behavior = MegaShieldPickup();
  502.                 jjObjectPresets[OBJECT::SEEKERPOWERUP].scriptedCollisions = true;
  503.                 jjObjectPresets[OBJECT::SEEKERPOWERUP].playerHandling = HANDLING::PICKUP;
  504.                 jjObjectPresets[OBJECT::SEEKERPOWERUP].light = 8;
  505.                 jjObjectPresets[OBJECT::SEEKERPOWERUP].triggersTNT = false;
  506.                 jjObjectPresets[OBJECT::SEEKERPOWERUP].determineCurAnim(customAnimID, 4);
  507.                 jjObjectPresets[OBJECT::SEEKERPOWERUP].determineCurFrame();
  508.                
  509.                 array<OBJECT::Object> Shields = {OBJECT::FIRESHIELD, OBJECT::WATERSHIELD, OBJECT::LIGHTNINGSHIELD, OBJECT::LASERSHIELD};
  510.                 for (uint s = 0; s < Shields.length(); s++) {
  511.                         jjObjectPresets[Shields[s]].behavior = PowerOrb();
  512.                         jjObjectPresets[Shields[s]].scriptedCollisions = true;
  513.                         jjObjectPresets[Shields[s]].playerHandling = HANDLING::PICKUP;
  514.                         jjObjectPresets[Shields[s]].light = 8;
  515.                         jjObjectPresets[Shields[s]].triggersTNT = false;
  516.                         jjObjectPresets[Shields[s]].determineCurAnim(customAnimID, 5);
  517.                         jjObjectPresets[Shields[s]].determineCurFrame();
  518.                 }
  519.                
  520.                 array<OBJECT::Object> Powerups = {OBJECT::BLASTERPOWERUP, OBJECT::BOUNCERPOWERUP, OBJECT::ICEPOWERUP, OBJECT::RFPOWERUP, OBJECT::TOASTERPOWERUP, OBJECT::TNTPOWERUP, OBJECT::GUN8POWERUP, OBJECT::GUN9POWERUP};
  521.                 for (uint p = 0; p < Powerups.length(); p++) {
  522.                         jjObjectPresets[Powerups[p]].behavior = ShieldPickup();
  523.                         jjObjectPresets[Powerups[p]].scriptedCollisions = true;
  524.                         jjObjectPresets[Powerups[p]].playerHandling = HANDLING::PICKUP;
  525.                         jjObjectPresets[Powerups[p]].light = 8;
  526.                         jjObjectPresets[Powerups[p]].triggersTNT = false;
  527.                         jjObjectPresets[Powerups[p]].determineCurAnim(customAnimID, 3);
  528.                         jjObjectPresets[Powerups[p]].determineCurFrame();
  529.                 }
  530.                
  531.                 jjObjectPresets[OBJECT::PURPLEGEM].determineCurAnim(customAnimID, 1);
  532.                 jjObjectPresets[OBJECT::PURPLEGEM].determineCurFrame();
  533.                 jjObjectPresets[OBJECT::PURPLEGEM].behavior = ShipExplosion();
  534.                 jjObjectPresets[OBJECT::PURPLEGEM].playerHandling = HANDLING::PARTICLE;
  535.                 jjObjectPresets[OBJECT::PURPLEGEM].bulletHandling = HANDLING::IGNOREBULLET;
  536.                 jjObjectPresets[OBJECT::PURPLEGEM].frameID = 0;
  537.         }
  538.        
  539.         void handleAnimationWork() {
  540.                 Resize::Resize(
  541.                         jjAnimations[jjAnimSets[ANIM::JAZZ] + 53],
  542.                         2.5,
  543.                         Resize::Method::Scale2x
  544.                 );
  545.                
  546.                 Resize::Resize(
  547.                         jjAnimations[jjAnimSets[ANIM::SPAZ] + 53],
  548.                         2.5,
  549.                         Resize::Method::Scale2x
  550.                 );
  551.                
  552.                 Resize::Resize(
  553.                         jjAnimations[jjAnimSets[ANIM::LORI] + 53],
  554.                         2.5,
  555.                         Resize::Method::Scale2x
  556.                 );
  557.                
  558.                 Resize::Resize(
  559.                         jjAnimations[jjAnimSets[ANIM::PICKUPS] + 41],
  560.                         2,
  561.                         Resize::Method::Scale2x
  562.                 );
  563.                
  564.                 Resize::Resize(
  565.                         jjAnimations[jjAnimSets[ANIM::AMMO] + 30],
  566.                         2,
  567.                         Resize::Method::Scale2x
  568.                 );
  569.                
  570.                 Resize::Resize(
  571.                         jjAnimations[jjAnimSets[ANIM::SONCSHIP] + 0],
  572.                         1.5,
  573.                         Resize::Method::Scale2x
  574.                 );
  575.                
  576.                 Resize::Resize(
  577.                         jjAnimations[jjAnimSets[ANIM::MENU] + 1],
  578.                         3.5,
  579.                         Resize::Method::Scale2x
  580.                 );
  581.                
  582.                
  583.                 jjANIMATION@ animBlaster = jjAnimations[jjAnimSets[ANIM::DEVAN] + 0];
  584.                 for (uint i = 0; i < animBlaster.frameCount; i++) {
  585.                         jjANIMFRAME@ frame = jjAnimFrames[animBlaster + i];
  586.                         jjPIXELMAP sprite(frame);
  587.                         for (uint x = 0; x < sprite.width; ++x) {
  588.                                 for (uint y = 0; y < sprite.height; ++y) {
  589.                                         if (sprite[x,y] >= 32 && sprite[x,y] <= 39) sprite[x,y] -= 17;
  590.                                 }
  591.                         }
  592.                         sprite.save(frame);
  593.                 }
  594.                
  595.                 jjANIMATION@ animBurst = jjAnimations[jjAnimSets[ANIM::PICKUPS] + 45];
  596.                 for (uint i = 0; i < animBurst.frameCount; i++) {
  597.                         jjANIMFRAME@ frame = jjAnimFrames[animBurst + i];
  598.                         jjPIXELMAP sprite(frame);
  599.                         for (uint x = 0; x < sprite.width; ++x) {
  600.                                 for (uint y = 0; y < sprite.height; ++y) {
  601.                                         if (sprite[x,y] >= 32 && sprite[x,y] <= 39) sprite[x,y] += 56;
  602.                                 }
  603.                         }
  604.                         sprite.save(frame);
  605.                 }
  606.                
  607.                 jjANIMATION@ animBurstAmmo = jjAnimations[jjAnimSets[ANIM::AMMO] + 29];
  608.                 for (uint i = 0; i < animBurstAmmo.frameCount; i++) {
  609.                         jjANIMFRAME@ frame = jjAnimFrames[animBurstAmmo + i];
  610.                         jjPIXELMAP sprite(frame);
  611.                         for (uint x = 0; x < sprite.width; ++x) {
  612.                                 for (uint y = 0; y < sprite.height; ++y) {
  613.                                         if (sprite[x,y] >= 32 && sprite[x,y] <= 39) sprite[x,y] += 56;
  614.                                 }
  615.                         }
  616.                         sprite.save(frame);
  617.                 }
  618.                
  619.                 jjANIMATION@ animBurstAmmoPU = jjAnimations[jjAnimSets[ANIM::AMMO] + 28];
  620.                 for (uint i = 0; i < animBurstAmmoPU.frameCount; i++) {
  621.                         jjANIMFRAME@ frame = jjAnimFrames[animBurstAmmoPU + i];
  622.                         jjPIXELMAP sprite(frame);
  623.                         for (uint x = 0; x < sprite.width; ++x) {
  624.                                 for (uint y = 0; y < sprite.height; ++y) {
  625.                                         if (sprite[x,y] >= 88 && sprite[x,y] <= 95) sprite[x,y] -= 33;
  626.                                 }
  627.                         }
  628.                         sprite.save(frame);
  629.                 }
  630.                
  631.                 jjANIMATION@ animMissile = jjAnimations[jjAnimSets[ANIM::SONCSHIP] + 0];
  632.                 for (uint i = 0; i < animMissile.frameCount; i++) {
  633.                         jjANIMFRAME@ frame = jjAnimFrames[animMissile + i];
  634.                         jjPIXELMAP sprite(frame);
  635.                         for (uint x = 0; x < sprite.width; ++x) {
  636.                                 for (uint y = 0; y < sprite.height; ++y) {
  637.                                         if (sprite[x,y] >= 88 && sprite[x,y] <= 95) sprite[x,y] -= 72;
  638.                                 }
  639.                         }
  640.                         sprite.save(frame);
  641.                 }
  642.                
  643.                
  644.                 jjANIMATION@ animLaser = jjAnimations[jjAnimSets[ANIM::AMMO] + 30];
  645.                 for (uint i = 0; i < animLaser.frameCount; i++) {
  646.                         jjANIMFRAME@ frame = jjAnimFrames[animLaser + i];
  647.                         jjPIXELMAP sprite(frame);
  648.                         for (uint x = 0; x < sprite.width; ++x) {
  649.                                 for (uint y = 0; y < sprite.height; ++y) {
  650.                                         if (sprite[x,y] >= 32 && sprite[x,y] <= 39) sprite[x,y] += 48;
  651.                                 }
  652.                         }
  653.                         sprite.save(frame);
  654.                 }
  655.                
  656.                 jjANIMATION@ animLaserAmmo = jjAnimations[jjAnimSets[ANIM::AMMO] + 62];
  657.                 for (uint i = 0; i < animLaserAmmo.frameCount; i++) {
  658.                         jjANIMFRAME@ frame = jjAnimFrames[animLaserAmmo + i];
  659.                         jjPIXELMAP sprite(frame);
  660.                         for (uint x = 0; x < sprite.width; ++x) {
  661.                                 for (uint y = 0; y < sprite.height; ++y) {
  662.                                         if (sprite[x,y] >= 88 && sprite[x,y] <= 95) sprite[x,y] -= 8;
  663.                                 }
  664.                         }
  665.                         sprite.save(frame);
  666.                 }
  667.                
  668.                 jjANIMATION@ animLaserAmmoPU = jjAnimations[jjAnimSets[ANIM::AMMO] + 61];
  669.                 for (uint i = 0; i < animLaserAmmoPU.frameCount; i++) {
  670.                         jjANIMFRAME@ frame = jjAnimFrames[animLaserAmmoPU + i];
  671.                         jjPIXELMAP sprite(frame);
  672.                         for (uint x = 0; x < sprite.width; ++x) {
  673.                                 for (uint y = 0; y < sprite.height; ++y) {
  674.                                         if (sprite[x,y] >= 24 && sprite[x,y] <= 31) sprite[x,y] += 24;
  675.                                 }
  676.                         }
  677.                         sprite.save(frame);
  678.                 }
  679.         }
  680.  
  681.         void handleOnLevelBegin() {
  682.                 jjAlert("|||Press |||||F2||| for instructions!");
  683.                 jjSampleLoad(SOUND::COMMON_LANDPOP, "silence.wav");
  684.         }
  685.  
  686.         void handleShipCollisions(jjOBJ@ obj, jjPLAYER@ creator) {
  687.                 if (!jjLocalPlayers[0].isIdle) {
  688.                         for (int i = 0; i < 32; i++) {
  689.                                 jjPLAYER@ play = jjPlayers[i];
  690.                                 SPACESHIP@ ship = Ships[i];
  691.                                
  692.                                 if (obj.doesCollide(play, true) && canBeHit(play,creator,obj) && (obj.var[8] & 1 << play.playerID == 0 || obj.eventID != OBJECT::FIREBALLBULLET)) {
  693.                                         if (obj.special != 100) {
  694.                                                 ship.damageAccumulated += obj.animSpeed;
  695.                                                 ship.accumulationTime = 0;
  696.                                                 obj.special = 100;
  697.                                         }
  698.                                         if (obj.eventID == OBJECT::ICEBULLET || obj.eventID == OBJECT::ICEBULLETPU) damageNumber(creator, play, ship.damageCalc(ship, ship.damageAccumulated));
  699.                                        
  700.                                         if (!ship.justHit) {
  701.                                                 ship.justHit = true;
  702.                                                 ship.hitDelay = 0;
  703.                                                                        
  704.                                                 randomHurtSample(play, 48);
  705.                                                                        
  706.                                                 if (!play.isLocal && obj.eventID != OBJECT::ICEBULLET && obj.eventID != OBJECT::ICEBULLETPU) damageNumber(creator, play, ship.damageCalc(ship, ship.damageAccumulated));
  707.                                                                        
  708.                                                 if ((obj.eventID == OBJECT::SEEKERBULLET || obj.eventID == OBJECT::SEEKERBULLETPU) && creator.isLocal) obj.state = STATE::EXPLODE;
  709.                                                                        
  710.                                                 jjSample(
  711.                                                         play.xPos, play.yPos,
  712.                                                         (obj.eventID == OBJECT::TOASTERBULLET || obj.eventID == OBJECT::TOASTERBULLETPU)? SOUND::BILSBOSS_FIRE :
  713.                                                         (obj.eventID == OBJECT::SEEKERBULLET || obj.eventID == OBJECT::SEEKERBULLETPU || obj.eventID == OBJECT::RFBULLET || obj.eventID == OBJECT::RFBULLETPU || obj.eventID == OBJECT::TNT)? SOUND::COMMON_EXPL_TNT :
  714.                                                         (obj.eventID == OBJECT::ELECTROBULLET || obj.eventID == OBJECT::ELECTROBULLETPU)? SOUND::COMMON_ELECTRICHIT :
  715.                                                         SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500
  716.                                                 );
  717.                                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  718.                                         }
  719.                                 }
  720.                         }
  721.                 }
  722.         }
  723.  
  724.         class Blaster : jjBEHAVIORINTERFACE {
  725.                 void onBehave(jjOBJ@ obj) {
  726.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  727.                        
  728.                         obj.behave(BEHAVIOR::BULLET, obj.state == STATE::FLY && inView(obj)? false:true);
  729.                         obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
  730.                        
  731.                         if (obj.state == STATE::START) {
  732.                                 obj.state = STATE::FLY;                
  733.                         }
  734.                        
  735.                         if (obj.state == STATE::FLY) {
  736.                                 if (obj.counter == 1 && jjPlayers[obj.creatorID].isLocal) jjSample(obj.xPos, obj.yPos, SOUND::DEVILDEVAN_PHASER2, 50, obj.eventID == OBJECT::BLASTERBULLETPU? 11500 : 0);
  737.                                 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);
  738.                         }
  739.                        
  740.                         if (obj.findNearestPlayer(1000) > -1 && obj.findNearestPlayer(1000) != creator.playerID) handleShipCollisions(obj, creator);
  741.                        
  742.                         if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
  743.                                 obj.xPos = creator.xPos;
  744.                                 obj.yPos = creator.yPos;
  745.                         }
  746.                        
  747.                 }
  748.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  749.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  750.                         SPACESHIP@ ship = Ships[play.playerID];
  751.                        
  752.                         if (canBeHit(play,creator,obj)) {
  753.                                 ship.xSpeed += recoilX(ship,obj,12);
  754.                                 ship.ySpeed += recoilY(ship,obj,12);
  755.                                 randomHurtSample(play, 0);
  756.                                
  757.                                 if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::BLASTERBULLETPU? jjObjectPresets[OBJECT::BLASTERBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::BLASTERBULLET].animSpeed * 1.3);
  758.                                
  759.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  760.                                         if (play.isLocal) {
  761.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  762.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  763.                                         }
  764.                                 } else {
  765.                                         if (play.isLocal) {
  766.                                                 play.hurt(7, true, creator);
  767.                                         }
  768.                                 }
  769.                                
  770.                                 if (!ship.justHit) {
  771.                                         ship.justHit = true;
  772.                                         ship.hitDelay = 0;
  773.                                 }
  774.                                
  775.                                 jjSample(play.xPos, play.yPos, SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500);
  776.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  777.                                 obj.state = STATE::EXPLODE;
  778.                                 obj.scriptedCollisions = false;
  779.                         }
  780.                         return true;
  781.                 }
  782.         }
  783.  
  784.         class RapidBlaster : jjBEHAVIORINTERFACE {
  785.                 void onBehave(jjOBJ@ obj) {
  786.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  787.                         obj.behave(BEHAVIOR::BULLET, obj.state == STATE::FLY && inView(obj)? false:true);
  788.                         obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
  789.                        
  790.                         if (obj.state == STATE::START) {
  791.                                 obj.state = STATE::FLY;
  792.                         }
  793.                        
  794.                         if (obj.state == STATE::FLY) {
  795.                                 if (obj.counter == 1 && jjPlayers[obj.creatorID].isLocal) jjSample(obj.xPos, obj.yPos, SOUND::COMMON_PISTOL1, 50, obj.eventID == OBJECT::BOUNCERBULLETPU? 20000 : 0);
  796.                                 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);
  797.                         }
  798.                        
  799.                         if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
  800.                        
  801.                         if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
  802.                                 obj.xPos = creator.xPos;
  803.                                 obj.yPos = creator.yPos;
  804.                         }
  805.                 }
  806.                
  807.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  808.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  809.                         SPACESHIP@ ship = Ships[play.playerID];
  810.                        
  811.                         if (canBeHit(play,creator,obj)) {
  812.                                 ship.xSpeed += recoilX(ship,obj,7.5);
  813.                                 ship.ySpeed += recoilY(ship,obj,7.5);
  814.                                 randomHurtSample(play, 0);
  815.                                
  816.                                 if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::BOUNCERBULLETPU? jjObjectPresets[OBJECT::BOUNCERBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::BOUNCERBULLET].animSpeed * 1.3);
  817.                                
  818.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  819.                                         if (play.isLocal) {
  820.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  821.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  822.                                         }
  823.                                 } else {
  824.                                         if (play.isLocal) {
  825.                                                 play.hurt(7, true, creator);
  826.                                         }
  827.                                 }
  828.                                 if (!ship.justHit) {
  829.                                         ship.justHit = true;
  830.                                         ship.hitDelay = 0;
  831.                                 }
  832.                                 jjSample(play.xPos, play.yPos, SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500);
  833.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  834.                                 obj.state = STATE::EXPLODE;
  835.                                 obj.scriptedCollisions = false;
  836.                         }
  837.                         return true;
  838.                 }
  839.         }
  840.  
  841.         class IceBurster : jjBEHAVIORINTERFACE {
  842.                 void onBehave(jjOBJ@ obj) {
  843.                         obj.behave(BEHAVIOR::BULLET, obj.state == STATE::FLY && inView(obj)? false:true);
  844.                         obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
  845.                        
  846.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  847.                        
  848.                         if (obj.state == STATE::START) {
  849.                                 obj.state = STATE::FLY;
  850.                         }
  851.                        
  852.                         if (obj.state == STATE::FLY) {
  853.                                 if (obj.counter == 2 && jjPlayers[obj.creatorID].isLocal) {
  854.                                         jjSample(obj.xPos, obj.yPos, SOUND::COMMON_ICECRUSH, 30, obj.eventID == OBJECT::ICEBULLETPU? 10500:0);
  855.                                         if (creator.ySpeed == 0) {
  856.                                                 if (obj.ySpeed < - 12) obj.ySpeed = -12;
  857.                                                 if (obj.ySpeed > 12) obj.ySpeed = 12;
  858.                                         }
  859.                                 }
  860.                                 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);
  861.                                 if (obj.eventID == OBJECT::ICEBULLETPU && jjGameTicks % 3 == 0) {
  862.                                         jjPARTICLE@ cinders = jjAddParticle(PARTICLE::FIRE);
  863.                                         cinders.xPos = obj.xPos;
  864.                                         cinders.yPos = obj.yPos;
  865.                                 }
  866.                         }
  867.                        
  868.                         if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
  869.                        
  870.                         if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
  871.                                 obj.xPos = creator.xPos;
  872.                                 obj.yPos = creator.yPos;
  873.                         }
  874.                        
  875.                 }
  876.                
  877.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  878.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  879.                         SPACESHIP@ ship = Ships[play.playerID];
  880.                        
  881.                         if (canBeHit(play,creator,obj)) {
  882.                                 ship.xSpeed += recoilX(ship,obj,17.5);
  883.                                 ship.ySpeed += recoilY(ship,obj,17.5);
  884.                                 randomHurtSample(play, 0);
  885.                                
  886.                                 if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::ICEBULLETPU? jjObjectPresets[OBJECT::ICEBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::ICEBULLET].animSpeed * 1.3);
  887.                                
  888.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  889.                                         if (play.isLocal) {
  890.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  891.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  892.                                         }
  893.                                 } else {
  894.                                         if (play.isLocal) {
  895.                                                 play.hurt(7, true, creator);
  896.                                         }
  897.                                 }
  898.                                 if (obj.special != 100) {
  899.                                         ship.damageAccumulated += obj.animSpeed;
  900.                                         ship.accumulationTime = 0;
  901.                                         obj.special = 100;
  902.                                 }
  903.                                 if (obj.eventID == OBJECT::ICEBULLET || obj.eventID == OBJECT::ICEBULLETPU) damageNumber(creator, play, ship.damageCalc(ship, ship.damageAccumulated));
  904.                                
  905.                                 if (!ship.justHit) {
  906.                                         ship.justHit = true;
  907.                                         ship.hitDelay = 0;
  908.                                 }
  909.                                 jjSample(play.xPos, play.yPos, SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500);
  910.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  911.                                 obj.state = STATE::EXPLODE;
  912.                                 obj.scriptedCollisions = false;
  913.                         }
  914.                         return true;
  915.                 }
  916.         }
  917.  
  918.         class HomingMissile : jjBEHAVIORINTERFACE {
  919.                 void onBehave(jjOBJ@ obj) {
  920.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  921.                         obj.behave(BEHAVIOR::BULLET, obj.state == STATE::FLY && inView(obj)? false:true);
  922.                         obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
  923.                         ++obj.age;
  924.                         if (obj.state == STATE::FLY && obj.counter > 1 && inView(obj)) jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.var[0], 1, 1, SPRITE::NORMAL);
  925.                        
  926.                                 if (obj.state == STATE::START) {
  927.                                         obj.points = int(atan2(obj.xSpeed, obj.ySpeed) * 162.974636 /*+ (jjCos(jjRandom() % 512) * 10)*/); //angle
  928.                                         obj.state = STATE::FLY;
  929.                                         obj.xSpeed += obj.var[7] / 65536.f;
  930.                                 } else if (obj.age > 14) { //redirect
  931.                                         array<float>@ target = null;
  932.                                         if (obj.creatorType == CREATOR::PLAYER && jjGameMode > GAME::COOP) {
  933.                                                 const int targetPlayerID = closestPlayers[obj.creatorID]; //closest to player who fired this
  934.                                                 if (targetPlayerID >= 0)
  935.                                                         @target = array<float> = { jjPlayers[targetPlayerID].xPos, jjPlayers[targetPlayerID].yPos };
  936.                                         }
  937.                                         if (target is null)
  938.                                                 @target = MLLEWeapons::HelpfulBulletFunctions::GetNearestEnemyPosition(obj, 350); //closest to bullet itself... this part is new to the .asc reimplementation
  939.                                        
  940.                                         if (target !is null) {
  941.                                                 int difference = ((int(atan2(obj.xPos - target[0], obj.yPos - target[1]) * 162.974636) + 512 - obj.points) & 1023);
  942.                                                 if (difference >= 512) difference -= 1024;
  943.                                                 obj.points += difference / 8;
  944.                                                 obj.xSpeed = 5 * jjSin(obj.points);
  945.                                                 obj.ySpeed = 5 * jjCos(obj.points);
  946.                                         }
  947.                                 }
  948.                         if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
  949.                        
  950.                         if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
  951.                                 obj.xPos = creator.xPos;
  952.                                 obj.yPos = creator.yPos;
  953.                         }
  954.                 }
  955.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  956.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  957.                         SPACESHIP@ ship = Ships[play.playerID];
  958.                        
  959.                         if (canBeHit(play,creator,obj) && obj.state != STATE::EXPLODE) {
  960.                                 ship.xSpeed += recoilX(ship,obj,55);
  961.                                 ship.ySpeed += recoilY(ship,obj,55);
  962.                                 randomHurtSample(play, 0);
  963.                                
  964.                                 if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::SEEKERBULLETPU? jjObjectPresets[OBJECT::SEEKERBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::SEEKERBULLET].animSpeed * 1.5);
  965.                                
  966.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  967.                                         if (play.isLocal) {
  968.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  969.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  970.                                         }
  971.                                 } else {
  972.                                         if (play.isLocal) {
  973.                                                 play.hurt(7, true, creator);
  974.                                         }
  975.                                 }
  976.                                 if (!ship.justHit) {
  977.                                         ship.justHit = true;
  978.                                         ship.hitDelay = 0;
  979.                                 }
  980.                                 jjSample(play.xPos, play.yPos, SOUND::COMMON_EXPL_TNT, 63, 12500 + jjRandom()%2500);
  981.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  982.                                 obj.state = STATE::EXPLODE;
  983.                                 obj.scriptedCollisions = false;
  984.                         }
  985.                         return true;
  986.                 }
  987.         }
  988.  
  989.         class SuperMissile : jjBEHAVIORINTERFACE {
  990.                 void onBehave(jjOBJ@ obj) {
  991.                         obj.behave(BEHAVIOR::BULLET, false);
  992.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  993.                         jjPLAYER@ play;
  994.                         obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
  995.                        
  996.                         switch (obj.state) {
  997.                                 case STATE::START:
  998.                                         obj.state = STATE::FLY;
  999.                                         obj.lightType = LIGHT::POINT;
  1000.                                         obj.var[2] = 0;
  1001.                                 break;
  1002.                                
  1003.                                 case STATE::FLY:
  1004.                                         if (obj.counter == 1 && creator.isLocal) {
  1005.                                                 jjSample(creator.xPos, creator.yPos, SOUND::INTRO_SHOT1, 0, obj.eventID == OBJECT::RFBULLETPU? 35500 : 0);
  1006.                                         }
  1007.                                        
  1008.                                         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);
  1009.                                        
  1010.                                         if (obj.counter % 5 == 0 && !jjLowDetail) {
  1011.                                                 jjOBJ@ trail = jjObjects[jjAddObject(OBJECT::EXPLOSION, int(obj.xPos - jjCos(obj.var[0])), int(obj.yPos - jjSin(obj.var[0])))];
  1012.                                                 trail.determineCurAnim(ANIM::AMMO, 3);
  1013.                                                 trail.lightType = LIGHT::NONE;
  1014.                                                 trail.playerHandling = HANDLING::PARTICLE;
  1015.                                                 trail.bulletHandling = HANDLING::IGNOREBULLET;
  1016.                                                 trail.isBlastable = false;
  1017.                                         }
  1018.  
  1019.                                 break;
  1020.                                
  1021.                                 case STATE::EXPLODE:
  1022.                                         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);
  1023.                                
  1024.                                         if (obj.var[2] == 0) {
  1025.                                                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_BENZIN1);
  1026.                                                 Shockwave temp;
  1027.                                                 jjOBJ@ blast = jjObjects[jjAddObject(OBJECT::BULLET, obj.xPos, obj.yPos, obj.creatorID, CREATOR::PLAYER, jjVOIDFUNCOBJ(temp.onBehave))];
  1028.                                                 obj.var[2] = 1;
  1029.                                                 blast.var[2] = 1;
  1030.                                                 blast.var[8] = obj.var[8];
  1031.                                                 blast.animSpeed = obj.animSpeed;
  1032.                                                 blast.eventID = OBJECT::BULLET;
  1033.                                         }
  1034.                                 break;
  1035.                         }
  1036.                        
  1037.                         if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
  1038.                        
  1039.                         if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
  1040.                                 obj.xPos = creator.xPos;
  1041.                                 obj.yPos = creator.yPos;
  1042.                         }
  1043.                 }
  1044.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1045.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1046.                         SPACESHIP@ ship = Ships[play.playerID];
  1047.                        
  1048.                         if (canBeHit(play,creator,obj) && obj.var[8] & 1 << play.playerID == 0) {
  1049.                                 ship.xSpeed += recoilX(ship,obj,30);
  1050.                                 ship.ySpeed += recoilY(ship,obj,30);
  1051.                                 randomHurtSample(play, 0);
  1052.                                
  1053.                                 if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::RFBULLETPU? jjObjectPresets[OBJECT::RFBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::RFBULLET].animSpeed * 1.5);
  1054.                                
  1055.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  1056.                                         if (play.isLocal) {
  1057.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  1058.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  1059.                                         }
  1060.                                 } else {
  1061.                                         if (play.isLocal) {
  1062.                                                 play.hurt(7, true, creator);
  1063.                                         }
  1064.                                 }
  1065.                                 if (!ship.justHit) {
  1066.                                         ship.justHit = true;
  1067.                                         ship.hitDelay = 0;
  1068.                                 }
  1069.                                 obj.var[8] = obj.var[8] | 1 << play.playerID;
  1070.                                 jjSample(play.xPos, play.yPos, SOUND::COMMON_EXPL_TNT, 63, 12500 + jjRandom()%2500);
  1071.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  1072.                                 obj.state = STATE::EXPLODE;
  1073.                                 obj.scriptedCollisions = false;
  1074.                         }
  1075.                         return true;
  1076.                 }
  1077.         }
  1078.  
  1079.         class Shockwave : jjBEHAVIORINTERFACE {
  1080.                 void onBehave(jjOBJ@ obj) {
  1081.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1082.                        
  1083.                         obj.playerHandling = HANDLING::PARTICLE;
  1084.                         obj.bulletHandling = HANDLING::IGNOREBULLET;
  1085.                        
  1086.                         if (obj.var[2] == 1) {
  1087.                                 obj.lightType = obj.var[2] == 1? LIGHT::RING2 : LIGHT::NONE;
  1088.                                 obj.var[1] = obj.var[1] + 1;
  1089.                                 obj.light += 2;
  1090.                                 obj.var[4] = obj.light * 4;
  1091.                                 obj.var[5] = obj.animSpeed - ((obj.var[4] * obj.animSpeed)/216);
  1092.                                
  1093.                                 if (obj.var[4] >= 200) obj.var[6] = 20;
  1094.                                 else if (obj.var[4] >= 100 && obj.var[6] < 200) obj.var[6] = 30;
  1095.                                 else if (obj.var[4] < 100) obj.var[6] = 40;
  1096.                                
  1097.                                 for (int i = 1; i < jjObjectCount; i++) {
  1098.                                         jjOBJ@ target = jjObjects[i];
  1099.                                         float dx = target.xPos - obj.xPos, dy = target.yPos - obj.yPos;
  1100.                                         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) {
  1101.                                                 if (dx * dx + dy * dy < obj.var[4] * obj.var[4]) {
  1102.                                                         if (target.eventID != OBJECT::TNT) {
  1103.                                                                 obj.objectHit(target, target.playerHandling == HANDLING::ENEMY? HANDLING::ENEMY : HANDLING::SPECIAL);
  1104.                                                                 if (target.playerHandling != HANDLING::ENEMY) target.state = STATE::KILL;
  1105.                                                         } else {
  1106.                                                                 target.state = STATE::EXPLODE;
  1107.                                                                 target.counter = 18;
  1108.                                                         }
  1109.                                                         if (target.playerHandling != HANDLING::ENEMY) target.var[4] = 1;
  1110.                                                 }
  1111.                                                 else target.var[4] = 0;
  1112.                                         }
  1113.                                 }
  1114.                                
  1115.                                
  1116.                                 if (gameIsActive()) {
  1117.                                         for (int i = 0; i < 32; i++) {
  1118.                                                 jjPLAYER@ play = jjPlayers[i];
  1119.                                                 SPACESHIP@ ship = Ships[play.playerID];
  1120.                                                 if (canBeHit(play,creator,obj) && obj.var[4] > 0) {
  1121.                                                         float dx = play.xPos - obj.xPos, dy = play.yPos - obj.yPos;
  1122.                                                         if (dx * dx + dy * dy < obj.var[4] * obj.var[4]) {
  1123.                                                                 if (obj.var[8] & 1 << i == 0 && play.blink == 0 && obj.var[5] > 0) {
  1124.                                                                         obj.var[8] = obj.var[8] | 1 << i;
  1125.                                                                         jjSample(play.xPos, play.yPos, SOUND::ROBOT_HYDROPUF, 63, 12500 + jjRandom()%2500);
  1126.                                                                         if ((ship.health - ship.damageCalc(ship, obj.var[5])) > 0) {
  1127.                                                                                 if (play.isLocal) {
  1128.                                                                                         ship.health -= ship.damageCalc(ship, obj.var[5]);
  1129.                                                                                         if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.var[5]) * 2;
  1130.                                                                                 }
  1131.                                                                                 randomHurtSample(play, 0);
  1132.                                                                                
  1133.                                                                                 ship.damageAccumulated += obj.var[5];
  1134.                                                                                 ship.accumulationTime = 0;
  1135.                                                                                 if (!play.isLocal) damageNumber(creator, play, ship.damageCalc(ship, obj.var[5]));
  1136.                                                                                
  1137.                                                                                 int angle = int(atan2(play.yPos - obj.yPos, play.xPos - obj.xPos) * (512 / PI));
  1138.                                                                                 obj.ySpeed = jjSin(angle) * 32;
  1139.                                                                                 obj.xSpeed = jjCos(angle) * 32;
  1140.                        
  1141.                                                                                 ship.xSpeed += recoilX(ship,obj,obj.var[6]);
  1142.                                                                                 ship.ySpeed += recoilY(ship,obj,obj.var[6]);
  1143.  
  1144.                                                                         } else {
  1145.                                                                                 if (play.isLocal) {
  1146.                                                                                         play.hurt(7, true, creator);
  1147.                                                                                 }
  1148.                                                                                 if (creator.isLocal) {
  1149.                                                                                         ship.SDPunishment = true;
  1150.                                                                                 }
  1151.                                                                         }
  1152.                                                                         if (!ship.justHit) {
  1153.                                                                                 ship.justHit = true;
  1154.                                                                                 ship.hitDelay = 0;
  1155.                                                                         }
  1156.                                                                 }
  1157.                                                         }
  1158.                                                 }
  1159.                                         }
  1160.                                 }
  1161.                         }
  1162.                        
  1163.                         if (obj.var[1] == 27) {
  1164.                                 obj.var[1] = 0;
  1165.                                 obj.var[2] = 0;
  1166.                                 obj.var[4] = 0;
  1167.                                 obj.delete();
  1168.                         }
  1169.                 }
  1170.         }
  1171.  
  1172.  
  1173.         class Flamethrower : jjBEHAVIORINTERFACE {
  1174.                 float xSpeed, ySpeed, xPos, yPos;
  1175.                 void onBehave(jjOBJ@ obj) {
  1176.                         obj.behave(BEHAVIOR::TOASTERBULLET, false);
  1177.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1178.                        
  1179.                         if (obj.state == STATE::FLY) {
  1180.                                 obj.var[0] = int(creator.xSpeed);
  1181.                                 if (obj.counter <= 3) {
  1182.                                         xSpeed = obj.xSpeed;
  1183.                                         ySpeed = obj.ySpeed;
  1184.                                 }
  1185.                                 if (obj.counter <= 7) {
  1186.                                         obj.xSpeed = xSpeed * 2;
  1187.                                         obj.ySpeed = ySpeed * 2;
  1188.                                 }
  1189.                                
  1190.                                 obj.counter++;
  1191.                                
  1192.                                 if (obj.counter > 1 && inView(obj)) {
  1193.                                         jjDrawSprite(obj.xPos, obj.yPos, ANIM::AMMO, 13, jjGameTicks >> 2, obj.direction, obj.eventID == OBJECT::TOASTERBULLETPU? SPRITE::SINGLEHUE : SPRITE::NORMAL, 32);
  1194.                                 }
  1195.                                
  1196.                                 if (obj.counter >= 200) obj.delete();
  1197.                         }
  1198.                         if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
  1199.                 }
  1200.                
  1201.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1202.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1203.                         SPACESHIP@ ship = Ships[play.playerID];
  1204.                        
  1205.                         if (canBeHit(play,creator,obj) && obj.state != STATE::EXPLODE) {
  1206.                                 ship.xSpeed += recoilX(ship,obj,8);
  1207.                                 ship.ySpeed += recoilY(ship,obj,8);
  1208.                                 randomHurtSample(play, 0);
  1209.                                
  1210.                                 if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::TOASTERBULLETPU? jjObjectPresets[OBJECT::TOASTERBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::TOASTERBULLET].animSpeed * 1.5);
  1211.                                
  1212.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  1213.                                         if (play.isLocal) {
  1214.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  1215.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  1216.                                         }
  1217.                                 } else {
  1218.                                         if (play.isLocal) {
  1219.                                                 play.hurt(7, true, creator);
  1220.                                         }
  1221.                                 }
  1222.                                 if (!ship.justHit) {
  1223.                                         ship.justHit = true;
  1224.                                         ship.hitDelay = 0;
  1225.                                 }
  1226.                                 obj.state = STATE::EXPLODE;
  1227.                                 obj.scriptedCollisions = false;
  1228.                                 jjSample(play.xPos, play.yPos, SOUND::BILSBOSS_FIRE, 63, 12500 + jjRandom()%2500);
  1229.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  1230.                         }
  1231.                         return true;
  1232.                 }
  1233.         }
  1234.  
  1235.         class SpikeMine : jjBEHAVIORINTERFACE {
  1236.                 bool isPowerup = false;
  1237.  
  1238.                 void onBehave(jjOBJ@ obj) {
  1239.                         obj.behave(obj.state == STATE::EXPLODE && obj.counter >= 18 && inView(obj)? BEHAVIOR::BULLET : BEHAVIOR::TNT, false);
  1240.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1241.                         SPACESHIP@ ship = Ships[creator.playerID];
  1242.                        
  1243.                         obj.animSpeed = creator is jjTokenOwner? (isPowerup? 210:105) : (isPowerup? 140:70);
  1244.                        
  1245.                         if (obj.state != STATE::EXPLODE) {
  1246.                                 obj.xPos = obj.xPos + obj.xSpeed;
  1247.                                 obj.yPos = obj.yPos + obj.ySpeed;
  1248.                                
  1249.                                 jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, isPowerup? SPRITE::SINGLEHUE : SPRITE::NORMAL, 40);
  1250.  
  1251.                                 if (obj.counter == 1) {
  1252.                                         if (ship.tntPowerup) isPowerup = true;
  1253.                                         else isPowerup = false;
  1254.                                        
  1255.                                         if (creator.isLocal) jjSample(obj.xPos, obj.yPos, SOUND::ROBOT_SHOOT, 0, isPowerup? 17500 : 0);
  1256.                                         obj.xSpeed = creator.xSpeed / -4;
  1257.                                         obj.ySpeed = (creator.ySpeed < 0.2 && creator.ySpeed > -0.2)? 0 : creator.ySpeed / -4;
  1258.                                 }
  1259.                                 if (obj.counter >= 175) {
  1260.                                         if (obj.counter % 20 > 9) jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::TRANSLUCENTSINGLEHUE, 24);
  1261.                                         obj.var[0] = jjSampleLooped(obj.xPos, obj.yPos, SOUND::COMMON_CLOCK, obj.var[0], 0, 0);
  1262.                                 }
  1263.                                
  1264.                                 if (jjMaskedPixel(int(obj.xPos), int(obj.yPos))) {
  1265.                                         obj.counter = 18;
  1266.                                         obj.state = STATE::EXPLODE;
  1267.                                 }
  1268.                         } else {
  1269.                                 if (obj.counter == 18) {
  1270.                                         jjDrawResizedSprite(obj.xPos, obj.yPos, ANIM::AMMO, 5, obj.curFrame, 2, 2, SPRITE::NORMAL);
  1271.                                        
  1272.                                         obj.behavior = BEHAVIOR::BULLET;
  1273.                                        
  1274.                                         if (obj.var[2] == 0) {
  1275.                                                 jjSample(obj.xPos, obj.yPos, SOUND::COMMON_BENZIN1);
  1276.                                                 Shockwave temp;
  1277.                                                 jjOBJ@ blast = jjObjects[jjAddObject(OBJECT::BULLET, obj.xPos, obj.yPos, obj.creatorID, CREATOR::PLAYER, jjVOIDFUNCOBJ(temp.onBehave))];
  1278.                                                 obj.var[2] = 1;
  1279.                                                 blast.var[2] = 1;
  1280.                                                 blast.var[8] = obj.var[8];
  1281.                                                 blast.animSpeed = obj.animSpeed;
  1282.                                                 blast.eventID = OBJECT::BULLET;
  1283.                                         }
  1284.                                 } else {
  1285.                                         jjDrawResizedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, (1 + (obj.counter/4)), (1 + (obj.counter/4)), isPowerup? SPRITE::SINGLEHUE : SPRITE::NORMAL, 40);
  1286.                                 }
  1287.                         }
  1288.                         if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
  1289.                        
  1290.                         if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
  1291.                                 obj.xPos = creator.xPos;
  1292.                                 obj.yPos = creator.yPos;
  1293.                         }
  1294.                 }
  1295.                
  1296.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1297.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1298.                         SPACESHIP@ ship = Ships[play.playerID];
  1299.                        
  1300.                         if (canBeHit(play,creator,obj) && obj.var[8] & 1 << play.playerID == 0) {
  1301.                                 ship.xSpeed += recoilX(ship,obj,20);
  1302.                                 ship.ySpeed += recoilY(ship,obj,20);
  1303.                                 randomHurtSample(play, 0);
  1304.                                
  1305.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  1306.                                         if (play.isLocal) {
  1307.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  1308.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  1309.                                         }
  1310.                                 } else {
  1311.                                         if (play.isLocal) {
  1312.                                                 play.hurt(7, true, creator);
  1313.                                         }
  1314.                                 }
  1315.                                 if (!ship.justHit) {
  1316.                                         ship.justHit = true;
  1317.                                         ship.hitDelay = 0;
  1318.                                 }
  1319.                                 obj.var[8] = obj.var[8] | 1 << play.playerID;
  1320.                                 obj.counter = 18;
  1321.                                 obj.state = STATE::EXPLODE;
  1322.                                 obj.scriptedCollisions = false;
  1323.                                 jjSample(play.xPos, play.yPos, SOUND::COMMON_EXPL_TNT, 63, 12500 + jjRandom()%2500);
  1324.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  1325.                         }
  1326.                         return true;
  1327.                 }
  1328.         }
  1329.  
  1330.         class Laser : jjBEHAVIORINTERFACE {
  1331.                 void onBehave(jjOBJ@ obj) {
  1332.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1333.                         obj.behave(BEHAVIOR::BULLET, obj.state == STATE::EXPLODE && inView(obj)? true:false);
  1334.                         obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
  1335.                         if (obj.state == STATE::FLY) {
  1336.                                 if (obj.counter == 1 && jjPlayers[obj.creatorID].isLocal) jjSample(obj.xPos, obj.yPos, SOUND::AMMO_LASER, 0, obj.eventID == OBJECT::BLASTERBULLETPU? 12500:0);
  1337.                                 if (obj.ySpeed < -15) obj.ySpeed = -15;
  1338.                                 if (obj.ySpeed > 15) obj.ySpeed = 15;
  1339.                         }
  1340.                        
  1341.                         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);
  1342.                        
  1343.                         if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
  1344.                        
  1345.                         if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
  1346.                                 obj.xPos = creator.xPos;
  1347.                                 obj.yPos = creator.yPos;
  1348.                         }
  1349.                 }
  1350.                
  1351.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1352.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1353.                         SPACESHIP@ ship = Ships[play.playerID];
  1354.                        
  1355.                         if (canBeHit(play,creator,obj) && obj.var[8] & 1 << play.playerID == 0) {
  1356.                                 ship.xSpeed += recoilX(ship,obj,40);
  1357.                                 ship.ySpeed += recoilY(ship,obj,40);
  1358.                                 randomHurtSample(play, 0);
  1359.                                
  1360.                                 if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::FIREBALLBULLETPU? jjObjectPresets[OBJECT::FIREBALLBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::FIREBALLBULLET].animSpeed * 1.5);
  1361.                                
  1362.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  1363.                                         if (play.isLocal) {
  1364.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  1365.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  1366.                                         }
  1367.                                 } else {
  1368.                                         if (play.isLocal) {
  1369.                                                 play.hurt(7, true, creator);
  1370.                                         }
  1371.                                 }
  1372.                                 if (!ship.justHit) {
  1373.                                         ship.justHit = true;
  1374.                                         ship.hitDelay = 0;
  1375.                                 }
  1376.                                 obj.var[8] = obj.var[8] | 1 << play.playerID;
  1377.                                 jjSample(play.xPos, play.yPos, SOUND::ROBOT_BIG2, 63, 12500 + jjRandom()%2500);
  1378.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  1379.                         }
  1380.                         return true;
  1381.                 }
  1382.         }
  1383.  
  1384.         class ElectroBlaster : jjBEHAVIORINTERFACE {
  1385.                 void onBehave(jjOBJ@ obj) {
  1386.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1387.                         obj.behave(BEHAVIOR::ELECTROBULLET, obj.counter > 1 && inView(obj)? true:false);
  1388.                        
  1389.                         obj.xPos += jjCos(obj.counter*36)*(obj.ySpeed/3);
  1390.                         obj.yPos += jjSin(obj.counter*36)*(obj.xSpeed/3);
  1391.                        
  1392.                         if (obj.findNearestPlayer(500) > -1 && obj.findNearestPlayer(500) != creator.playerID) handleShipCollisions(obj, creator);
  1393.                        
  1394.                         if ((creator.charCurr == CHAR::JAZZ || creator.charCurr == CHAR::LORI) && obj.counter == 1 && obj.state != STATE::EXPLODE) {
  1395.                                 obj.xPos = creator.xPos;
  1396.                                 obj.yPos = creator.yPos;
  1397.                         }
  1398.                 }
  1399.                
  1400.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1401.                         jjPLAYER@ creator = jjPlayers[obj.creatorID];
  1402.                         SPACESHIP@ ship = Ships[play.playerID];
  1403.                        
  1404.                         if (canBeHit(play,creator,obj) && obj.state != STATE::EXPLODE) {
  1405.                                 ship.xSpeed += recoilX(ship,obj,15);
  1406.                                 ship.ySpeed += recoilY(ship,obj,15);
  1407.                                 randomHurtSample(play, 0);
  1408.                                
  1409.                                 if (creator is jjTokenOwner) obj.animSpeed = int(obj.eventID == OBJECT::ELECTROBULLETPU? jjObjectPresets[OBJECT::ELECTROBULLETPU].animSpeed * 1.5 : jjObjectPresets[OBJECT::ELECTROBULLET].animSpeed * 1.5);
  1410.                                
  1411.                                 if ((ship.health - ship.damageCalc(ship, obj.animSpeed)) > 0) {
  1412.                                         if (play.isLocal) {
  1413.                                                 ship.health -= ship.damageCalc(ship, obj.animSpeed);
  1414.                                                 if (ship.armor > 0) ship.armor -= ship.damageCalc(ship, obj.animSpeed) * 2;
  1415.                                         }
  1416.                                 } else {
  1417.                                         if (play.isLocal) {
  1418.                                                 play.hurt(7, true, creator);
  1419.                                         }
  1420.                                 }
  1421.                                 if (!ship.justHit) {
  1422.                                         ship.justHit = true;
  1423.                                         ship.hitDelay = 0;
  1424.                                 }
  1425.                                 jjSample(play.xPos, play.yPos, SOUND::COMMON_ELECTRICHIT, 63, 12500 + jjRandom()%2500);
  1426.                                 if (ship.armor > 0) jjSample(play.xPos, play.yPos, SOUND::COMMON_LAND1, 63, 12500 + jjRandom()%2500);
  1427.                                 obj.state = STATE::EXPLODE;
  1428.                                 obj.scriptedCollisions = false;
  1429.                         }
  1430.                         return true;
  1431.                 }
  1432.         }
  1433.  
  1434.         bool inView(const jjOBJ@ obj) {
  1435.                 for (int i = 0; i < jjLocalPlayerCount; i++) {
  1436.                         const jjPLAYER@ play = jjLocalPlayers[i];
  1437.                         if (obj.xPos > play.cameraX - 64 && obj.yPos > play.cameraY - 64 && obj.xPos < play.cameraX + jjSubscreenWidth + 64 && obj.yPos < play.cameraY + jjSubscreenHeight + 64)
  1438.                                 return true;
  1439.                 }
  1440.                 return false;
  1441.         }
  1442.  
  1443.         bool shipInView(jjPLAYER@ play) {
  1444.                 for (int i = 0; i < jjLocalPlayerCount; i++) {
  1445.                         const jjPLAYER@ player = jjLocalPlayers[i];
  1446.                         if (play.xPos > player.cameraX - 64 && play.yPos > player.cameraY - 64 && play.xPos < player.cameraX + jjSubscreenWidth + 64 && play.yPos < player.cameraY + jjSubscreenHeight + 64)
  1447.                                 return true;
  1448.                 }
  1449.                 return false;
  1450.         }
  1451.  
  1452.         void damageNumber(jjPLAYER@ creator, jjPLAYER@ play, int num) {
  1453.                 if (creator.isLocal) {
  1454.                         jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
  1455.                         if (text !is null) {
  1456.                                 text.xPos = play.xPos;
  1457.                                 text.yPos = play.yPos;
  1458.                                 text.ySpeed = -0.25;
  1459.                                 text.string.text = "" + num;
  1460.                         }
  1461.                         jjSample(creator.xPos, creator.yPos, SOUND::MENUSOUNDS_TYPE, 63, 28500 - (num * 50));
  1462.                         crosshairFlash = true;
  1463.                         crosshairTime = 0;
  1464.                 }
  1465.         }
  1466.  
  1467.         class AmmoPickup : jjBEHAVIORINTERFACE {
  1468.                 float getY(const ::jjOBJ@ obj) const {
  1469.                         int arg = (((obj.objectID << 3) + ::jjGameTicks) << (obj.yPos > ::jjWaterLevel ? 1 : 4)) + (int(obj.xPos) << 4);
  1470.                         return obj.yPos + ::jjSin(arg) * 4.f;
  1471.                 }
  1472.                 void onBehave(jjOBJ@ obj) {
  1473.                         obj.behave(BEHAVIOR::PICKUP, obj.eventID == OBJECT::TNTAMMO3? false:true);
  1474.                         if (obj.eventID == OBJECT::TNTAMMO3) {
  1475.                                 jjDrawSprite(obj.xPos, getY(obj), ANIM::ROBOT, 0, 0, 0, SPRITE::SINGLEHUE, (jjLocalPlayers[0].powerup[WEAPON::TNT]? 40:72));
  1476.                         }
  1477.                 }
  1478.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1479.                         if (play.ammo[obj.var[4]] < jjWeapons[obj.var[4]].maximum) {
  1480.                                 if (play.ammo[obj.var[4]] + obj.var[5] > jjWeapons[obj.var[4]].maximum) {
  1481.                                         play.ammo[obj.var[4]] = jjWeapons[obj.var[4]].maximum;
  1482.                                 } else {
  1483.                                         if (jjAutoWeaponChange && play.ammo[obj.var[4]] == 0) play.currWeapon = obj.var[4];
  1484.                                         play.ammo[obj.var[4]] = play.ammo[obj.var[4]] + obj.var[5];
  1485.                                 }
  1486.                                 if (play.isLocal) jjSample(play.xPos, play.yPos, SOUND::COMMON_PICKUPW1);
  1487.                                 obj.behavior = BEHAVIOR::EXPLOSION2;
  1488.                                 obj.scriptedCollisions = false;
  1489.                                 obj.frameID = 0;
  1490.                         }
  1491.                         return true;
  1492.                 }
  1493.         }
  1494.  
  1495.         class HealthPickup : jjBEHAVIORINTERFACE {
  1496.                 void onBehave(jjOBJ@ obj) {
  1497.                         obj.behave(BEHAVIOR::PICKUP);
  1498.                         obj.direction = 1;
  1499.                 }
  1500.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1501.                         SPACESHIP@ ship = Ships[play.playerID];
  1502.                        
  1503.                         int amount = ship.health > (maxHealth - int(maxHealth/5))? maxHealth - ship.health : int(maxHealth/5);
  1504.                        
  1505.                         if (ship.health < maxHealth && play.blink == 0) {
  1506.                                 sendShipRotationPacket(ship);
  1507.                                 ship.health += amount;
  1508.                                
  1509.                                 if (play.isLocal) {
  1510.                                         jjSample(play.xPos, play.yPos, SOUND::COMMON_MONITOR);
  1511.                                         jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
  1512.                                         if (text !is null) {
  1513.                                                 text.xPos = play.xPos;
  1514.                                                 text.yPos = play.yPos;
  1515.                                                 text.ySpeed = -0.25;
  1516.                                                 text.string.text = "|||||+" + amount;
  1517.                                         }      
  1518.                                 }
  1519.                                 play.invincibility = 70;
  1520.                                 obj.behavior = BEHAVIOR::EXPLOSION2;
  1521.                                 obj.scriptedCollisions = false;
  1522.                                 obj.frameID = 0;
  1523.                         }
  1524.                         return true;
  1525.                 }
  1526.         }
  1527.  
  1528.  
  1529.         class MegaHealthPickup : jjBEHAVIORINTERFACE {
  1530.                 void onBehave(jjOBJ@ obj) {
  1531.                         obj.behave(BEHAVIOR::PICKUP);
  1532.                         obj.direction = 1;
  1533.                 }
  1534.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1535.                         SPACESHIP@ ship = Ships[play.playerID];
  1536.                        
  1537.                         int amount = ship.health > maxHealth? (maxHealth*2) - ship.health : maxHealth;
  1538.                        
  1539.                         if (ship.health < (maxHealth*2) && play.blink == 0) {
  1540.                                 sendShipRotationPacket(ship);
  1541.                                 ship.health += amount;
  1542.  
  1543.                                 if (play.isLocal) {
  1544.                                         jjSample(play.xPos, play.yPos, SOUND::COMMON_ITEMTRE);
  1545.                                         jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
  1546.                                         if (text !is null) {
  1547.                                                 text.xPos = play.xPos;
  1548.                                                 text.yPos = play.yPos;
  1549.                                                 text.ySpeed = -0.25;
  1550.                                                 text.string.text = "|||||+" + amount;
  1551.                                         }
  1552.                                         playHappySample(play);
  1553.                                 }
  1554.                                 play.invincibility = 210;
  1555.                                 obj.behavior = BEHAVIOR::EXPLOSION2;
  1556.                                 obj.scriptedCollisions = false;
  1557.                                 obj.frameID = 0;
  1558.                         }
  1559.                         return true;
  1560.                 }
  1561.         }
  1562.  
  1563.         class ShieldPickup : jjBEHAVIORINTERFACE {
  1564.                 void onBehave(jjOBJ@ obj) {
  1565.                         obj.behave(BEHAVIOR::PICKUP);
  1566.                         obj.direction = 1;
  1567.                 }
  1568.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1569.                         SPACESHIP@ ship = Ships[play.playerID];
  1570.                        
  1571.                         int amount = ship.armor > maxHealth? maxHealth - ship.armor : int(maxHealth/2);
  1572.                        
  1573.                         if (ship.armor < maxHealth) {
  1574.                                 sendShipRotationPacket(ship);
  1575.                                 ship.armor += amount;
  1576.                                
  1577.                                 if (play.isLocal) {
  1578.                                         jjSample(play.xPos, play.yPos, SOUND::INTRO_SHOTGRN);
  1579.                                         jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
  1580.                                         if (text !is null) {
  1581.                                                 text.xPos = play.xPos;
  1582.                                                 text.yPos = play.yPos;
  1583.                                                 text.ySpeed = -0.25;
  1584.                                                 text.string.text = "|+" + amount;
  1585.                                         }
  1586.                                 }
  1587.                                 obj.behavior = BEHAVIOR::EXPLOSION2;
  1588.                                 obj.scriptedCollisions = false;
  1589.                                 obj.frameID = 0;
  1590.                         }
  1591.                         return true;
  1592.                 }
  1593.         }
  1594.  
  1595.         class MegaShieldPickup : jjBEHAVIORINTERFACE {
  1596.                 void onBehave(jjOBJ@ obj) {
  1597.                         obj.behave(BEHAVIOR::PICKUP);
  1598.                         obj.direction = 1;
  1599.                 }
  1600.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1601.                         SPACESHIP@ ship = Ships[play.playerID];
  1602.                        
  1603.                         int amount = ship.armor > maxHealth? (maxHealth*2) - ship.armor : maxHealth;
  1604.                        
  1605.                         if (ship.armor < (maxHealth * 2)) {
  1606.                                 sendShipRotationPacket(ship);
  1607.                                 ship.armor += amount;
  1608.                                
  1609.                                 if (play.isLocal) {
  1610.                                         jjSample(play.xPos, play.yPos, SOUND::INTRO_SHOTGRN, 0, 18000);
  1611.                                         jjPARTICLE@ text = jjAddParticle(PARTICLE::STRING);
  1612.                                         if (text !is null) {
  1613.                                                 text.xPos = play.xPos;
  1614.                                                 text.yPos = play.yPos;
  1615.                                                 text.ySpeed = -0.25;
  1616.                                                 text.string.text = "|+" + amount;
  1617.                                         }
  1618.                                         playHappySample(play);
  1619.                                 }
  1620.                                 obj.behavior = BEHAVIOR::EXPLOSION2;
  1621.                                 obj.scriptedCollisions = false;
  1622.                                 obj.frameID = 0;
  1623.                         }
  1624.                         return true;
  1625.                 }
  1626.         }
  1627.  
  1628.         class PowerOrb : jjBEHAVIORINTERFACE {
  1629.                 void onBehave(jjOBJ@ obj) {
  1630.                         obj.behave(BEHAVIOR::PICKUP);
  1631.                         obj.direction = 1;
  1632.                 }
  1633.                 bool onObjectHit(jjOBJ@ obj, jjOBJ@ bull, jjPLAYER@ play, int force) {
  1634.                         SPACESHIP@ ship = Ships[play.playerID];
  1635.                        
  1636.                         sendShipRotationPacket(ship);
  1637.                         ship.powerUp = true;
  1638.                         ship.powerTime = 30*70;
  1639.                         if (play.isLocal) {
  1640.                                 jjSample(play.xPos, play.yPos, SOUND::BILSBOSS_FIRESTART, 0, 0);
  1641.                                 playWarCry(play);
  1642.                         }
  1643.                         obj.behavior = BEHAVIOR::EXPLOSION2;
  1644.                         obj.scriptedCollisions = false;
  1645.                         obj.frameID = 0;
  1646.                        
  1647.                         return true;
  1648.                 }
  1649.         }
  1650.  
  1651.         class ShipExplosion : jjBEHAVIORINTERFACE {
  1652.                 void onBehave(jjOBJ@ obj) {
  1653.                
  1654.                         obj.frameID++;
  1655.                         if (obj.frameID == 2 && jjGameTicks > 70) {
  1656.                                 obj.particlePixelExplosion(1);
  1657.                                 jjSample(obj.xPos, obj.yPos, SOUND::INTRO_BOEM2);
  1658.                         }
  1659.                         if (obj.frameID == 84) obj.delete();
  1660.                        
  1661.                         jjDrawResizedSprite(obj.xPos, obj.yPos, ANIM::AMMO, 5, obj.frameID / 7, 2, 2, SPRITE::NORMAL);
  1662.                 }
  1663.         }
  1664.  
  1665.         void playHappySample(jjPLAYER@ play) {
  1666.                 switch (play.charCurr) {
  1667.                         case CHAR::JAZZ: jjSample(play.xPos, play.yPos, SOUND::JAZZSOUNDS_JUMMY, 0, 0); break;
  1668.                         case CHAR::SPAZ: jjSample(play.xPos, play.yPos, SOUND::SPAZSOUNDS_HAPPY, 0, 0); break;
  1669.                         case CHAR::LORI: jjSample(play.xPos, play.yPos, SOUND::LORISOUNDS_WEHOO, 0, 0); break;
  1670.                         default: break;
  1671.                 }
  1672.         }
  1673.  
  1674.         void playWarCry(jjPLAYER@ play) {
  1675.                 switch (play.charCurr) {
  1676.                         case CHAR::JAZZ: jjSample(play.xPos, play.yPos, SOUND::JAZZSOUNDS_IDLE, 0, 0); break;
  1677.                         case CHAR::SPAZ: jjSample(play.xPos, play.yPos, SOUND::SPAZSOUNDS_HAHAHA, 0, 0); break;
  1678.                         case CHAR::LORI: jjSample(play.xPos, play.yPos, SOUND::LORISOUNDS_LORIBOOM, 0, 0); break;
  1679.                         default: break;
  1680.                 }
  1681.         }
  1682.  
  1683.  
  1684.         void handleOnPlayer(jjPLAYER@ play) {
  1685.                 SPACESHIP@ ship = Ships[play.playerID];
  1686.                
  1687.                 if (jjKey[0x71]) {
  1688.                         if (!showInstructions) {
  1689.                                 if (!pressOnce[0]) {
  1690.                                         showInstructions = true;
  1691.                                         pressOnce[0] = true;
  1692.                                 }
  1693.                         } else {
  1694.                                 if (!pressOnce[0]) {
  1695.                                         showInstructions = false;
  1696.                                         pressOnce[0] = true;
  1697.                                 }
  1698.                         }
  1699.                 } else {
  1700.                         pressOnce[0] = false;
  1701.                 }
  1702.                 if (showInstructions) {
  1703.                         if (jjKey[0xBC]) {
  1704.                                 if (!pressOnce[1]) {
  1705.                                         if (currPage == 1) {
  1706.                                                 currPage = 3;
  1707.                                         } else {
  1708.                                                 currPage--;
  1709.                                         }
  1710.                                         pressOnce[1] = true;
  1711.                                 }
  1712.                         } else {
  1713.                                 pressOnce[1] = false;
  1714.                         }
  1715.                        
  1716.                         if (jjKey[0xBE]) {
  1717.                                 if (!pressOnce[2]) {
  1718.                                         if (currPage == 3) {
  1719.                                                 currPage = 1;
  1720.                                         } else {
  1721.                                                 currPage++;
  1722.                                         }
  1723.                                         pressOnce[2] = true;
  1724.                                 }
  1725.                         } else {
  1726.                                 pressOnce[2] = false;
  1727.                         }
  1728.                 }
  1729.                
  1730.                 if (ship.hasShip) {
  1731.                         play.spriteMode = SPRITE::INVISIBLE;
  1732.                         play.ballTime = 1;
  1733.                         play.direction = 1;
  1734.                         play.fly = FLIGHT::NONE;
  1735.                         play.jumpStrength = 0;
  1736.                         jjCharacters[play.charCurr].airJump = AIR::NONE;
  1737.                        
  1738.                         if (play.blink != 0) {
  1739.                                 ship.health = ship.SDPunishment? 1:maxHealth;
  1740.                         } else ship.SDPunishment = false;
  1741.                        
  1742.                         if (play.health == 0) {
  1743.                                 ship.health = ship.SDPunishment? 1:maxHealth;
  1744.                                 ship.armor = 0;
  1745.                         }
  1746.                        
  1747.                         if (ship.health > maxHealth && jjGameTicks % (ship.health > int(maxHealth*1.5) && ship.health < (maxHealth*2)? 28:70) == 0 && play.blink == 0 && jjGameState != GAME::STOPPED) {
  1748.                                 ship.health--;
  1749.                         }
  1750.                        
  1751.                         if (ship.armor < 0) ship.armor = 0;
  1752.                         if (ship.armor > maxHealth && jjGameTicks % (ship.armor > int(maxHealth*1.5) && ship.armor < (maxHealth*2)? 28:70) == 0 && play.blink == 0 && jjGameState != GAME::STOPPED) {
  1753.                                 ship.armor--;
  1754.                         }
  1755.                        
  1756.                         if (jjMaxHealth == 1) {
  1757.                                 ship.health = 1;
  1758.                                 ship.armor = 0;
  1759.                         }
  1760.                        
  1761.                         if (ship.health > (maxHealth*2)) {
  1762.                                 ship.health = (maxHealth*2);
  1763.                         }
  1764.                        
  1765.                         if (ship.armor > (maxHealth*2)) {
  1766.                                 ship.armor = (maxHealth*2);
  1767.                         }
  1768.                        
  1769.                         switch (play.currWeapon) {
  1770.                                 case WEAPON::BLASTER:
  1771.                                         if (currentWeapon == 1) play.fastfire = jjMaxHealth == 1? 45:14;
  1772.                                 break;
  1773.                                 case WEAPON::BOUNCER:
  1774.                                         if (currentWeapon == 2) play.fastfire = 6;
  1775.                                 break;
  1776.                                 case WEAPON::ICE:
  1777.                                         if (currentWeapon == 3) play.fastfire = 55;
  1778.                                 break;
  1779.                                 case WEAPON::SEEKER:
  1780.                                         if (currentWeapon == 4) play.fastfire = 70;
  1781.                                 break;
  1782.                                 case WEAPON::RF:
  1783.                                         if (currentWeapon == 5) play.fastfire = 110;
  1784.                                 break;
  1785.                                 case WEAPON::TOASTER:
  1786.                                         if (currentWeapon == 6) play.fastfire = 4;
  1787.                                 break;
  1788.                                 case WEAPON::TNT:
  1789.                                         if (currentWeapon == 7) play.fastfire = 70;
  1790.                                 break;
  1791.                                 case WEAPON::GUN8:
  1792.                                         if (currentWeapon == 8) play.fastfire = 35;
  1793.                                 break;
  1794.                                 case WEAPON::GUN9:
  1795.                                         if (currentWeapon == 9) play.fastfire = 12;
  1796.                                 break;
  1797.                                 default: break;
  1798.                         }
  1799.                        
  1800.                         while (play.ammo[currentWeapon] == 0 && play.currWeapon != WEAPON::BLASTER) {
  1801.                                 currentWeapon--;
  1802.                                 play.currWeapon = currentWeapon;
  1803.                         }
  1804.                        
  1805.                         if (ship.powerUp) {
  1806.                                 if (jjGameState != GAME::STOPPED) ship.powerTime--;
  1807.                                
  1808.                                 for (int i = 1; i <= 9; i++) {
  1809.                                         play.powerup[i] = true;
  1810.                                 }
  1811.                         } else {
  1812.                                 for (int i = 1; i <= 9; i++) {
  1813.                                         play.powerup[i] = false;
  1814.                                 }
  1815.                         }
  1816.                        
  1817.                         if (ship.powerTime <= 0 && ship.powerUp) {
  1818.                                 ship.powerTime = 0;
  1819.                                 ship.powerUp = false;
  1820.                                 if (play.isLocal) jjSample(play.xPos, play.yPos, SOUND::COMMON_SHLDOF3, 0, 0);
  1821.                         }
  1822.                        
  1823.                         play.xAcc = play.yAcc = 0;
  1824.                        
  1825.                         if (jjMaxHealth == 1) {
  1826.                                 for (int i = 2; i <= 9; i++) {
  1827.                                         play.ammo[i] = 0;
  1828.                                 }
  1829.                         }
  1830.                                
  1831.                         if (play.health > 0) {
  1832.                                 play.xSpeed = ship.xSpeed;
  1833.                                 play.ySpeed = ship.ySpeed;
  1834.                                 if (ship.ySpeed < 0.05 && ship.ySpeed > -0.05) {
  1835.                                         ship.ySpeed = 0;
  1836.                                 }
  1837.                                 if (ship.ySpeed == 0) {
  1838.                                         play.ySpeed = 0;
  1839.                                         play.yPos -= 0.125f;
  1840.                                 }
  1841.                                 if (ship.xSpeed < 0.05 && ship.xSpeed > -0.05) {
  1842.                                         ship.xSpeed = 0;
  1843.                                 }
  1844.                                 if (ship.xSpeed == 0) {
  1845.                                         play.xSpeed = 0;
  1846.                                         if (play.keyRight && !jjMaskedPixel(int(play.xPos-16), int(play.yPos))) play.xPos -= (play.keyRun? 0.368f : 0.183f);
  1847.                                         if (play.keyLeft && !jjMaskedPixel(int(play.xPos+16), int(play.yPos))) play.xPos += (play.keyRun? 0.368f : 0.183f);
  1848.                                 }
  1849.                         }
  1850.                        
  1851.                         if (jjGameTicks % 70 < 69) {
  1852.                                 if (ship.rotationSpeed != 0) {
  1853.                                         ship.rotating = true;
  1854.                                 }
  1855.                         }
  1856.                        
  1857.                         if (jjGameTicks % 70 == 69 && (ship.rotating || play.health == 0 || ship.wasHit)) {
  1858.                                 sendShipRotationPacket(ship);
  1859.                                 ship.rotating = false;
  1860.                                 ship.wasHit = false;
  1861.                         }
  1862.                        
  1863.                                
  1864.                         if (play.ySpeed > (play.keyRun? 8:6)) play.ySpeed = (play.keyRun? 8:6);
  1865.                        
  1866.                         if (play.ySpeed < -6 && !play.keyRun) play.ySpeed = -6;
  1867.                                
  1868.                         if (!ship.reverse) {
  1869.                                 if (ship.xAcc < 0) ship.xAcc = 0;
  1870.                                 if (ship.yAcc < 0) ship.yAcc = 0;
  1871.                         }
  1872.                        
  1873.                         if (ship.thrust && !ship.reverse) {
  1874.                                 if (!ship.justHit) {
  1875.                                         ship.xSpeed = (jjCos(ship.angle) * ship.xAcc) + ship.xMomentum;
  1876.                                         ship.ySpeed = (-jjSin(ship.angle) * ship.yAcc) + ship.yMomentum;
  1877.                                 }
  1878.                                        
  1879.                                 if (ship.xMomentum > 0) ship.xMomentum -= 0.05;
  1880.                                 if (ship.xMomentum < 0) ship.xMomentum += 0.05;
  1881.                                
  1882.                                 if (ship.yMomentum > 0) ship.yMomentum -= 0.05;
  1883.                                 if (ship.yMomentum < 0) ship.yMomentum += 0.05;
  1884.                                
  1885.                                 if (ship.xAcc < (play.keyRun? ship.maxSpeed:ship.maxTurningSpeed)) ship.xAcc += 0.2;
  1886.                                 if (ship.yAcc < (play.keyRun? ship.maxSpeed:ship.maxTurningSpeed)) ship.yAcc += 0.2;
  1887.                                        
  1888.                                 if (ship.rotationSpeed != 0) {
  1889.                                         if (ship.xAcc > (play.keyRun? ship.maxTurningSpeed:4)) ship.xAcc -= 0.25;
  1890.                                         if (ship.yAcc > (play.keyRun? ship.maxTurningSpeed:4)) ship.yAcc -= 0.25;
  1891.                                 }
  1892.                         } else {
  1893.                                 if (ship.reverse && !ship.thrust) {
  1894.                                         if (!ship.justHit) {
  1895.                                                 ship.xSpeed = (jjCos(ship.angle) * ship.xAcc) + ship.xMomentum;
  1896.                                                 ship.ySpeed = (-jjSin(ship.angle) * ship.yAcc) + ship.yMomentum;
  1897.                                         }
  1898.                                        
  1899.                                         if (ship.xMomentum > 0) ship.xMomentum -= 0.1;
  1900.                                         if (ship.xMomentum < 0) ship.xMomentum += 0.1;
  1901.                                        
  1902.                                         if (ship.yMomentum > 0) ship.yMomentum -= 0.1;
  1903.                                         if (ship.yMomentum < 0) ship.yMomentum += 0.1;
  1904.                                        
  1905.                                         if (ship.xAcc > (play.keyRun? -ship.maxSpeedRev:-ship.maxTurningSpeedRev)) ship.xAcc -= 0.085;
  1906.                                         if (ship.yAcc > (play.keyRun? -ship.maxSpeedRev:-ship.maxTurningSpeedRev)) ship.yAcc -= 0.085;
  1907.                                                
  1908.                                         if (ship.rotationSpeed != 0) {
  1909.                                                 if (ship.xAcc < (play.keyRun? -ship.maxTurningSpeedRev:-3)) ship.xAcc += 0.25;
  1910.                                                 if (ship.yAcc < (play.keyRun? -ship.maxTurningSpeedRev:-3)) ship.yAcc += 0.25;
  1911.                                         }
  1912.                                 } else {
  1913.                                         ship.xMomentum = play.xSpeed * 0.75;
  1914.                                         ship.yMomentum = play.ySpeed * 0.75;
  1915.                                        
  1916.                                         if (jjMaskedHLine(int(play.xPos + ship.xSpeed), -32, int(play.yPos)) || jjMaskedHLine(int(play.xPos - ship.xSpeed), 32, int(play.yPos))) {
  1917.                                                 ship.xSpeed = ship.xAcc = ship.xMomentum = 0;
  1918.                                         }
  1919.                                        
  1920.                                         if (jjMaskedVLine(int(play.xPos), int(play.yPos + ship.ySpeed), -32) || jjMaskedVLine(int(play.xPos), int(play.yPos - ship.ySpeed), 32)) {
  1921.                                                 ship.ySpeed = ship.yAcc = ship.yMomentum = 0;
  1922.                                         }
  1923.                                        
  1924.                                         if (ship.xMomentum > ship.maxSpeed) ship.xMomentum = ship.maxSpeed;
  1925.                                         if (ship.xMomentum < -ship.maxSpeed) ship.xMomentum = -ship.maxSpeed;
  1926.                                        
  1927.                                         if (ship.yMomentum > ship.maxSpeed) ship.yMomentum = ship.maxSpeed;
  1928.                                         if (ship.yMomentum < -ship.maxSpeed) ship.yMomentum = -ship.maxSpeed;
  1929.                                        
  1930.                                         if (ship.xSpeed > 0) ship.xSpeed -= 0.05;
  1931.                                         else if (ship.xSpeed < 0) ship.xSpeed += 0.05;
  1932.                                                  
  1933.                                         if (ship.ySpeed > 0) ship.xSpeed -= 0.05;
  1934.                                         else if (ship.ySpeed < 0) ship.ySpeed += 0.05;
  1935.                                        
  1936.                                         if (ship.xAcc > (ship.xSpeed * (ship.xSpeed > 0? -1:1))) {
  1937.                                                 ship.xAcc -= 0.25;
  1938.                                         }
  1939.                                         if (ship.yAcc > (ship.ySpeed * (ship.ySpeed > 0? -1:1))) {
  1940.                                                 ship.yAcc -= 0.25;
  1941.                                         }
  1942.                                                
  1943.                                         if (ship.ySpeed > 0 && ship.ySpeed < ship.maxSpeed && ship.yAcc <= 0 ) {
  1944.                                                 ship.ySpeed -= 0.025;
  1945.                                         }
  1946.                                         if (play.keyDown) {
  1947.                                                 ship.xAcc = ship.yAcc = 0;
  1948.                                         }
  1949.                                 }
  1950.                         }
  1951.                         play.buttstomp = 100;
  1952.                        
  1953.                         if (play.xSpeed > ship.maxSpeed) play.xSpeed = ship.maxSpeed;
  1954.                         if (play.xSpeed < -ship.maxSpeed) play.xSpeed = -ship.maxSpeed;
  1955.                         if (play.ySpeed > ship.maxSpeed) play.ySpeed = ship.maxSpeed;
  1956.                         if (play.ySpeed < -ship.maxSpeed) play.ySpeed = -ship.maxSpeed;
  1957.                        
  1958.                         if (play.xSpeed > ship.maxDiagonalSpeed && play.ySpeed > ship.maxDiagonalSpeed) {
  1959.                                 play.xSpeed = ship.maxDiagonalSpeed;
  1960.                                 play.ySpeed = ship.maxDiagonalSpeed;
  1961.                         }
  1962.                
  1963.                         if (play.xSpeed > ship.maxDiagonalSpeed && play.ySpeed < -ship.maxDiagonalSpeed) {
  1964.                                 play.xSpeed = ship.maxDiagonalSpeed;
  1965.                                 play.ySpeed = -ship.maxDiagonalSpeed;
  1966.                         }
  1967.                        
  1968.                         if (play.xSpeed < -ship.maxDiagonalSpeed && play.ySpeed > ship.maxDiagonalSpeed) {
  1969.                                 play.xSpeed = -ship.maxDiagonalSpeed;
  1970.                                 play.ySpeed = ship.maxDiagonalSpeed;
  1971.                         }
  1972.                        
  1973.                         if (play.xSpeed < -ship.maxDiagonalSpeed && play.ySpeed < -ship.maxDiagonalSpeed) {
  1974.                                 play.xSpeed = -ship.maxDiagonalSpeed;
  1975.                                 play.ySpeed = -ship.maxDiagonalSpeed;
  1976.                         }
  1977.                        
  1978.                         if (jjMaskedPixel(int(play.xPos) + int(ship.xSpeed), int(play.yPos) + int(ship.ySpeed)) && !ship.thrust) {
  1979.                                 ship.xAcc = ship.yAcc = ship.xMomentum = ship.yMomentum = 0;
  1980.                         }
  1981.                        
  1982.