class Game_Event < Game_Character
  def in_view_areaT(cx ,cy)
#~     return false unless @va_conditions
    case @va_conditions.view_areas_num
    when 0
      in_view_areaF(cx,cy)
    when 1

      in_view_areaF2(cx,cy)
    end  
    
  end  
  
  def out_view_areaT(cx ,cy)    
#~     return false unless @va_conditions
    case @va_conditions.not_view_areas_num
    when 0
 
      area_circle_norm2(cx,cy,8)
    when 1
      
      in_view_areaF2(cx,cy)
    end     
  end 
  
  def in_view_areaF(cx,cy)
    t = false
    t = view_area_frac1(cx,cy) && area_circle_norm1(cx,cy,7)
    t ||=  view_area_frac2(cx,cy)
    return t
    
  end    
  
  def in_view_areaF2(cx,cy)
    t = false
    t = view_area_frac1(cx,cy) && area_circle_norm1(cx,cy,4)
    t ||=  view_area_frac_rect(cx,cy,3,5,-1,1)
    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 < 8) && (-1 <= cy && cy <= 1)
      return true
    else
      return false
    end  
    
  end  
  def view_area_frac_rect(cx,cy,a,b,c,d)
    if (a<= cx && cx <= b) && (c <= cy && cy <= d)
      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    
  
end  

class Game_Event < Game_Character
  attr_accessor :moveChange  
  attr_accessor :chase_flag
  attr_accessor :view_area_type 
  attr_accessor :view_area_mode
  attr_accessor :page_id
  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 = true
    @view_area_mode = 0
    set_page_id
    set_view_area_conditions
  end 
  
  #視界エリアの条件のセット
  def set_view_area_conditions
    va = check_change_selfswitch ? check_change_selfswitch : nil
    va_con = va ? (va[0] ? (va[0].include?(@page.page_id) ? va[1]  : nil) : va[1] ) : nil
    @va_conditions = va_con ? $view_area_conditions[va_con] : nil 
  end 

  def clear_self_button_chase
    return unless check_change_selfswitch
    key = [@map_id, @event.id, $switchChar]
    $game_self_switches[key] = false
  end  

  #--------------------------------------------------------------------------
  # ● イベントページの設定をセットアップ
  #--------------------------------------------------------------------------
  alias tako5setup_page_settings  setup_page_settings
  def setup_page_settings
    tako5setup_page_settings
#~     set_page_id
    set_view_area_conditions
  end
  #--------------------------------------------------------------------------
  # ●
  #--------------------------------------------------------------------------
  def set_page_id
    return unless @event 
    num = 1
    @event.pages.each do |i| 
      
      i.page_id = num 
      num += 1
    end  
  end  
  #--------------------------------------------------------------------------
  # ● 移動タイプ : 近づく
  #--------------------------------------------------------------------------

  def update_self_movementEx
    selfswitchChange if check_change_selfswitch
    update_self_movement
  end
  
  #視界スクリプトを動作させるか判定
  def check_change_selfswitch
    va_condition = $data_view_areas_conditions[[@character_name , @character_index]] 

    return va_condition || $view_area_set[[@map_id ,@id]]  
 
  end  
    
  
  #エリアによるセルフスイッチの変更
  def selfswitchChange

    return unless @va_conditions
    return if @va_conditions.sight_strength < $game_player.event_invisiblity
    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 = out_view_area(cx,cy)

    facemodeS = (@va_conditions.face_to_face_mode ? face_inverse_Pface : true)
   
      
    key = [@map_id, @event.id, $switchChar]
    key2 = [@map_id, @event.id, $switchCharA]
    
    if inVA && !@moveChange && facemodeS
      $game_self_switches[key] = true
      $game_self_switches[key2] = false
      $game_self_switches.on_change 
      @moveChange  = true
    elsif !(inVAoff) && @moveChange 
      $game_self_switches[key] = false
      $game_self_switches[key2] = true 
      $game_self_switches.on_change 
      @moveChange  = false
    end      

    
  end  
  #スイッチ用の条件
  def condition_switch_on
    
  end
  
  #スイッチ用の条件
  def condition_switch_on2
    
  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]
    return in_view_areaT(cxT , cyT)
  end  
  def out_view_area(cx,cy)
    array = transCoord([cx,cy], @direction)
    cxT = array[0]
    cyT = array[1]
    return out_view_areaT(cxT ,cyT)
  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
    td1 = false
    td2 = false
    pid = 0
    tsetID = $game_map.map.tileset_id
    darray.each do |d|
      pid = get_pid(d)
      tarray = get_tile_id_array(d,tsetID)
      tidx = tarray[0]
      tidy = tarray[1]
      td1 = $data_viewblind.include?([tsetID, pid, tidx,tidy])
      td2 = $data_viewnonblind.include?([tsetID, pid, tidx,tidy]) 
      dd ||= ((d_tileset(d) == 3) && !td2 )         
      dd ||= (td1 && !td2)       
#~         dd ||= $game_map.terrain_tag(cSx, cSy) >= 1
    
    end 

    return dd
  end

  def get_tile_id_array(d ,tsetID)
      if d >= 2048  
          tid = d - get_dtile_least_const(d)
          
          tid /= 48
          tidx = tid % 8
          tidy = (tid / 8 ) - tile_id_const(tsetID,d , 0) 

      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)

      end  
      return [tidx ,tidy] 
  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
      dadd =  ($data_viewblind_add.include?([$game_map.map_id , et.id])) || check_blind_character_name(et)
      nondadd = ($data_viewnonblind_add.include?([$game_map.map_id , et.id])) 
      d ||= ( dt && dadd && !nondadd)

    end
    return d
  end  
  
  def check_blind_character_name(event)
    return false unless $data_viewblind_character_names
    $data_viewblind_character_names.any? do |data_array|
      check_blind_character_name_each(data_array, event)
    end  
  end 
    
  
  def check_blind_character_name_each(data_array, event)
    
    return false unless data_array[0] == event.character_name
    return false unless data_array[1] == event.character_index
    data_array[2] == -1 || data_array[2] == event.direction
  end  

  def face_inverse_Pface
    @direction + $game_player.direction == 10
  end  
end  

class Game_Map
  def map 
    @map
  end
  
  def map_id
    @map_id
  end  
  
  def clear_self_switch_chase
    @events.each_value {|e| e.clear_self_button_chase}
  end  
    
end  

class Game_Player < Game_Character
  def event_invisiblity
    @event_invisiblity = 0 unless @event_invisiblity
    @event_invisiblity 
  end   
  
  def event_invisiblity=(val)
    @event_invisiblity = val
  end  
  
end  

class RPG::Event::Page
  alias ttttakoinitialize initialize
  def initialize
    ttttakoinitialize
    @page_id = 0
  end

  def page_id 
    @page_id
  end  
  
  def page_id=(val)
    @page_id = val
  end  
end

class View_Area_Conditions
  attr_accessor :view_areas_num
  attr_accessor :not_view_areas_num 
  attr_accessor :face_to_face_mode
  attr_accessor :sight_strength
  
  def initialize(va , nva ,fm , sight_strength)
    @view_areas_num = va
    @not_view_areas_num  = nva
    @face_to_face_mode = fm
    @sight_strength = sight_strength
  end  
  

  
end  