/* powerup.c - Powerup stuff for gradient wars

   No license - Use as you wish

   By James Stanley */

#include "powerup.h"

powerup_t *powerup_list;
powerup_t *last_powerup;

const int pwr_rad[POWERUPS] = { /* Hundred */ 12, /* Life */ 12, /* MG */ 12, /* Five MG */ 12, /* Nuke */ 12, /* Spiral */ 12 };

void new_powerup(fixed x, fixed y, int type, int ttl) {
  powerup_t *powerup;
  
  powerup = malloc(sizeof(powerup_t));
  powerup->x = x;
  powerup->y = y;
  powerup->type = type;
  powerup->ttl = ttl;
  powerup->ringrad = pwr_rad[type];
  powerup->next = NULL;
  
  if(powerup_list) {
    powerup->prev = last_powerup;
    last_powerup->next = powerup;
  } else {
    powerup->prev = NULL;
    powerup_list = powerup;
  }
  
  last_powerup = powerup;
}

void del_powerup(powerup_t *powerup) {
  if(powerup->next) {//If there's a next powerup, update it's prev pointer
    powerup->next->prev = powerup->prev;
  } else {//powerup == last_powerup
    last_powerup = powerup->prev;
    if(last_powerup) last_powerup->next = NULL;
  }
  
  if(powerup->prev) {
    powerup->prev->next = powerup->next;
  } else {//powerup == powerup_list
    powerup_list = powerup->next;
    if(powerup_list) powerup_list->prev = NULL;
  }
  
  free(powerup);
}

void draw_powerups(BITMAP *canvas) {
  powerup_t *powerup;
  int x, y;
  
  for(powerup = powerup_list; powerup; powerup = powerup->next) {
    x = fixtoi(powerup->x);
    y = fixtoi(powerup->y);
    if((x > (-offsetx)) && (x < ((-offsetx)+SCR_WIDTH))) {
      if((y > (-offsety)) && (y < ((-offsety)+SCR_HEIGHT))) {
        draw_sprite(canvas, powerup_img[powerup->type], offsetx+(x-pwr_rad[powerup->type]), offsety+(y-pwr_rad[powerup->type]));
        circle(canvas, offsetx+x, offsety+y, powerup->ringrad, makecol(255-powerup->ttl, powerup->ttl, powerup->ttl));
      }
    }
  }
}

void update_powerups(void) {
  powerup_t *powerup = powerup_list;
  powerup_t *powerup_next;
  int xdiff, ydiff, dist;
  
  while(powerup) {
    powerup_next = powerup->next;
    
    if(powerup->ttl % 2) {//Run this code every other loop
      powerup->ringrad++;
      if(powerup->ringrad > (pwr_rad[powerup->type]*2)) powerup->ringrad = pwr_rad[powerup->type];
    }
    
    //Check for collision with player
    xdiff = fixtoi(px - powerup->x);
    ydiff = fixtoi(py - powerup->y);
    dist = (xdiff * xdiff) + (ydiff * ydiff);
    if(dist < (pwr_rad[powerup->type]+12)*(pwr_rad[powerup->type]+12)) {//Collision - pwr_rad[powerup->type] for enemy, 12 for player, squared because we're cheatin' on pythagoras
      play_sample(power, 255, 127, 1000, 0);
      switch(powerup->type) {
        case HUNDRED:
          pscore += 100;
          display_text("100", fixtoi(powerup->x), fixtoi(powerup->y));
          break;
        case LIFE:
          plives++;
          display_text("EXTRA LIFE", fixtoi(powerup->x), fixtoi(powerup->y));
          break;
        case MG:
          if(pweapon != MG) {
            pweptime = 0;
            pweapon = MG;
          }
          pweptime += 200;
          display_text("MG", fixtoi(powerup->x), fixtoi(powerup->y));
          break;
        case FIVE_MG:
          if(pweapon != FIVE_MG) {
            pweptime = 0;
            pweapon = FIVE_MG;
          }
          pweptime += 100;//Fires at half the speed of MG so you only get half the time
          display_text("5-WAY MG", fixtoi(powerup->x), fixtoi(powerup->y));
          break;
        case NUKE:
          if(pweapon != NUKE) {
            pweptime = 0;
            pweapon = NUKE;
          }
          pweptime += 3;
          display_text("NUKE", fixtoi(powerup->x), fixtoi(powerup->y));
          break;
        case SPIRAL:
          if(pweapon != SPIRAL) {
            pweptime = 0;
            pweapon = SPIRAL;
          }
          pweptime += 200;
          display_text("SPIRAL MG", fixtoi(powerup->x), fixtoi(powerup->y));
          break;
      }
      del_powerup(powerup);//Powerup was used by the player
      powerup = NULL;
    }
    
    if(powerup) {//Not picked up yet
      powerup->ttl--;
      if(powerup->ttl < 0) {
        del_powerup(powerup);
        powerup = NULL;
      }
    }
    
    powerup = powerup_next;
  }
}

void spawn_powerup(int points) {
  if(points < uplevels[0]) new_powerup(itofix(rand()%WIDTH), itofix(rand()%HEIGHT), HUNDRED, 250);
  else if(points < uplevels[1]) {
    if(rand()%8) {// != 0
      spawn_powerup(levels[0]-1);
    } else {
      new_powerup(itofix(rand()%WIDTH), itofix(rand()%HEIGHT), LIFE, 200);
    }
  } else if(points < uplevels[2]) {
    if(rand()%4) {// != 0
      spawn_powerup(levels[1]-1);
    } else {
      new_powerup(itofix(rand()%WIDTH), itofix(rand()%HEIGHT), MG, 200);
    }
  } else if(points < uplevels[3]) {
    if(rand()%6) {// != 0
      spawn_powerup(levels[2]-1);
    } else {
      new_powerup(itofix(rand()%WIDTH), itofix(rand()%HEIGHT), FIVE_MG, 200);
    }
  } else if(points < uplevels[4]) {
    if(rand()%6) {// != 0
      spawn_powerup(levels[3]-1);
    } else {
      new_powerup(itofix(rand()%WIDTH), itofix(rand()%HEIGHT), NUKE, 150);
    }
  } else {
    if(rand()%10) {// != 0
      spawn_powerup(levels[4]-1);
    } else {
      new_powerup(itofix(rand()%WIDTH), itofix(rand()%HEIGHT), SPIRAL, 150);
    }
  }
}

void kill_powerups(void) {
  powerup_t *powerup;
  
  while(powerup_list) {
    powerup = powerup_list->next;
    free(powerup_list);
    powerup_list = powerup;
  }
  
  last_powerup = NULL;
}
