/* Boomerang gun 1.0, by Foly http://www.jazz2online.com/snippets/50/boomerang-gun/ */ /***Constants***/ const float cMaxSpeed = 10; //The maximum speed the boomerang can have const float cAcceleration = 0.1; //The acceleration of the boomerang const float cReturnAccMult = 2; //When the boomerang is returning, this is a multiplier for the acceleration (so a value of 2 let's the boomerang return with 2x acceleration) const float cVerAccMult = 0.7; //When the boomerang is shot vertical and not returning, this is a multiplier for the acceleration (a higher value lets the boomerang go faster and higher upward) const float cReturnSpeed = 0.2; //At what speed the boomerang returns back to the player (WARNING! This constant should always be higher than cAcceleration) const float cReturnRadius = 32; //Radius in pixels at which the player takes the boomerang back /***Variables***/ array Returning(32, false); array Speed(32, cMaxSpeed); /***Script only functions***/ int FindBulletID(int playerID, int BulletType) { int BulletID = -1; for (int i = 1; i < jjObjectCount; i++) { if (jjObjects[i].isActive && (jjObjects[i].eventID == BulletType) && (jjObjects[i].creatorType == CREATOR::PLAYER) && ((jjObjects[i].creator - 32768) == playerID)) { BulletID = i; break; } } return BulletID; } //Calculates the distance between two points float Distance(float x1, float y1, float x2, float y2) { return sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)); } //The square root function float sqrt(float x) { float y = 1.0; for (int i = 0; i < 20; i++) y = (y + x/y)/2; return y; } //Determines the absolute value float abs(float x) { if (x < 0) x = -x; return x; } //Determines the sign int sign(int x) { int y; if (x < 0) y = -1; else y = 1; return y; } /***Gameplay functions***/ void onLevelLoad() { jjObjectPresets[OBJECT::BLASTERBULLETPU].determineCurAnim(ANIM::TUFBOSS, 3); jjObjectPresets[OBJECT::BLASTERBULLETPU].counterEnd = 254; } void onMain() { int BlasterID, ElectroID; float Slope; for (int i = 0; i < 32; i++) { /*Boomerang gun*/ BlasterID = FindBulletID(i, OBJECT::BLASTERBULLETPU); if (BlasterID != -1) { if ((abs(jjObjects[BlasterID].xSpeed) < cReturnSpeed && jjObjects[BlasterID].direction != 0) || (abs(jjObjects[BlasterID].ySpeed) < cReturnSpeed && jjObjects[BlasterID].direction == 0) && !Returning[i]) Returning[i] = true; if (jjObjects[BlasterID].counter == 1) jjObjects[BlasterID].determineCurAnim(ANIM::TUFBOSS, 3); if (Returning[i]) { if (Distance(jjPlayers[i].xPos, jjPlayers[i].yPos, jjObjects[BlasterID].xPos, jjObjects[BlasterID].yPos) < cReturnRadius) jjKillObject(BlasterID); if (Speed[i] < cMaxSpeed) Speed[i] = Speed[i] + cAcceleration*2; if (jjPlayers[i].xPos == jjObjects[BlasterID].xPos) Slope = 100000; else Slope = (jjPlayers[i].yPos - jjObjects[BlasterID].yPos)/(jjPlayers[i].xPos - jjObjects[BlasterID].xPos); jjObjects[BlasterID].ySpeed = Speed[i]*sign(jjPlayers[i].yPos - jjObjects[BlasterID].yPos)/sqrt(1 + 1/(Slope*Slope)); jjObjects[BlasterID].xSpeed = Speed[i]*sign(jjPlayers[i].xPos - jjObjects[BlasterID].xPos)/sqrt(1 + Slope*Slope); } else { if (Speed[i] > 0) Speed[i] = Speed[i] - cAcceleration*cReturnAccMult; if (jjObjects[BlasterID].direction == 0) jjObjects[BlasterID].ySpeed = -Speed[i]*cVerAccMult; else jjObjects[BlasterID].xSpeed = Speed[i]*jjObjects[BlasterID].direction; } if (jjObjects[BlasterID].counter > 200) jjObjects[BlasterID].counter = 30; } else { Speed[i] = cMaxSpeed; Returning[i] = false; if (i == p.playerID) p.noFire = false; } //Both guns only work with one shot, therefore they player shouldn't be able to shoot when he has shot already if ((i == p.playerID) && BlasterID != -1) p.noFire = true; } }