#include_function ".\CommonFunctions.dnh"
#include_function ".\CommonDataHelpers.dnh"

let CameraX = GetCenterX;
let CameraY = GetCenterY;
let CameraCharge = 50;
let CameraChargeAccel = 0.08;
  
let Charging = false;

let CameraLayer = 4;

let CameraReady = false;
let CameraZoom = false;
let CameraUsed = false;
let CameraShow = true;

let Pictures = [];
let Frames = [];
let Scores = [];
let CurrentPicture = 0;

let SceneBestPictureScore = -1;
let WasSuccessful = false;

let imgCrosshair = GCD ~ "img\crosshair.png";
let imgPercent = GCD ~ "img\percent.png";
let imgText = GCD ~ "img\text.png";
let imgCircle1 = GCD ~ "img\circle1.png";
let imgCircle2 = GCD ~ "img\circle2.png";
let imgEdge = GCD ~ "img\edge.png";
let imgPhotoBG1 = GCD ~ "img\photobg1.png";
let imgPhotoBG2 = GCD ~ "img\photobg2.png";
let imgWhite = GCD ~ "img\white.png";

task CreatePictures {
  yield;
  loop(11){
    let obj = ObjEffect_InitializeRect(imgWhite, 8);
    ObjEffect_SetUVRect(obj, 0, 0, 16, 16);
    Frames = Frames ~ [obj];
  
    obj = ObjEffect_InitializeRect("", 8);
    Pictures = Pictures ~ [obj];
    
    obj = Obj_Create(OBJ_EFFECT);
    ObjEffect_SetTexture(obj, imgText);
    ObjEffect_SetLayer(obj, 8);
    ObjEffect_SetPrimitiveType(obj, PRIMITIVE_TRIANGLESTRIP);
    ObjEffect_CreateVertex(obj, 3);
    Scores = Scores ~ [obj];
  }
}

