Boomerang gun

Version:

3.0

Added on:

26 Feb 2013 16:41

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.

EDIT: Modified the script to be way more efficiƫnt.
/***Constants***/
const float cMaxSpeed = 10; //The maximum speed the boomerang can have
const float cAcceleration = 0.2; //The acceleration of the boomerang
const float cReturnAccMult = 1; //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 cVerSpdMult = 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.4; //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<bool> boomerangfired(32, false);
array<float> speed(32, cMaxSpeed);

/***Math functions***/
//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;
}

/***Other functions***/
void BoomerangGun(int boomerangID) {
  int playerID = jjObjects[boomerangID].creator - 32768;

  if ((abs(jjObjects[boomerangID].xSpeed) < cReturnSpeed && jjObjects[boomerangID].direction != 0) || (abs(jjObjects[boomerangID].ySpeed) < cReturnSpeed && jjObjects[boomerangID].direction == 0) && !returning[playerID])
    returning[playerID] = true;

  if (jjObjects[boomerangID].counter == 1) {
    if (playerID == p.playerID)
      p.noFire = true;
    jjObjects[boomerangID].determineCurAnim(ANIM::TUFBOSS, 3);
    jjObjects[boomerangID].counterEnd = 254;
  }

  if (returning[playerID]) {
    if (distance(jjPlayers[playerID].xPos, jjPlayers[playerID].yPos, jjObjects[boomerangID].xPos, jjObjects[boomerangID].yPos) < cReturnRadius)
      jjKillObject(boomerangID);
    
    if (speed[playerID] < cMaxSpeed)
      speed[playerID] = speed[playerID] + cAcceleration*cReturnAccMult;

    jjObjects[boomerangID].ySpeed = speed[playerID]*(jjPlayers[playerID].yPos - jjObjects[boomerangID].yPos)/distance(jjPlayers[playerID].xPos, jjPlayers[playerID].yPos, jjObjects[boomerangID].xPos, jjObjects[boomerangID].yPos);
    jjObjects[boomerangID].xSpeed = speed[playerID]*(jjPlayers[playerID].xPos - jjObjects[boomerangID].xPos)/distance(jjPlayers[playerID].xPos, jjPlayers[playerID].yPos, jjObjects[boomerangID].xPos, jjObjects[boomerangID].yPos);
  } else {
    if (speed[playerID] > 0)
      speed[playerID] = speed[playerID] - cAcceleration;
    if (jjObjects[boomerangID].direction == 0)
      jjObjects[boomerangID].ySpeed = -speed[playerID]*cVerSpdMult;
    else
      jjObjects[boomerangID].xSpeed = speed[playerID]*jjObjects[boomerangID].direction;
  }

  if (jjObjects[boomerangID].counter > 200)
    jjObjects[boomerangID].counter = 30;
}

/***Gameplay functions***/
void onMain() {
  for (int i = 0;  i < jjObjectCount; i++)
    if (jjObjects[i].isActive && jjObjects[i].creatorType == CREATOR::PLAYER) {
      //Maintain boomerang gun
      if (jjObjects[i].eventID == OBJECT::BLASTERBULLETPU) {
        BoomerangGun(i);
        jjObjects[i].animSpeed = 3;
        boomerangfired[jjObjects[i].creator - 32768] = true;
        continue;
      }
    }
    
  for (int i = 0; i < 32; i++)
    if (!boomerangfired[i]) {
      speed[i] = cMaxSpeed;
      returning[i] = false;
      if (i == p.playerID)
        p.noFire = false;
    } else boomerangfired[i] = false;
}