class Game_Event < Game_Character
  attr_accessor :moveChange  
  attr_accessor :chase_flag

  def move_type
    @move_type
  end  
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     event : RPG::Event
  #--------------------------------------------------------------------------
  alias tako4initialize initialize
  def initialize(map_id, event)
    tako4initialize(map_id, event)
    
    @moveChange = false
    @chase_flag = (priority_type == 1 )

  end  

  #--------------------------------------------------------------------------
  # ● 移動タイプ : 近づく
  #--------------------------------------------------------------------------

  def update_self_movementEx
    selfswitchChange
    update_self_movement
  end

  #エリアによるセルフスイッチの変更
  def selfswitchChange
    inVA = false
    cx = - distance_x_from($game_player.x)
    cy = - distance_y_from($game_player.y)
    inVA = in_view_area(cx,cy) && !blind_wall(cx,cy)
    inVAoff = area_circle_norm2(cx,cy,11)
    if inVA && !@moveChange
      
      key = [@map_id, @event.id, $switchChar]
      $game_self_switches[key] = true
      @moveChange  = true
      
    elsif !(inVAoff) && @moveChange
      key = [@map_id, @event.id, $switchChar]
      $game_self_switches[key] = false
      @moveChange  = false      
      
      key2 = [@map_id, @event.id, $switchCharA]
      $game_self_switches[key2] = true  
    end      
    
  end  
  
  #--------------------------------------------------------------------------
  # ● 停止時の更新
  #--------------------------------------------------------------------------
  def update_stop
    super
    if chase_flag 
      update_self_movementEx 
      
    else  
      update_self_movement unless @move_route_forcing
    end  
  end
  
  def in_view_area(cx,cy)
    array = transCoord([cx,cy], @direction)
    cxT = array[0]
    cyT = array[1]
    in_view_areaT(cxT , cyT)
  end  
  
  def in_view_areaT(cx,cy)
    t = false
    t = view_area_frac1(cx,cy) && area_circle_norm1(cx,cy,8)
    t ||=  view_area_frac2(cx,cy)
    return t
    
  end  
  
  def area_circle_norm1(cx,cy,r)
    sx = cx.abs
    sy = cy.abs
    return sx + sy < r
  end      
    

  
  def view_area_frac1(cx,cy)
    if (cy - cx < 0) && (cx + cy > 0)
      return true
    else
      return false
    end  
    
  end   

  def view_area_frac2(cx,cy)
    if (3 < cx && cx < 9) && (-1 <= cy && cy <= 1)
      return true
    else
      return false
    end  
    
  end  
  
  def area_circle_norm2(cx,cy,r)
    if cx ^2 + cy ^2 <= r^2
      return true
    else
      return false
    end  
    
  end  
  
  #座標変換　
  def transCoord(array,d)
    cx = array[0]
    cy = array[1]
    case d
    when 2
      return [cy,-cx]
    when 4
      return [- cx,-cy]      
    when 6
      return [cx,cy]      
    when 8
      return [-cy, cx]      
    else

    end  
  end  
  
  #座標変換（上の逆変換）
  def transCoordInverse(array,d)
    cx = array[0]
    cy = array[1]
    case d
    when 2
      return [-cy,cx]
    when 4
      return [- cx,-cy]      
    when 6
      return [cx,cy]      
    when 8
      return [cy, -cx]      
    else

    end  
  end  
  
  #座標変換 local -> global
  def transCoordLocalIntoGlobal(array,d)
    array2 = transCoordInverse(array,d)
    return [(array2[0] + @x) , (array2[1] + @y)]
    
  end
  
  #壁による視界の遮断
  def blind_wall(cx,cy)
    cT = transCoord([cx,cy],@direction)
    array = get_line_cell(cT[0] , cT[1])
    d = false
    array.each do |c|
      cS = transCoordLocalIntoGlobal(c,@direction)
      d ||= (is_blind_object?(cS[0],cS[1]) || is_blind_event?(cS[0],cS[1]))
    end  
    return d
  end  
  
  #ライン上にあるセルの配列の取得
  def get_line_cell(cTx , cTy)
    cTxa = cTx.abs
    cTya = cTy.abs   
    xSign = (cTx >= 0) ? 1 : (-1)
    ySign = (cTy >= 0) ? 1 : (-1)
    return [[0,0]] if cTxa == 0 && cTya == 0
    array = []    
    if cTxa == 0
      for j in 0 .. cTya
        array.push([0,j])
      end  
      return array
    end  
    cTyi0 = 0
    cTyi1 = 0
    cTyi0int = 0
    cTyi1int = 0    
    for i in 0 .. cTxa
      cTyi0 = 1.0 * cTya * i / cTxa 
      cTyi1 = 1.0 * cTya * (i + 1) / cTxa + 0.5

      cTyi0int = cTyi0.floor
      cTyi1int = cTyi1.floor     
      for j in cTyi0int .. cTyi1int 
        array.push([i * xSign , j * ySign])
    
      end
    end    
    return array
  end
  
  #ライン上にあるマップチップは視界を遮断するか