task TakePicture(left, top, right, bottom, flash, willdelete){
  WasSuccessful = IsPointInRectangle(GetEnemyX, GetEnemyY, left, top, right, bottom) && willdelete;
  CameraShow = false;
  DrawOverlayEffect;
  yield;
  
  let imgSnapShot = GetCurrentScriptDirectory ~ "img\snapshot\temp" ~ IntString(CurrentPicture) ~ ".bmp";
  loop(10){
    SaveSnapShot(imgSnapShot, left, top, right, bottom);
  }
  
  CameraShow = true;
  yield;
  if(willdelete){SetCameraDeleteArea(left, top, right, bottom);}
  
  DrawPicture;
  if(flash){DrawFlashEffect;}
  
  yield;
  SetCameraDeleteArea(-1, -1, -1, -1);


  task DrawPicture {
    LoadGraphic(imgSnapShot);
    let width = right-left;
    let height = bottom-top;
    
    let frame = Frames[CurrentPicture];
    ObjEffect_SetXYRect(frame, width/2*-1.05, height/2*-1.05, width/2*1.05, height/2*1.05);
    ObjEffect_SetColor(frame, 4, 0, 255, 255, 255);
    Obj_SetPosition(frame, CameraX, CameraY);
    
    let picture = Pictures[CurrentPicture];
    ObjEffect_SetTexture(picture, imgSnapShot);
    ObjEffect_SetUVRect(picture, 0, 0, width, height);
    ObjEffect_SetXYRect(picture, width/2*-1, height/2*-1, width/2, height/2);
    ObjEffect_SetColor(picture, 4, 0, 255, 255, 255);
    Obj_SetPosition(picture, CameraX, CameraY);
    
    Wait(20);
    if(WasSuccessful && CurrentPicture < 10){
      let destX = GetClipMaxX+56+floor(CurrentPicture/5)*112;
      let destY = 420 - 90*(CurrentPicture%5);
      let dist = Distance(Obj_GetX(frame), Obj_GetY(frame), destX, destY);
      let angle = AngleFrom(Obj_GetX(frame), Obj_GetY(frame), destX, destY);
      let incr = dist/30;
      
      let picscore = GetPictureScore;
      let bestshot = false;
      if(picscore > SceneBestPictureScore){
        SceneBestPictureScore = picscore;
        bestshot = true;
      }
      let score = Scores[CurrentPicture];
      SetVertexForScore(score, picscore);
      Obj_SetPosition(score, destX+50, destY+20);
      if(bestshot){
        ObjEffect_SetColor(score, 60, 255, 255, 255, 128);
      }
      
      CurrentPicture++;
      SetCurrentPicture(CurrentPicture);
      ObjEffect_SetColor(frame, 4, 255, 255, 255, 255);
      ObjEffect_SetColor(picture, 4, 255, 255, 255, 255);
      descent(i in 0..30){
        Obj_SetPosition(frame, Obj_GetX(frame)+cos(angle)*incr, Obj_GetY(frame)+sin(angle)*incr);
        ObjEffect_SetAngle(frame, 0, 0, i*-12);
        ObjEffect_SetScale(frame, 0.4+i/30*0.6, 0.4+i/30*0.6);
        
        Obj_SetPosition(picture, Obj_GetX(picture)+cos(angle)*incr, Obj_GetY(picture)+sin(angle)*incr);
        ObjEffect_SetAngle(picture, 0, 0, i*-12);
        ObjEffect_SetScale(picture, 0.4+i/30*0.6, 0.4+i/30*0.6);
        yield;
      }
      let random = rand(-5, 5);
      Obj_SetPosition(frame, destX, destY);
      ObjEffect_SetAngle(frame, 0, 0, random);
      ObjEffect_SetScale(frame, 0.4, 0.4);
      
      Obj_SetPosition(picture, destX, destY);
      ObjEffect_SetAngle(picture, 0, 0, random);
      ObjEffect_SetScale(picture, 0.4, 0.4);
      while(GetPlayerEnabled){
        if(picscore < SceneBestPictureScore){
          bestshot = false;
        }
        if(!bestshot){
          ObjEffect_SetColor(score, 60, 255, 255, 255, 255);
        }
        yield;
      }
      ObjEffect_ResizeVertexCount(score, 3);
      Obj_SetPosition(score, -500, -500);
    }
    else {
      descent(i in 0..30){
        Obj_SetPosition(frame, Obj_GetX(frame)-1, Obj_GetY(frame)+5);
        ObjEffect_SetAngle(frame, 0, 0, i*12);
        ObjEffect_SetScale(frame, 0.2+i/30*0.8, 0.2+i/30*0.8);
        ObjEffect_SetColor(frame, 4, i*255/30, 255, 255, 255);
        
        Obj_SetPosition(picture, Obj_GetX(picture)-1, Obj_GetY(picture)+5);
        ObjEffect_SetAngle(picture, 0, 0, i*12);
        ObjEffect_SetScale(picture, 0.2+i/30*0.8, 0.2+i/30*0.8);
        ObjEffect_SetColor(picture, 4, i*255/30, 255, 255, 255);
        yield;
      }
    }
    DeleteGraphic(imgSnapShot);
    
    ObjEffect_SetTexture(picture, "");
    ObjEffect_SetScale(picture, 1, 1);
    ObjEffect_SetAngle(picture, 0, 0, 0);
    Obj_SetPosition(picture, 0, 0);
    
    ObjEffect_SetScale(frame, 1, 1);
    ObjEffect_SetAngle(frame, 0, 0, 0);
    ObjEffect_SetColor(frame, 4, 0, 255, 255, 255);
    Obj_SetPosition(frame, 0, 0);
    
    function SetVertexForScore(obj, score){
      let string = IntString(score);
      let digits = [];
      ascent(i in 0..length(string)){
        digits = digits ~ [CharToInteger(string[i])];
      }
      
      ObjEffect_ResizeVertexCount(obj, length(digits)*6);
      ascent(i in 0..length(digits)){
        let minx = (i*9)-(length(digits)*9);
        ObjEffect_SetVertexXY(obj, i*6  , minx,    0);
        ObjEffect_SetVertexXY(obj, i*6+1, minx,    0);
        ObjEffect_SetVertexXY(obj, i*6+2, minx+12, 0);
        ObjEffect_SetVertexXY(obj, i*6+3, minx,    12);
        ObjEffect_SetVertexXY(obj, i*6+4, minx+12, 12);
        ObjEffect_SetVertexXY(obj, i*6+5, minx+12, 12);
        if(digits[i] <= 9){
          ObjEffect_SetVertexUV(obj, i*6,   digits[i]*12   , 0);
          ObjEffect_SetVertexUV(obj, i*6+1, digits[i]*12   , 0);
          ObjEffect_SetVertexUV(obj, i*6+2, digits[i]*12+12, 0);
          ObjEffect_SetVertexUV(obj, i*6+3, digits[i]*12   , 12);
          ObjEffect_SetVertexUV(obj, i*6+4, digits[i]*12+12, 12);
          ObjEffect_SetVertexUV(obj, i*6+5, digits[i]*12+12, 12);
        }
        else {
          ObjEffect_SetVertexUV(obj, i*6,   116, 188);
          ObjEffect_SetVertexUV(obj, i*6+1, 116, 188);
          ObjEffect_SetVertexUV(obj, i*6+2, 128, 188);
          ObjEffect_SetVertexUV(obj, i*6+3, 116, 200);
          ObjEffect_SetVertexUV(obj, i*6+4, 128, 200);
          ObjEffect_SetVertexUV(obj, i*6+5, 128, 200);
        }
      }
      
      function CharToInteger(char){
        alternative(char)
        case('0'){ return 0; }
        case('1'){ return 1; }
        case('2'){ return 2; }
        case('3'){ return 3; }
        case('4'){ return 4; }
        case('5'){ return 5; }
        case('6'){ return 6; }
        case('7'){ return 7; }
        case('8'){ return 8; }
        case('9'){ return 9; }
        others { return -1; }
      }
    }
  }
  
  task DrawOverlayEffect {
    let overlay = ObjEffect_InitializeRect(imgWhite, 1);
    ObjEffect_SetUVRect(overlay, 0, 0, 16, 16);
    ObjEffect_SetXYRect(overlay, GetClipMinX, GetClipMinY, GetClipMaxX, GetClipMaxY);
    ObjEffect_SetRenderState(overlay, ADD);
    ObjEffect_SetColor(overlay, 4, 255, 1, 1, 1);
    Wait(3);
    Obj_Delete(overlay);
  }
  
  task DrawFlashEffect {
    let flash = ObjEffect_InitializeRect(imgWhite, 7);
    ObjEffect_SetUVRect(flash, 96, 224, 128, 256);
    ObjEffect_SetXYRect(flash, GetClipMinX, GetClipMinY, GetClipMaxX, GetClipMaxY);
    ascent(i in 0..4){
      ObjEffect_SetColor(flash, 4, i*81, 255, 255, 255);
      yield;
    }
    descent(i in 0..4){
      ObjEffect_SetColor(flash, 4, i*81, 255, 255, 255);
      yield;
    }
    Obj_Delete(flash);
  }
}

