Boomerang gun

Version:

1.0

Added on:

06 Feb 2013 15:29

Tags:

Description:
This is a script that changes the upgraded blaster into a boomerang gun. The behaviour of the boomerang (faster, higher, etc) can be changed by changing the constants.
/***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<bool> Returning(32, false);
array<float> 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;
  }
}