#~   def blind_on_line?(cx,cy)
#~     array = get_line_cell(cx , cy)
#~     d = false
#~     array.each do |c|
#~       d ||= is_blind_object?(c[0],c[1])
#~     end
#~     return d
#~   end  
  
  #座標cx,cyにあるマップチップまたはイベントが視界を遮断するか
  def is_blind_object?(cSx,cSy)
    darray = $game_map.layered_tiles(cSx, cSy)
    dd = false
    pid = 0
    tsetID = $game_map.map.tileset_id
    darray.each do |d|
      pid = get_pid(d)
      if d >= 2048  
          tid = d - get_dtile_least_const(d)
          
          tid /= 48
          tidx = tid % 8
          tidy = (tid / 8 ) - tile_id_const(tsetID,d , 0) 

          dd ||= $data_viewblind.include?([tsetID, pid, tidx,tidy])       

      else
          tid = d - get_dtile_least_const(d)
          tidx = tid % 8
          tidy = (tid / 8 ) + ((d_tileset(d) == 4) ? tile_id_const(tsetID, d , 1) : 0)
          dd ||= $data_viewblind.include?([tsetID, pid, tidx,tidy])
      end 
              

#~         dd ||= $game_map.terrain_tag(cSx, cSy) >= 1
    
    end 

    return dd
  end
  
  def tile_id_const(tsetID,id,flagn)
    cc = d_tileset(id)
      
    return 0 if cc == 0

    xx = 0
    array = []
    for i in 0 .. cc - 1
      
      array = $data_check_tile[tsetID]
      if array[i] == flagn
        if i == 0 
          xx += 2
        elsif i == 1 || i == 2 
          xx += 4
        elsif i == 3 
          xx += 6
        end  

      end  
    end
    
    return xx
    
  end
  
  def d_tileset(id)

    cc = 0
    if id < 8 * 32
      cc = 5
  
    elsif id < 8 * 64
      cc = 6

    elsif id < 8 * 96
      cc = 7
      
    elsif id < 8 * 128  
      cc = 8
      
    elsif id < 2048
      cc = 4

    elsif id < 2048 + 48 * 8 * 2
      cc = 0
      
    elsif id < 2048 + 48 * 8 * 6
      cc = 1
    elsif id < 2048 + 48 * 8 * 10
      cc = 2
    elsif id < 2048 + 48 * 8 * 16 
      cc = 3
      
    end      
    return cc
  end  
  
  def get_pid(id)
    dtileset = d_tileset(id)
    if dtileset < 5
      return 0
    elsif dtileset == 5
      return 1
    elsif dtileset == 6 
      return 2
    elsif dtileset == 7
      return 3
    elsif dtileset == 8       
      return 4
    end  
  end  
  
  def get_dtile_least_const(id)
    dtileset = d_tileset(id)
    if dtileset < 4

      return 2048
    elsif dtileset == 4
      return 1536
    elsif dtileset == 5 
      return 0
    elsif dtileset == 6
      return 8 * 32
    elsif dtileset == 7       
      return 8 * 64
    elsif dtileset == 8       
      return 8 * 96      
    end      
  end
  #それが視界を遮断するイベントか 
  def is_blind_event?(cSx,cSy)
    d = false 
    $game_map.events_xy(cSx,cSy).each do |et|
      dt = et.priority_type == 1 && et.move_type == 0
      dexcept =  ($data_chase_blind_exception.include?([$game_map.map_id , et.id]))
      nondexcept = ($data_chase_nonblind_exception.include?([$game_map.map_id , et.id])) 
      d ||= ( dt && dexcept && !nondexcept)

    end
    return d
  end  
end  

class Game_Map
  def map 
    @map
  end  
end  