task ZoomMode {
  let xSize = 108+CameraCharge*1.48;
  let ySize = 81+CameraCharge*1.11;
  CameraZoom = true;
  SetGameSpeed(1);
  
  DrawZoomEffects;
  
  let counter = 0;
  while(CameraCharge > 0){
    if(OnMissed){
      break;
    }
    if(GetKeyState(VK_SHOT)!=KEY_HOLD && GetKeyState(VK_SHOT)!=KEY_PUSH){
      break;
    }
    if(counter > 20){ CameraCharge-=2; }
    xSize = 108+CameraCharge*1.48;
    ySize = 81+CameraCharge*1.11;
    counter++;
    yield;
  }
  
  CameraUsed = true;
  CameraZoom = false;
  
  if(!OnMissed){
    SetGameSpeed(-1);
    let left = CameraX-xSize/2;
    let top = CameraY-ySize/2;
    let right = CameraX+xSize/2;
    let bottom = CameraY+ySize/2;
    if(left < GetClipMinX){ left = GetClipMinX; }
    if(top < GetClipMinY){ top = GetClipMinY; }
    if(right > GetClipMaxX){ right = GetClipMaxX; }
    if(bottom > GetClipMaxY){ bottom = GetClipMaxY; }
    if(CameraCharge > 0){
      CameraCharge = 0;
      TakePicture(left, top, right, bottom, true, true);
    }
    else {
      CameraCharge = 50;
      TakePicture(left, top, right, bottom, false, false);
    }
    Wait(60);
    SetGameSpeed(0);
    Wait(60);
    CameraReady = false;
    CameraUsed = false;
  }
  
  sub DrawZoomEffects {
    DrawZoomCircleEffect;
    DrawZoomEdgesEffect;
    DrawZoomBackdropEffect;
    
    task DrawZoomCircleEffect {
      let circle = ObjEffect_InitializeRect(imgCircle2, CameraLayer);
      ObjEffect_SetUVRect(circle, 0, 0, 128, 128);
      ObjEffect_SetXYRect(circle, -64, -64, 64, 64);
      ObjEffect_SetColor(circle, 4, 200, 255, 255, 255);
      
      let counter = 0;
      while(CameraZoom || OnMissed){
        Obj_SetPosition(circle, CameraX, CameraY);
        ObjEffect_SetScale(circle, CameraCharge/50, CameraCharge/50);
        if(IsPointInRectangle(GetEnemyX, GetEnemyY, CameraX-xSize/2, CameraY-ySize/2, CameraX+xSize/2, CameraY+ySize/2)){
          ObjEffect_SetColor(circle, 4, 200, 255, 128, 128);
        }
        else {
          ObjEffect_SetColor(circle, 4, 128, 255, 255, 255);
        }
        counter++;
        yield;
      }
      Obj_Delete(circle);
    }
    
    task DrawZoomEdgesEffect {
      let edges = [];
      ascent(i in 0..4){
        let obj = ObjEffect_InitializeRect(imgEdge, CameraLayer);
        ObjEffect_SetUVRect(obj, 0, 0, 64, 32);
        ObjEffect_SetXYRect(obj, 0, -32, 64, 0);
        ObjEffect_SetColor(obj, 4, 200, 255, 255, 255);
        edges = edges ~ [obj];
      }
      ObjEffect_SetAngle(edges[0], 180, 0, 0);
      ObjEffect_SetAngle(edges[1], 180, 180, 0);
      ObjEffect_SetAngle(edges[2], 0, 0, 0);
      ObjEffect_SetAngle(edges[3], 0, 180, 0);
      
      let counter = 0;
      while(CameraZoom || OnMissed){
        Obj_SetPosition(edges[0], CameraX-xSize/2, CameraY-ySize/2);
        Obj_SetPosition(edges[1], CameraX+xSize/2, CameraY-ySize/2);
        Obj_SetPosition(edges[2], CameraX-xSize/2, CameraY+ySize/2);
        Obj_SetPosition(edges[3], CameraX+xSize/2, CameraY+ySize/2);
        if(IsPointInRectangle(GetEnemyX, GetEnemyY, CameraX-xSize/2, CameraY-ySize/2, CameraX+xSize/2, CameraY+ySize/2)){
          ascent(i in 0..4){ ObjEffect_SetColor(edges[i], 4, 200, 255, 128, 128); }
        }
        else {
          ascent(i in 0..4){ ObjEffect_SetColor(edges[i], 4, 200, 255, 255, 255); }
        }
        counter++;
        yield;
      }
      ascent(i in 0..4){
        Obj_Delete(edges[i]);
      }
    }
    
    task DrawZoomBackdropEffect {
      let backdrop1 = [];
      loop(4){
        let obj = ObjEffect_InitializeRect(imgPhotoBG1, 1);
        ObjEffect_SetColor(obj, 4, 200, 255, 255, 255);
        backdrop1 = backdrop1 ~ [obj];
      }
      
      let backdrop2 = [];
      loop(4){
        let obj1 = ObjEffect_InitializeRect(imgPhotoBG2, 1);
        let obj2 = ObjEffect_InitializeRect(imgPhotoBG2, 1);
        backdrop2 = backdrop2 ~ [[obj1, obj2]];
      }
      
      let counter = 0;
      while(CameraZoom){
        let x1 = GetClipMinX;
        let x2 = CameraX-xSize/2;
        let x3 = CameraX+xSize/2;
        let x4 = GetClipMaxX;
        let y1 = GetClipMinY;
        let y2 = CameraY-ySize/2;
        let y3 = CameraY+ySize/2;
        let y4 = GetClipMaxY;
        ObjEffect_SetXYRect(backdrop1[0], x1, y1, x2, y4);
        ObjEffect_SetXYRect(backdrop1[1], x2, y1, x3, y2);
        ObjEffect_SetXYRect(backdrop1[2], x2, y3, x3, y4);
        ObjEffect_SetXYRect(backdrop1[3], x3, y1, x4, y4);
        ascent(i in 0..2){
          ObjEffect_SetXYRect(backdrop2[0][i], x1, y1, x2, y4);
          ObjEffect_SetXYRect(backdrop2[1][i], x2, y1, x3, y2);
          ObjEffect_SetXYRect(backdrop2[2][i], x2, y3, x3, y4);
          ObjEffect_SetXYRect(backdrop2[3][i], x3, y1, x4, y4);
        }
        
        x1 = 0;
        x2 = (CameraX-xSize/2) - GetClipMinX;
        x3 = (CameraX+xSize/2) - GetClipMinX;
        x4 = GetClipMaxX - GetClipMinX;
        y1 = 0;
        y2 = (CameraY-ySize/2) - GetClipMinY;
        y3 = (CameraY+ySize/2) - GetClipMinY;
        y4 = GetClipMaxY - GetClipMinY;
        ObjEffect_SetUVRect(backdrop1[0], x1, y1, x2, y4);
        ObjEffect_SetUVRect(backdrop1[1], x2, y1, x3, y2);
        ObjEffect_SetUVRect(backdrop1[2], x2, y3, x3, y4);
        ObjEffect_SetUVRect(backdrop1[3], x3, y1, x4, y4);
        
        let randomY = rand(0, 256);
        ObjEffect_SetUVRect(backdrop2[0][0], counter+x1, y1+randomY, counter+x2, y4+randomY);
        ObjEffect_SetUVRect(backdrop2[1][0], counter+x2, y1+randomY, counter+x3, y2+randomY);
        ObjEffect_SetUVRect(backdrop2[2][0], counter+x2, y3+randomY, counter+x3, y4+randomY);
        ObjEffect_SetUVRect(backdrop2[3][0], counter+x3, y1+randomY, counter+x4, y4+randomY);
        ObjEffect_SetUVRect(backdrop2[0][1], -1*counter+x1, y1+randomY, -1*counter+x2, y4+randomY);
        ObjEffect_SetUVRect(backdrop2[1][1], -1*counter+x2, y1+randomY, -1*counter+x3, y2+randomY);
        ObjEffect_SetUVRect(backdrop2[2][1], -1*counter+x2, y3+randomY, -1*counter+x3, y4+randomY);
        ObjEffect_SetUVRect(backdrop2[3][1], -1*counter+x3, y1+randomY, -1*counter+x4, y4+randomY);
        counter++;
        yield;
      }
      ascent(i in 0..4){
        Obj_Delete(backdrop1[i]);
        Obj_Delete(backdrop2[i][0]);
        Obj_Delete(backdrop2[i][1]);
      }
    }
  }
}

