#TouhouDanmakufu[Player]
#ScriptVersion[2]
#Menu[Youmu]
#Text[Arrow keys: Movement
Shift: Slow move
Z: Shoot
X: Charge Special
C: Switch Shot

Special: Sword Slash. Deletes bullets and deals high damage close range.
Shot 1: Myon Spread. Lock angle with slow move.
Shot 2: Myon Focused. Lock angle with slow move.]
#Image[.\YoumuSelect.png]
#ReplayName[Youmu]

script_player_main {
  #include_function ".\AnimationHelpers.dnh"
  let imgYoumuCutIn = GCD ~ "img\youmucutin.png";
  let imgMyon       = GCD ~ "img\myon.png";
  let imgBar        = GCD ~ "img\bar.png";
  
  let shotCount = -1;
  let bNextShot = false;
  
  let MyonX = GetCenterX;
  let MyonY = GetCenterY;
  let MyonShotAngle = 270;
  
  let SecondaryShot = false;
  let xDisplace = 0;
  let yDisplace = 0;
  
  let sfxCharge1 = GCD ~ "sfx\charge1.wav";
  let sfxCharge2 = GCD ~ "sfx\charge2.wav";
  let sfxSlash = GCD ~ "sfx\slash.wav";
  let sfxShot = GCD ~ "sfx\shot.wav";
  
  @Initialize {
    LoadGraphic(imgMyon);
    LoadGraphic(imgBar);
    
    SetPlayerLifeImage(imgYoumu, 0, 0, 32, 48);
    SetInitialBombCount(0);
    
    LoadPlayerShotData(GCD ~ "YoumuShotData.dnh");
    
    InitializeYoumuAnimation;
    ManageSpecialAttack;
    CreateMyon;
    
    if(!IsCommonDataAreaExists("temp")){
      CreateCommonDataArea("temp");
    }
    ex_SetSpeed(5.5, 1.8);
  }
  
  @MainLoop {
    SetX(GetCenterX);
    SetY(GetCenterY);
    if((GetKeyState(VK_SHOT)==KEY_PUSH || GetKeyState(VK_SHOT)==KEY_HOLD || bNextShot) && shotCount==-1){
      shotCount = 0;
      bNextShot = false;
    }
    if(GetKeyState(VK_SHOT)==KEY_HOLD && shotCount>0 && GetKeyState(VK_BOMB) != KEY_HOLD){
      bNextShot = true;
    }
    if(shotCount%5 == 0 && GetKeyState(VK_BOMB) != KEY_HOLD && !OnEvent){
      PlaySE(sfxShot);
      Shot(GetPlayerX, GetPlayerY, 15, YoumuAngle-10, 2, 2, 1);
      Shot(GetPlayerX, GetPlayerY, 15, YoumuAngle   , 3, 2, 1);
      Shot(GetPlayerX, GetPlayerY, 15, YoumuAngle+10, 2, 2, 1);
    }

    if(shotCount >= 0 && GetKeyState(VK_BOMB) != KEY_HOLD){
      shotCount++;
    }
    if(shotCount == 30 || GetKeyState(VK_BOMB)==KEY_HOLD){
      shotCount=-1;
    }
    
    if(GetKeyState(VK_USER)==KEY_PUSH){
      SecondaryShot = !SecondaryShot;
    }
    
    SetIntersectionCircle(GetPlayerX, GetPlayerY, 1);
    yield;
  }
  @Missed {
    yield;
    MyonShotAngle = 270;
    shotCount = -1;
    bNextShot = false;
    SetX(GetCenterX);
    SetY(GetCenterY);
  }
  @SpellCard {
  }
  
  @DrawLoop {
    DrawYoumu;
  }
  
  @Finalize {
    DeleteGraphic(imgYoumu);
    DeleteGraphic(imgMyon);
    DeleteGraphic(imgBar);
  }
  
  task ex_SetSpeed(unfocus, focus){
    SetSpeed(0, 0);
    
    let xPos = 0;
    let yPos = 0;
    loop {
      let angle = GetPlayerMoveAngle;
      let speed = 0;
      xDisplace = 0;
      yDisplace = 0;
      if(GetPlayerMoveAngle != NULL && !OnMissed){
        let speed = unfocus;
        if(IsFocused){
          speed = focus;
        }
        xDisplace = cos(angle)*speed;
        yDisplace = sin(angle)*speed;
      }
      
      xPos += xDisplace;
      yPos += yDisplace;
      
      if(xPos > 320){ xPos -= 640; }
      if(xPos <= -320){ xPos += 640; }
      if(yPos > 320){ yPos -= 640; }
      if(yPos <= -320){ yPos += 640; }
      SetCommonDataEx("temp", "xPos", xPos);
      SetCommonDataEx("temp", "yPos", yPos);
      SetCommonDataEx("temp", "xDisplace", xDisplace);
      SetCommonDataEx("temp", "yDisplace", yDisplace);
      yield;
    }
  }
  
  task ManageSpecialAttack {
    let charge = 0;
    yield;
    DrawSpecialBar;
    loop {
      if(GetKeyState(VK_BOMB)==KEY_HOLD && !OnEvent && !OnMissed){
        PlaySE(sfxCharge1);
        while(GetKeyState(VK_BOMB)==KEY_HOLD && !OnEvent && !OnMissed && charge < 100){
          charge++;
          yield;
        }
        StopSE(sfxCharge1);
        if(charge >= 100){
          PlaySE(sfxCharge2);
        }
        while(GetKeyState(VK_BOMB)==KEY_HOLD && !OnEvent && !OnMissed){
          yield;
        }
      }
      if(charge >= 100 && !OnEvent && !OnMissed){
        Slash;
        charge = 0;
        Wait(30);
      }
      charge = 0;
      yield;
    }
    
    task DrawSpecialBar {
      yield;
      let bar = ObjEffect_InitializeRect(imgBar, 3);
      ObjEffect_SetUVRect(bar, 0, 8, 0, 16);
      ObjEffect_SetXYRect(bar, -32, -4, -32, 4);
      ObjEffect_SetColor(bar, 4, 255, 16, 112, 96);
      let container = ObjEffect_InitializeRect(imgBar, 3);
      ObjEffect_SetUVRect(container, 0, 0, 64, 8);
      ObjEffect_SetXYRect(container, -32, -4, 32, 4);
      ObjEffect_SetColor(container, 4, 255, 176, 224, 240);
      
      loop {
        while(charge < 100){
          Obj_SetPosition(bar, GetPlayerX, GetPlayerY+26);
          Obj_SetPosition(container, GetPlayerX, GetPlayerY+26);
          ObjEffect_SetUVRect(bar, 0, 8, charge*0.64, 16);
          ObjEffect_SetXYRect(bar, -32, -4, -32+charge*0.64, 4);
          yield;
        }
        ObjEffect_SetUVRect(bar, 0, 8, 64, 16);
        ObjEffect_SetXYRect(bar, -32, -4, 32, 4);
        
        let counter = 0;
        while(charge >= 100){
          Obj_SetPosition(bar, GetPlayerX, GetPlayerY+26);
          Obj_SetPosition(container, GetPlayerX, GetPlayerY+26);
          if(counter%4 <= 1){
            ObjEffect_SetColor(bar, 4, 255, 176, 224, 240);
          }
          else {
            ObjEffect_SetColor(bar, 4, 255, 16, 112, 96);
          }
          counter++;
          yield;
        }
        ObjEffect_SetColor(bar, 4, 255, 16, 112, 96);
      }
    }
    
    task Slash {
      PlaySE(sfxSlash);
      CreateSlashShot(GetPlayerX+cos(YoumuAngle)*24, GetPlayerY+sin(YoumuAngle)*24);
      let baseX = GetPlayerX+cos(YoumuAngle+180)*30;
      let baseY = GetPlayerY+sin(YoumuAngle+180)*30;
      loop(6){
        descent(i in 0..10){
          DeleteEnemyShotImmediatelyInCircle(SHOT, baseX+cos(YoumuAngle-i*5)*64, baseY+sin(YoumuAngle-i*5)*64, 18-i/2);
        }
        ascent(i in 1..10){
          DeleteEnemyShotImmediatelyInCircle(SHOT, baseX+cos(YoumuAngle+i*5)*64, baseY+sin(YoumuAngle+i*5)*64, 18-i/2);
        }
        yield;
      }
      
      task CreateSlashShot(x, y){
        let obj = Obj_Create(OBJ_SHOT);
        Obj_SetPosition(obj, x, y);
        Obj_SetSpeed(obj, 1);
        Obj_SetAngle(obj, YoumuAngle);
        ObjShot_SetGraphic(obj, 2);
        ObjShot_SetDamage(obj, 100);
        ObjShot_SetPenetration(obj, 100);
        loop(12){
          Obj_SetPosition(obj, Obj_GetX(obj)-xDisplace, Obj_GetY(obj)-yDisplace);
          yield;
        }
        Obj_Delete(obj);
      }
    }
  }
  
  task CreateMyon {
    DrawMyonEffect;
    UpdateMyonPosition;
    UpdateMyonAngle;
    loop {
      if(SecondaryShot){
        if(shotCount%5 == 0){
          Shot(MyonX, MyonY, 15, MyonShotAngle-5, 1.4, 2, 1);
          Shot(MyonX, MyonY, 15, MyonShotAngle-2.5, 1.5, 2, 1);
          Shot(MyonX, MyonY, 15, MyonShotAngle, 2, 1.6, 1);
          Shot(MyonX, MyonY, 15, MyonShotAngle+2.5, 1.5, 2, 1);
          Shot(MyonX, MyonY, 15, MyonShotAngle+5, 2, 1.4, 1);
        }
      }
      else {
        if(shotCount%5 == 0){
          Shot(MyonX, MyonY, 15, MyonShotAngle-30, 1, 2, 1);
          Shot(MyonX, MyonY, 15, MyonShotAngle-15, 1.1, 2, 1);
          Shot(MyonX, MyonY, 15, MyonShotAngle, 1.2, 2, 1);
          Shot(MyonX, MyonY, 15, MyonShotAngle+15, 1.1, 2, 1);
          Shot(MyonX, MyonY, 15, MyonShotAngle+30, 1, 2, 1);
        }
      }
      yield;
    }
   
    task UpdateMyonPosition {
      let xCounter = 0;
      let yCounter = 0;
      loop {
        let targetx = GetPlayerX;
        let targety = GetPlayerY;
        targetx += sin(xCounter*2.5)*24;
        targety += sin(yCounter*1.5)*12;
        MyonX = (MyonX*19 + targetx)/20 - xDisplace;
        MyonY = (MyonY*19 + targety)/20 - yDisplace;
        xCounter++;
        yCounter++;
        yield;
      }
    }
    
    task UpdateMyonAngle {
      loop {
        let targetAngle = GetPlayerMoveAngle;
        if(targetAngle!=NULL && !IsFocused){
          let angdist = AngularDistance(MyonShotAngle, targetAngle+180);
          if(absolute(angdist) < 5){
            MyonShotAngle = targetAngle+180;
          }
          else if(angdist < 0){
            MyonShotAngle -= 5;
          }
          else {
            MyonShotAngle += 5;
          }
        }
        yield;
      }
    }
    
    task DrawMyonEffect {
      loop {
        yield;
        if(!OnMissed){
          CreateMyonParticle(MyonX, MyonY, rand_int(0, 7));
        }
      }
      
      task CreateMyonParticle(x, y, type){
        let uvx = (type%4)*32;
        let uvy = floor(type/4)*32;
      
        let obj = ObjEffect_InitializeRect(imgMyon, 2);
        ObjEffect_SetXYRect(obj, -16, -16, 16, 16);
        ObjEffect_SetUVRect(obj, uvx, uvy, uvx+32, uvy+32);
        Obj_SetPosition(obj, x, y);
        descent(i in 0..30){
          Obj_SetPosition(obj, Obj_GetX(obj)-xDisplace, Obj_GetY(obj)-yDisplace);
          ObjEffect_SetColor(obj, 4, 255/30*i, 255, 255, 255);
          ObjEffect_SetScale(obj, i/30, i/30);
          yield;
        }
        Obj_Delete(obj);
      }
    }
  }

  task Shot(x, y, speed, angle, damage, penetration, graphic){
    let obj = Obj_Create(OBJ_SHOT);
    Obj_SetPosition(obj, x, y);
    Obj_SetSpeed(obj, speed);
    Obj_SetAngle(obj, angle);
    Obj_SetAutoDelete(obj, false);
    ObjShot_SetGraphic(obj, graphic);
    ObjShot_SetDamage(obj, damage);
    ObjShot_SetPenetration(obj, penetration);
    while(Distance(Obj_GetX(obj), Obj_GetY(obj), x, y) < 300 && !Obj_BeDeleted(obj)){
      Obj_SetPosition(obj, Obj_GetX(obj)-xDisplace, Obj_GetY(obj)-yDisplace);
      yield;
    }
    //add special effect
    Obj_Delete(obj);
  }
}