task CreateCamera {
  yield;
  
  DrawCameraCrosshairEffect;
  DrawCameraCircleEffect;
  DrawCameraPercentageEffect;
  DrawCameraIndicatorEffect;
  ControlCharge;
  
  let angle = -90;
  let dist = 64;
  loop {
    if(CameraZoom && !CameraUsed){
      if(GetPlayerMoveAngle != NULL){
        CameraX += cos(GetPlayerMoveAngle)*2.25;
        CameraY += sin(GetPlayerMoveAngle)*2.25;
      }
    }
    else if(!CameraUsed) {
      if(GetKeyState(VK_SLOWMOVE)==KEY_HOLD){
        angle = AngleFromPlayer(GetEnemyX, GetEnemyY);
        if(GetKeyState(VK_SHOT)==KEY_FREE){
          if(dist > DistanceFromPlayer(GetEnemyX, GetEnemyY)){
            dist = DistanceFromPlayer(GetEnemyX, GetEnemyY);
          }
          else {
            dist++;
            if(dist > 80){
              dist = 80;
            }
          }
        }
        else if(Charging){
          dist = 0;
        }
        else {
          dist--;
          if(dist < 48){
            dist = 48;
          }
        }
      }
      else {
        dist--;
        if(dist < 48){
          dist = 48;
        }
        if(xDisplacement == 0 && yDisplacement == 0){
          let angdist = AngularDistance(angle, AngleFromPlayer(GetEnemyX, GetEnemyY));
          if(absolute(angdist) < 1){
            angle = AngleFromPlayer(GetEnemyX, GetEnemyY);
          }
          else {
            if(absolute(angdist/25) > 1){
              angle += angdist/25;
            }
            else {
              angle += angdist/absolute(angdist);
            }
          }
        }
        else {
          let angdist = AngularDistance(angle, atan2(yDisplacement, xDisplacement));
          if(absolute(angdist) < 5){
            angle = atan2(yDisplacement, xDisplacement)
          }
          else {
            if(absolute(angdist/25) > 1){
              angle += angdist/25;
            }
            else {
              angle += angdist/absolute(angdist);
            }
          }
        }
      }
      let targetdist = dist;
      let targetX = GetPlayerX+cos(angle)*targetdist;
      let targetY = GetPlayerY+sin(angle)*targetdist;
      while(targetX > GetClipMinX && targetX < GetClipMaxX && targetY > GetClipMinY && targetY < GetClipMaxY && targetdist < dist){
        targetdist++;
        targetX = GetPlayerX+cos(angle)*targetdist;
        targetY = GetPlayerY+sin(angle)*targetdist;
      }
      while(targetX < GetClipMinX || targetX > GetClipMaxX || targetY < GetClipMinY || targetY > GetClipMaxY){
        targetdist--;
        targetX = GetPlayerX+cos(angle)*targetdist;
        targetY = GetPlayerY+sin(angle)*targetdist;
      }
      CameraX = (targetX+CameraX*2)/3;
      CameraY = (targetY+CameraY*2)/3;
    }
    yield;
  }
  
  task DrawCameraIndicatorEffect {
    let indicator = ObjEffect_InitializeRect(imgText, CameraLayer);
    ObjEffect_SetXYRect(indicator, -20, -6, 20, 6);
    
    loop {
      let counter = 0;
      while(!CameraReady){
        ObjEffect_SetColor(indicator, 4, 150+sin(counter*4)*50, 255, 255, 255);
        ObjEffect_SetUVRect(indicator, 66, 36, 106, 48);
        Obj_SetPosition(indicator, CameraX+22, CameraY+8);
        
        if(CameraShow){ ObjEffect_SetTexture(indicator, imgText); }
        else { ObjEffect_SetTexture(indicator, ""); }
        counter++;
        yield;
      }
      
      counter = 0;
      while(CameraReady){
        let color = [0, 0, 0, 0];
        if(counter < 180){
          if(counter%4 < 2){ color = [200, 255, 255, 255]; }
          else { color = [200, 255, 128, 128]; }
        }
        else {
          if(counter%40 < 20){ color = [200, 255, 255, 255]; }
          else { color = [200, 255, 128, 128]; }
        }
        ObjEffect_SetColor(indicator, 4, color[0], color[1], color[2], color[3]);
        ObjEffect_SetUVRect(indicator, 66, 24, 106, 36);
        Obj_SetPosition(indicator, CameraX+22, CameraY+8);
        
        if(CameraShow && !CameraZoom && !CameraUsed){ ObjEffect_SetTexture(indicator, imgText); }
        else { ObjEffect_SetTexture(indicator, ""); }
        counter++;
        yield;
      }
    }
  }
  
  task DrawCameraPercentageEffect {
    let percentage = Obj_Create(OBJ_EFFECT);
    ObjEffect_SetTexture(percentage, imgText);
    ObjEffect_SetPrimitiveType(percentage, PRIMITIVE_TRIANGLESTRIP);
    ObjEffect_SetLayer(percentage, CameraLayer);
    ObjEffect_CreateVertex(percentage, 24);
    ObjEffect_SetVertexUV(percentage, 18, 66, 12);
    ObjEffect_SetVertexUV(percentage, 19, 66, 12);
    ObjEffect_SetVertexUV(percentage, 20, 78, 12);
    ObjEffect_SetVertexUV(percentage, 21, 66, 24);
    ObjEffect_SetVertexUV(percentage, 22, 78, 24);
    ObjEffect_SetVertexUV(percentage, 23, 78, 24);
    
    let minx = 0;
    ascent(i in 0..4){
      minx += 9;
      ObjEffect_SetVertexXY(percentage, (i*6)  , minx,    0);
      ObjEffect_SetVertexXY(percentage, (i*6)+1, minx,    0);
      ObjEffect_SetVertexXY(percentage, (i*6)+2, minx+12, 0);
      ObjEffect_SetVertexXY(percentage, (i*6)+3, minx,    12);
      ObjEffect_SetVertexXY(percentage, (i*6)+4, minx+12, 12);
      ObjEffect_SetVertexXY(percentage, (i*6)+5, minx+12, 12);
    }
    
    loop {
      let percent = CameraCharge;
      let percent100 = floor(percent/100);
      percent -= percent100*100;
      let percent10 = floor(percent/10);
      percent -= percent10*10;
      let percent1 = floor(percent);
      if(percent100 == 0){percent100 = 10;}
      if(percent10 == 0 && percent100 == 10){percent10 = 10;}
      
      let percentArray = [percent100, percent10, percent1];
      
      ascent(i in 0..3){
        if(percentArray[i] <= 9){
          ObjEffect_SetVertexUV(percentage, i*6,   percentArray[i]*12   , 0);
          ObjEffect_SetVertexUV(percentage, i*6+1, percentArray[i]*12   , 0);
          ObjEffect_SetVertexUV(percentage, i*6+2, percentArray[i]*12+12, 0);
          ObjEffect_SetVertexUV(percentage, i*6+3, percentArray[i]*12   , 12);
          ObjEffect_SetVertexUV(percentage, i*6+4, percentArray[i]*12+12, 12);
          ObjEffect_SetVertexUV(percentage, i*6+5, percentArray[i]*12+12, 12);
        }
        else {
          ObjEffect_SetVertexUV(percentage, i*6,   116, 188);
          ObjEffect_SetVertexUV(percentage, i*6+1, 116, 188);
          ObjEffect_SetVertexUV(percentage, i*6+2, 128, 188);
          ObjEffect_SetVertexUV(percentage, i*6+3, 116, 200);
          ObjEffect_SetVertexUV(percentage, i*6+4, 128, 200);
          ObjEffect_SetVertexUV(percentage, i*6+5, 128, 200);
        }
      }
      
      if(CameraReady){
        ascent(i in 0..24){
          ObjEffect_SetVertexColor(percentage, i, 200, 255, 128, 128);
        }
      }
      else {
        ascent(i in 0..24){
          ObjEffect_SetVertexColor(percentage, i, 200, 255, 255, 255);
        }
      }
      
      Obj_SetPosition(percentage, CameraX-50, CameraY-14);
      
      if(CameraShow){
        ObjEffect_SetTexture(percentage, imgText);
      }
      else {
        ObjEffect_SetTexture(percentage, "");
      }
      yield;
    }
  }
  
  task DrawCameraCircleEffect {
    let circle = ObjEffect_InitializeRect(imgCircle1, CameraLayer);
    ObjEffect_SetUVRect(circle, 0, 0, 64, 64);
    ObjEffect_SetXYRect(circle, -32, -32, 32, 32);
    
    let angle = 0;
    let anglespeed = 3;
    let scale = 1;
    let color = [200, 255, 128, 128];
    loop {
      if(CameraReady){
        anglespeed = 9;
        scale = 1;
        color = [200, 255, 128, 128];
      }
      else {
        anglespeed = 5;
        scale = 0.3;
        color = [150, 255, 255, 255];
      }
      if(GetGameSpeed != -1){
        angle += anglespeed;
        if(angle > 360){ angle -= 360; }
      }
      
      Obj_SetPosition(circle, CameraX, CameraY);
      ObjEffect_SetAngle(circle, 0, 0, angle);
      ObjEffect_SetScale(circle, scale, scale);
      ObjEffect_SetColor(circle, 4, color[0], color[1], color[2], color[3]);
      
      if(CameraShow){ ObjEffect_SetTexture(circle, imgCircle1); }
      else { ObjEffect_SetTexture(circle, ""); }
      yield;
    }
  }
  
  task DrawCameraCrosshairEffect {
    let crosshair = ObjEffect_InitializeRect(imgCrosshair, CameraLayer);
    ObjEffect_SetUVRect(crosshair, 0, 0, 64, 64);
    ObjEffect_SetXYRect(crosshair, -32, -32, 32, 32);
    ObjEffect_SetColor(crosshair, 4, 200, 255, 255, 255);
    
    let counter = 0;
    let basescale = 1;
    let color = [0, 0, 0, 0];
    loop {
      color = [160+sin(counter)*32, 255, 255, 255];
      basescale = 1;
      if(CameraReady){
        basescale = 1.25;
        if(Distance(GetEnemyX, GetEnemyY, CameraX, CameraY) < 100){ color = [160+sin(counter)*32, 255, 128, 128]; }
      }
      
      Obj_SetPosition(crosshair, CameraX, CameraY);
      ObjEffect_SetScale(crosshair, basescale+sin(counter)*basescale/10, basescale+sin(counter)*basescale/10);
      
      if(CameraReady && Distance(GetEnemyX, GetEnemyY, CameraX, CameraY) < 100){
        ObjEffect_SetColor(crosshair, 4, 160+sin(counter)*32, 255, 128, 128);
      }
      else {
        ObjEffect_SetColor(crosshair, 4, 160+sin(counter)*32, 255, 255, 255);
      }
      
      counter+=9;
      if(counter > 360){ counter -= 360; }
      
      if(CameraShow){ ObjEffect_SetTexture(crosshair, imgCrosshair); }
      else { ObjEffect_SetTexture(crosshair, ""); }
      yield;
    }
  }
}

sub ControlCharge {
  if(
    GetPlayerEnabled &&
    GetKeyState(VK_SHOT)==KEY_HOLD && 
    GetKeyState(VK_SLOWMOVE)==KEY_HOLD &&
    !CameraReady &&
    !CameraUsed
  ){
    Charging = true;
    CameraCharge += CameraChargeAccel;
    CameraChargeAccel += 0.005;
    if(CameraChargeAccel > 0.4){ CameraChargeAccel = 0.4; }
  }
  else {
    Charging = false;
    CameraChargeAccel = 0.08;
    if(
      GetPlayerEnabled &&    
      !CameraReady &&
      !CameraUsed  &&
      (GetKeyState(VK_SHOT)!=KEY_HOLD || GetKeyState(VK_SLOWMOVE)!=KEY_HOLD)
    ){
      CameraCharge += 0.1;
    }
    else if(!GetPlayerEnabled){
      CameraCharge = 50;
      CameraChargeAccel = 0.08;
      CameraReady = false;
      CameraZoom = false;
      CameraUsed = false;
      CameraShow = true;
      Charging = false;
    }
  }
  if(CameraCharge > 100){
    CameraCharge = 100;
    CameraReady = true;
  }
}