Language Translator | JavaScript

Ruby to JavaScript Code Translation for Game Development

This document outlines the translated Ruby game code into JavaScript. It maintains original logic while ensuring compatibility with JavaScript syntax. Key game systems such as Renderer, DataManager, and Characters are preserved for


Empty image or helper icon

Prompt

#==============================================================================
# ** MakerSystems
#------------------------------------------------------------------------------
#  Module four our Systems.
#==============================================================================

module MakerSystems
  
  #============================================================================
  # ** Effectus
  #----------------------------------------------------------------------------
  #  This module contains variables that you can edit to make Effectus work
  # in whatever way you may need.
  #============================================================================
  
  module Effectus
    
    #------------------------------------------------------------------------
    # * Always Update Patterns.                                         [OPT]
    #------------------------------------------------------------------------
    # This are the patterns that Effectus will look for to know if it needs
    # to always update the event. The search is performed through all comments
    # in the current page of the event, so the order of the event commands
    # doesn't matter.
    # You don't have to use this feature if you set PREVENT_OFFSCREEN_UPDATES
    # to false.
    #------------------------------------------------------------------------
    PATTERNS = ['always']
    #------------------------------------------------------------------------
    # * Prevent Offscreen Updates.                                      [OPT]
    #------------------------------------------------------------------------
    # Common technique against event lag.
    # If true, events that are not inside the screen area won't be updated.
    # If false, events will be normally updated as in vanilla Ace.
    #           but you will still enjoy an enhanced experience thanks to
    #           the system's clever improvements.
    #------------------------------------------------------------------------
    PREVENT_OFFSCREEN_UPDATES = true
    #------------------------------------------------------------------------
    # * Screen Tile Division Modulo.                                    [OPT]
    #------------------------------------------------------------------------
    # Set this to true if either screen width or height divided by 32 (pixels
    # in a tile) has a division remainder.
    # If true, an additional tile is considered as "near the visible area".
    #          Tiny (really tiny) performance loss.
    # If false, screen size must be evenly divisible by 32 to avoid errors.
    #------------------------------------------------------------------------
    SCREEN_TILE_DIVMOD = true
    #------------------------------------------------------------------------
    # * Only Parallax Maps.                                             [OPT]
    #------------------------------------------------------------------------
    # Set this to true if you ONLY use parallax mapping in your project for
    # a huge performance boost.
    # If true, the tilemap (the thing needed to render the maps you created 
    #          using the editor inside the game) will be removed.
    # If false, the tilemap will be created as usual.
    #------------------------------------------------------------------------
    ONLY_PARALLAX_MAPS = false
    #------------------------------------------------------------------------
    # * Improved Plane.                                                 [OPT]
    #------------------------------------------------------------------------
    # Set this to true to use the best custom Plane script available, that is 
    # both memory and CPU efficient. This will improve the performance, 
    # especially for screen sizes bigger than 544x416.
    # If true, the default Plane script will be replaced by our version.
    # If false, the default Plane will be used as usual.
    #------------------------------------------------------------------------
    IMPROVED_PLANE     = false
    #------------------------------------------------------------------------
    # * ATB Bars Need Fixing?                                           [OPT]
    #------------------------------------------------------------------------
    # Set this to true if the bars from the battle system of your game are
    # not being displayed properly.
    # Ignore otherwise.
    # If true, the new Plane script will be in compatibility mode.
    # If false, the new Plane script will work normally.
    #------------------------------------------------------------------------
    ATB_BARS_NEED_FIXING = false
    #------------------------------------------------------------------------
    # * Improved Map Window Control.                                    [OPT]
    #------------------------------------------------------------------------
    # Set this to true to make Effectus improve the handling of default
    # Window objects in the map scene. It's a small improvement, deactivate
    # if you find any weird behavior with custom message systems.
    # If true, default Window objects on the map will be created on demand.
    # If false, default Window objects on the map will be handled as usual.
    #------------------------------------------------------------------------
    MAP_SCENE_WINDOW_IMPROVEMENTS = false
    #------------------------------------------------------------------------
    # * Sprite_Character Full Update Rate.                              [OPT]
    #------------------------------------------------------------------------
    # This is the interval at which the full update for Sprite_Character 
    # instances (The sprites for each event on the map) will be performed.
    # Must be greater than 0. Default is 2 (safe for everyone).
    # Increasing this number makes Sprite_Character less responsive to 
    # changes so you'll have to try to find a value that suits your game.
    #------------------------------------------------------------------------
    SPRITE_CHARACTER_FULL_UPDATE_RATE = 2
    
  end
  
end

#==============================================================================
# ** Plane
#------------------------------------------------------------------------------
#  Planes are special Sprites that tile bitmap patterns across the entire
# screen and are used to display parallax backgrounds and so on.
#==============================================================================

if MakerSystems::Effectus::IMPROVED_PLANE

Object.send(:remove_const, :Plane)

class Plane < Sprite
  
  #--------------------------------------------------------------------------
  # * Set Bitmap.                                                       [NEW]
  #--------------------------------------------------------------------------
  def bitmap=(new_bitmap)
    return if new_bitmap == @ms_real_bitmap && viewport == @ms_last_viewport
    if @ms_real_bitmap
      @ms_real_bitmap  = nil
      self.bitmap.dispose
    end
    return super(new_bitmap) unless new_bitmap
    vw = viewport ? viewport.rect.width  : Graphics.width
    vh = viewport ? viewport.rect.height : Graphics.height
    @ms_real_width  = new_bitmap.width
    @ms_real_height = new_bitmap.height
    super(Bitmap.new(vw + @ms_real_width, vh + @ms_real_height))
    horizontal = vw / @ms_real_width  + 1 + (vw % @ms_real_width  > 0 ? 1 : 0)
    vertical   = vh / @ms_real_height + 1 + (vh % @ms_real_height > 0 ? 1 : 0)
    horizontal.times do |bx|
      vertical.times do |by|
        bitmap.blt(
          bx * @ms_real_width,
          by * @ms_real_height, new_bitmap,
          new_bitmap.rect
        )
      end
    end
    @ms_last_viewport = viewport
    @ms_real_bitmap   = new_bitmap
  end
  #--------------------------------------------------------------------------
  # * Set Offset X.                                                     [NEW]
  #--------------------------------------------------------------------------
  def ox=(value)
    super(@ms_real_bitmap ? value % @ms_real_width  : value)
  end
  #--------------------------------------------------------------------------
  # * Set Offset Y.                                                     [NEW]
  #--------------------------------------------------------------------------
  def oy=(value)
    super(@ms_real_bitmap ? value % @ms_real_height : value)
  end
  #--------------------------------------------------------------------------
  # * Bitmap.                                                           [NEW]
  #--------------------------------------------------------------------------
  if MakerSystems::Effectus::ATB_BARS_NEED_FIXING
    def bitmap
      super
    end
  else
    def bitmap
      @ms_real_bitmap ? @ms_real_bitmap : super
    end
  end
  #--------------------------------------------------------------------------
  # * Set Viewport.                                                     [NEW]
  #--------------------------------------------------------------------------
  def viewport=(new_viewport)
    if new_viewport != viewport
      super(new_viewport)
      self.bitmap = @ms_real_bitmap if @ms_real_bitmap
    end
  end
  #--------------------------------------------------------------------------
  # * Dispose.                                                          [NEW]
  #--------------------------------------------------------------------------
  def dispose
    if @ms_real_bitmap
      @ms_real_bitmap  = nil
      self.bitmap.dispose
    end
    super
  end
  
end

end

#==============================================================================
# ** DataManager
#------------------------------------------------------------------------------
#  This module manages the database and game objects. Almost all of the 
# global variables used by the game are initialized by this module.
#==============================================================================

module DataManager
  
  class << self
    
    #------------------------------------------------------------------------
    # * Create Save Contents.                                           [REP]
    #------------------------------------------------------------------------
    def save_game_without_rescue(index)
      $game_map.ms_effectus_party_pos.default = nil
      $game_map.ms_effectus_event_pos.default = nil
      $game_map.ms_effectus_etile_pos.default = nil
      $game_map.ms_effectus_etriggers.default = nil
      File.open(make_filename(index), "wb") do |file|
        $game_system.on_before_save
        Marshal.dump(make_save_header, file)
        Marshal.dump(make_save_contents, file)
        @last_savefile_index = index
      end
      $game_map.ms_effectus_party_pos.default_proc = proc { |h, k| h[k] = [] }
      $game_map.ms_effectus_event_pos.default_proc = proc { |h, k| h[k] = [] }
      $game_map.ms_effectus_etile_pos.default_proc = proc { |h, k| h[k] = [] }
      $game_map.ms_effectus_etriggers.default_proc = proc { |h, k| h[k] = [] }
      true
    end
    #------------------------------------------------------------------------
    # * Extract Save Contents.                                          [REP]
    #------------------------------------------------------------------------
    def extract_save_contents(contents)
      $game_system        = contents[:system]
      $game_timer         = contents[:timer]
      $game_message       = contents[:message]
      $game_switches      = contents[:switches]
      $game_variables     = contents[:variables]
      $game_self_switches = contents[:self_switches]
      $game_actors        = contents[:actors]
      $game_party         = contents[:party]
      $game_troop         = contents[:troop]
      $game_map           = contents[:map]
      $game_player        = contents[:player]
      return unless $game_map.ms_effectus_party_pos
      $game_map.ms_effectus_party_pos.default_proc = proc { |h, k| h[k] = [] }
      $game_map.ms_effectus_event_pos.default_proc = proc { |h, k| h[k] = [] }
      $game_map.ms_effectus_etile_pos.default_proc = proc { |h, k| h[k] = [] }
      $game_map.ms_effectus_etriggers.default_proc = proc { |h, k| h[k] = [] }
    end
  end
  
end

#==============================================================================
# ** Game_Temp
#------------------------------------------------------------------------------
#  This class handles temporary data that is not included with save data.
# The instance of this class is referenced by $game_temp.
#==============================================================================

class Game_Temp

  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_accessor :ms_effectus_sprites, :ms_effectus_triggers
  #--------------------------------------------------------------------------
  # * Initialize.                                                       [REP]
  #--------------------------------------------------------------------------
  def initialize
    @common_event_id      = 0
    @fade_type            = 0
    @ms_effectus_sprites  = {}
    @ms_effectus_triggers = []
  end
  
end

#==============================================================================
# ** Game_Switches
#------------------------------------------------------------------------------
#  This class handles switches. It's a wrapper for the built-in class "Array."
# The instance of this class is referenced by $game_switches.
#==============================================================================

class Game_Switches
  
  #--------------------------------------------------------------------------
  # * Set Switch.                                                       [REP]
  #--------------------------------------------------------------------------
  def []=(switch_id, value)
    @data[switch_id] = value
    trigger_symbol = :"switch_#{switch_id}"
    unless $game_temp.ms_effectus_triggers.include?(trigger_symbol)
      $game_temp.ms_effectus_triggers << trigger_symbol
    end
    $game_map.ms_effectus_need_refresh = true
    on_change
  end
  #--------------------------------------------------------------------------
  # * On Change.                                                        [REP]
  #--------------------------------------------------------------------------
  def on_change
    # Kept for compatibility purposes.
  end
  
end

#==============================================================================
# ** Game_Variables
#------------------------------------------------------------------------------
#  This class handles variables. It's a wrapper for the built-in class "Array."
# The instance of this class is referenced by $game_variables.
#==============================================================================

class Game_Variables
  
  #--------------------------------------------------------------------------
  # * Set Variable.                                                     [REP]
  #--------------------------------------------------------------------------
  def []=(variable_id, value)
    @data[variable_id] = value
    trigger_symbol = :"variable_#{variable_id}"
    unless $game_temp.ms_effectus_triggers.include?(trigger_symbol)
      $game_temp.ms_effectus_triggers << trigger_symbol
    end
    $game_map.ms_effectus_need_refresh = true
    on_change
  end
  #--------------------------------------------------------------------------
  # * On Change.                                                        [REP]
  #--------------------------------------------------------------------------
  def on_change
    # Kept for compatibility purposes.
  end
  
end

#==============================================================================
# ** Game_SelfSwitches
#------------------------------------------------------------------------------
#  This class handles self switches. It's a wrapper for the built-in class
# "Hash." The instance of this class is referenced by $game_self_switches.
#==============================================================================

class Game_SelfSwitches
  
  #--------------------------------------------------------------------------
  # * Set SelfSwitch.                                                   [REP]
  #--------------------------------------------------------------------------
  def []=(key, value)
    @data[key] = value
    unless $game_temp.ms_effectus_triggers.include?(key)
      $game_temp.ms_effectus_triggers << key
    end
    $game_map.ms_effectus_need_refresh = true
    on_change
  end
  #--------------------------------------------------------------------------
  # * On Change.                                                        [REP]
  #--------------------------------------------------------------------------
  def on_change
    # Kept for compatibility purposes.
  end
  
end

#==============================================================================
# ** Game_Party
#------------------------------------------------------------------------------
#  This class handles parties. Information such as gold and items is included.
# Instances of this class are referenced by $game_party.
#==============================================================================

class Game_Party < Game_Unit
  
  #--------------------------------------------------------------------------
  # * Add an Actor.                                                     [REP]
  #--------------------------------------------------------------------------
  def add_actor(actor_id)
    @actors.push(actor_id) unless @actors.include?(actor_id)
    $game_player.refresh
    trigger_symbol = :"actor_id_#{actor_id}"
    unless $game_temp.ms_effectus_triggers.include?(trigger_symbol)
      $game_temp.ms_effectus_triggers << trigger_symbol
    end
    $game_map.ms_effectus_need_refresh = true
  end
  #--------------------------------------------------------------------------
  # * Remove Actor.                                                     [REP]
  #--------------------------------------------------------------------------
  def remove_actor(actor_id)
    @actors.delete(actor_id)
    $game_player.refresh
    trigger_symbol = :"actor_id_#{actor_id}"
    unless $game_temp.ms_effectus_triggers.include?(trigger_symbol)
      $game_temp.ms_effectus_triggers << trigger_symbol
    end
    $game_map.ms_effectus_need_refresh = true
  end
  #--------------------------------------------------------------------------
  # * Increase/Decrease Items.                                          [REP]
  #--------------------------------------------------------------------------
  def gain_item(item, amount, include_equip = false)
    container = item_container(item.class)
    return unless container
    last_number = item_number(item)
    new_number = last_number + amount
    container[item.id] = [[new_number, 0].max, max_item_number(item)].min
    container.delete(item.id) if container[item.id] == 0
    if include_equip && new_number < 0
      discard_members_equip(item, -new_number)
    end
    trigger_symbol = :"item_id_#{item.id}"
    unless $game_temp.ms_effectus_triggers.include?(trigger_symbol)
      $game_temp.ms_effectus_triggers << trigger_symbol
    end
    $game_map.ms_effectus_need_refresh = true
  end
  
end

#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
#  This class handles maps. It includes scrolling and passage determination
# functions. The instance of this class is referenced by $game_map.
#==============================================================================

class Game_Map

  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_accessor :ms_effectus_event_pos, :ms_effectus_party_pos,
                :ms_effectus_etile_pos, :ms_effectus_hard_events,
                :ms_effectus_events_to_update, :ms_effectus_pass_table,
                :ms_effectus_event_starting, :ms_effectus_etriggers,
                :ms_effectus_tile_events, :ms_effectus_need_refresh
  #--------------------------------------------------------------------------
  # * Setup.                                                            [REP]
  #--------------------------------------------------------------------------
  def setup(map_id)
    @ms_effectus_dref_display_x   = 0
    @ms_effectus_dref_display_y   = 0
    @ms_effectus_event_starting   = nil
    @ms_effectus_events_to_update = []
    @ms_effectus_hard_events      = []
    @ms_effectus_tile_events      = []
    @ms_effectus_initial_run      = nil
    @ms_effectus_ody              = nil
    @ms_effectus_odx              = nil
    @ms_effectus_party_pos        = Hash.new { |hash, key| hash[key] = [] }
    @ms_effectus_event_pos        = Hash.new { |hash, key| hash[key] = [] }
    @ms_effectus_etile_pos        = Hash.new { |hash, key| hash[key] = [] }
    @ms_effectus_etriggers        = Hash.new { |hash, key| hash[key] = [] }
    @ms_effectus_need_refresh     = false
    @map_id = map_id
    @map = load_data(sprintf("Data/Map%03d.rvdata2", @map_id))
    @tileset_id = @map.tileset_id
    @display_x = 0
    @display_y = 0
    referesh_vehicles
    setup_events
    setup_scroll
    setup_parallax
    setup_battleback
    @need_refresh = false
    @ms_effectus_pass_table = Table.new($game_map.width, $game_map.height, 4)
    $game_player.followers.each do |follower|
      follower.ms_effectus_position_registered = false
    end
    @ms_effectus_adjx = (width  - screen_tile_x) / 2
    @ms_effectus_adjy = (height - screen_tile_y) / 2
  end
  #--------------------------------------------------------------------------
  # * Refresh Tile Events.                                              [REP]
  #--------------------------------------------------------------------------
  def ms_effectus_refresh_tile_events
    @tile_events = []
    @ms_effectus_tile_events.each { |e| e.tile? && @tile_events << e }
  end
  #--------------------------------------------------------------------------
  # * Refresh.                                                          [REP]
  #--------------------------------------------------------------------------
  def refresh
    @tile_events = []
    @events.each_value do |event|
      event.refresh
      event.tile? && @tile_events << event
    end
    @common_events.each { |event| event.refresh }
    @need_refresh = false
  end
  #--------------------------------------------------------------------------
  # * Trigger Refresh.                                                  [NEW]
  #--------------------------------------------------------------------------
  def ms_effectus_trigger_refresh
    $game_temp.ms_effectus_triggers.each do |trigger|
      ms_effectus_etriggers[trigger].each { |event| event.refresh }
    end
    ms_effectus_refresh_tile_events
    $game_temp.ms_effectus_triggers.clear
    @ms_effectus_need_refresh = false
  end
  #--------------------------------------------------------------------------
  # * Update.                                                           [REP]
  #--------------------------------------------------------------------------
  def update(main = false)
    refresh                     if @need_refresh
    ms_effectus_trigger_refresh if @ms_effectus_need_refresh
    if main
      update_interpreter 
    else
      update_events
      update_vehicles
    end
    update_scroll
    update_parallax
    @screen.update
    @ms_effectus_dref_display_x = (@display_x * 32).floor / 32.0
    @ms_effectus_dref_display_y = (@display_y * 32).floor / 32.0
  end
  #--------------------------------------------------------------------------
  # * Set Correct Display Values.                                       [NEW]
  #--------------------------------------------------------------------------
  def ms_effectus_dref_set
    @ms_effectus_dref_display_x = (@display_x * 32).floor / 32.0
    @ms_effectus_dref_display_y = (@display_y * 32).floor / 32.0
  end
  #--------------------------------------------------------------------------
  # * Display X.                                                        [REP]
  #--------------------------------------------------------------------------
  def display_x
    @ms_effectus_dref_display_x
  end
  #--------------------------------------------------------------------------
  # * Display Y.                                                        [REP]
  #--------------------------------------------------------------------------
  def display_y
    @ms_effectus_dref_display_y
  end
  #--------------------------------------------------------------------------
  # * Calculate X Coordinate, Minus Display Coordinate.                 [REP]
  #--------------------------------------------------------------------------
  def adjust_x(x)
    if loop_horizontal? && x < @ms_effectus_dref_display_x - @ms_effectus_adjx
      x - @ms_effectus_dref_display_x + @map.width
    else
      x - @ms_effectus_dref_display_x
    end
  end
  #--------------------------------------------------------------------------
  # * Calculate Y Coordinate, Minus Display Coordinate.                 [REP]
  #--------------------------------------------------------------------------
  def adjust_y(y)
    if loop_vertical? && y < @ms_effectus_dref_display_y - @ms_effectus_adjy
      y - @ms_effectus_dref_display_y + @map.height
    else
      y - @ms_effectus_dref_display_y
    end
  end
  #--------------------------------------------------------------------------
  # * Update Events.                                                    [REP]
  #--------------------------------------------------------------------------
  if MakerSystems::Effectus::SCREEN_TILE_DIVMOD
    def update_events
      if @events.size > 999 && MakerSystems::Effectus::PREVENT_OFFSCREEN_UPDATES
        unless @ms_effectus_initial_run
          @events.each_value  { |event| event.update }
          @common_events.each { |event| event.update }
          @ms_effectus_initial_run = true
          return
        end
        adx = @display_x.to_i
        ady = @display_y.to_i
        if adx != @ms_effectus_odx || ady != @ms_effectus_ody
          @ms_effectus_odx = adx
          @ms_effectus_ody = ady
          @ms_effectus_events_to_update = []
          x1 = adx - 3
          x2 = adx + screen_tile_x + 2
          y1 = ady - 3
          y2 = ady + screen_tile_y + 2
          x1 = 0      if x1 < 0 
          x2 = width  if x2 > width
          y1 = 0      if y1 < 0
          y2 = height if y2 > height
          while x1 <= x2
            yy = y1
            while yy <= y2
              @ms_effectus_event_pos[yy * width + x1].each do |event|
                @ms_effectus_events_to_update << event
                event.update
              end
              yy += 1
            end
            x1 += 1
          end
          return
        end
         (@ms_effectus_events_to_update | @ms_effectus_hard_events).each do |e|
          e.update
        end
      else
        @events.each_value { |event| event.update }
      end
      @common_events.each  { |event| event.update }
    end
  else
    def update_events
      if @events.size > 999 && MakerSystems::Effectus::PREVENT_OFFSCREEN_UPDATES
        unless @ms_effectus_initial_run
          @events.each_value  { |event| event.update }
          @common_events.each { |event| event.update }
          @ms_effectus_initial_run = true
          return
        end
        adx = @display_x.to_i
        ady = @display_y.to_i
        if adx != @ms_effectus_odx || ady != @ms_effectus_ody
          @ms_effectus_odx = adx
          @ms_effectus_ody = ady
          @ms_effectus_events_to_update = []
          x1 = adx - 3
          x2 = adx + screen_tile_x + 1
          y1 = ady - 3
          y2 = ady + screen_tile_y + 1
          x1 = 0      if x1 < 0 
          x2 = width  if x2 > width
          y1 = 0      if y1 < 0
          y2 = height if y2 > height
          while x1 <= x2
            yy = y1
            while yy <= y2
              @ms_effectus_event_pos[yy * width + x1].each do |event|
                @ms_effectus_events_to_update << event
                event.update
              end
              yy += 1
            end
            x1 += 1
          end
          return
        end
        (@ms_effectus_events_to_update | @ms_effectus_hard_events).each do |e|
          e.update
        end
      else
        @events.each_value { |event| event.update }
      end
      @common_events.each  { |event| event.update }
    end
  end
  #--------------------------------------------------------------------------
  # * Set Display Position.                                             [REP]
  #--------------------------------------------------------------------------
  def set_display_pos(x, y)
    to_update_events = $game_map.ms_effectus_events_to_update
    x = [0, [x, width  - screen_tile_x].min].max unless loop_horizontal?
    y = [0, [y, height - screen_tile_y].min].max unless loop_vertical?
    @display_x = (x + width)  % width
    @display_y = (y + height) % height
    @parallax_x = x
    @parallax_y = y
    to_update_events.each { |event| event.update }
  end
  #--------------------------------------------------------------------------
  # * Events XY.                                                        [REP]
  #--------------------------------------------------------------------------
  def events_xy(x, y)
    @ms_effectus_event_pos[y * width + x]
  end
  #--------------------------------------------------------------------------
  # * Events XY NT.                                                     [REP]
  #--------------------------------------------------------------------------
  def events_xy_nt(x, y)
    @ms_effectus_event_pos[y * width + x].select { |event| !event.through }
  end
  #--------------------------------------------------------------------------
  # * Tile Events XY.                                                   [REP]
  #--------------------------------------------------------------------------
  def tile_events_xy(x, y)
    @ms_effectus_etile_pos[y * width + x]
  end
  #--------------------------------------------------------------------------
  # * All Tiles.                                                        [REP]
  #--------------------------------------------------------------------------
  def all_tiles(x, y)
    @ms_effectus_etile_pos[y * width + x].collect { |event| event.tile_id } + 
    layered_tiles(x, y)
  end
  #--------------------------------------------------------------------------
  # * Alias Passable?                                                   [NEW]
  #--------------------------------------------------------------------------
  alias_method(:ms_effectus_original_passable?, :passable?)
  #--------------------------------------------------------------------------
  # * Passable?                                                         [MOD]
  #--------------------------------------------------------------------------
  def passable?(x, y, d)
    if @ms_effectus_pass_table[x, y, (d / 2) - 1] == 0
      cd = 10 - d
      cx = d == 4 ? x - 1 : d == 6 ? x + 1 : x
      cy = d == 2 ? y + 1 : d == 8 ? y - 1 : y
      if ms_effectus_original_passable?(x, y, d) &&
        ms_effectus_original_passable?(cx, cy, cd)
        @ms_effectus_pass_table[x, y, (d / 2) - 1] = 1
        @ms_effectus_pass_table[cx, cy, (cd / 2) - 1] = 1
        return true
      else
        @ms_effectus_pass_table[x, y, (d / 2) - 1] = 2
        return false
      end
    end
    @ms_effectus_pass_table[x, y, (d / 2) - 1] == 1
  end
  #--------------------------------------------------------------------------
  # * MS Effectus Release.                                              [NEW]
  #--------------------------------------------------------------------------
  def ms_effectus_release(x, y)
    @ms_effectus_pass_table[x, y, 0] = 0
    @ms_effectus_pass_table[x, y, 1] = 0
    @ms_effectus_pass_table[x, y, 2] = 0
    @ms_effectus_pass_table[x, y, 3] = 0
    @ms_effectus_pass_table[x - 1, y, 0] = 0
    @ms_effectus_pass_table[x - 1, y, 1] = 0
    @ms_effectus_pass_table[x - 1, y, 2] = 0
    @ms_effectus_pass_table[x - 1, y, 3] = 0
    @ms_effectus_pass_table[x + 1, y, 0] = 0
    @ms_effectus_pass_table[x + 1, y, 1] = 0
    @ms_effectus_pass_table[x + 1, y, 2] = 0
    @ms_effectus_pass_table[x + 1, y, 3] = 0
    @ms_effectus_pass_table[x, y - 1, 0] = 0
    @ms_effectus_pass_table[x, y - 1, 1] = 0
    @ms_effectus_pass_table[x, y - 1, 2] = 0
    @ms_effectus_pass_table[x, y - 1, 3] = 0
    @ms_effectus_pass_table[x, y + 1, 0] = 0
    @ms_effectus_pass_table[x, y + 1, 1] = 0
    @ms_effectus_pass_table[x, y + 1, 2] = 0
    @ms_effectus_pass_table[x, y + 1, 3] = 0
  end
  #--------------------------------------------------------------------------
  # * Setup Starting Map Event.                                         [REP]
  #--------------------------------------------------------------------------
  def setup_starting_map_event
    return nil unless @ms_effectus_event_starting
    event = @ms_effectus_event_starting
    event.clear_starting_flag
    @interpreter.setup(event.list, event.id)
    @ms_effectus_event_starting = nil
    event
  end
  #--------------------------------------------------------------------------
  # * Any Event Starting?                                               [REP]
  #--------------------------------------------------------------------------
  def any_event_starting?
    @ms_effectus_event_starting
  end
  
end

#==============================================================================
# ** Game_CommonEvent
#------------------------------------------------------------------------------
#  This class handles common events. It includes functionality for execution of
# parallel process events. It's used within the Game_Map class ($game_map).
#==============================================================================

class Game_CommonEvent

  #--------------------------------------------------------------------------
  # * Initialize.                                                       [REP]
  #--------------------------------------------------------------------------
  def initialize(common_event_id)
    @event = $data_common_events[common_event_id]
    refresh 
    if @event.parallel? || @event.autorun?
      trigger = $game_map.ms_effectus_etriggers[:"switch_#{@event.switch_id}"]
      trigger << self unless trigger.include?(self)
    end
  end
  
end

#==============================================================================
# ** Game_CharacterBase
#------------------------------------------------------------------------------
#  This base class handles characters. It retains basic information, such as 
# coordinates and graphics, shared by all characters.
#==============================================================================

class Game_CharacterBase
 
  #--------------------------------------------------------------------------
  # * Passable?                                                         [REP]
  #--------------------------------------------------------------------------
  def passable?(x, y, d)
    x2 = x + (d == 4 ? -1 : d == 6 ? 1 : 0)
    y2 = y + (d == 8 ? -1 : d == 2 ? 1 : 0)
    return false unless $game_map.valid?(x2, y2)
    return true if @through || debug_through?
    return false unless map_passable?(x, y, d)
    return false if collide_with_characters?(x2, y2)
    return true
  end
  #--------------------------------------------------------------------------
  # * Collide with Events?                                              [REP]
  #--------------------------------------------------------------------------
  def collide_with_events?(x, y)
    $game_map.ms_effectus_event_pos[y * $game_map.width + x].each do |event|
      if (event.normal_priority? || self.is_a?(Game_Event)) && !event.through
        return true
      end
    end
    false
  end
  
end

#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
#  This class handles the player. It includes event starting determinants and
# map scrolling functions. The instance of this class is referenced by
# $game_player.
#==============================================================================

class Game_Player < Game_Character
  
  #--------------------------------------------------------------------------
  # * Map Passable?                                                     [REP]
  #--------------------------------------------------------------------------
  def map_passable?(x, y, d)
    case @vehicle_type
    when :boat
      ox = d == 4 ? -1 : d == 6 ? 1 : 0
      oy = d == 8 ? -1 : d == 2 ? 1 : 0
      $game_map.boat_passable?(x, y) && $game_map.boat_passable?(x + ox, y + oy)
    when :ship
      ox = d == 4 ? -1 : d == 6 ? 1 : 0
      oy = d == 8 ? -1 : d == 2 ? 1 : 0
      $game_map.ship_passable?(x, y) && $game_map.ship_passable?(x + ox, y + oy)
    when :airship
      true
    else
      super
    end
  end
  #--------------------------------------------------------------------------
  # * Collide?                                                          [REP]
  #--------------------------------------------------------------------------
  def collide?(x, y)
    !@through && (pos?(x, y)  ||
    !$game_map.ms_effectus_party_pos[y * $game_map.width + x].empty?)
  end
  #--------------------------------------------------------------------------
  # * Start Map Event.                                                  [REP]
  #--------------------------------------------------------------------------
  def start_map_event(x, y, triggers, normal)
    return if $game_map.interpreter.running?
    $game_map.ms_effectus_event_pos[y * $game_map.width + x].each do |event|
      if event.trigger_in?(triggers) && event.normal_priority? == normal
        event.start
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update.                                                     [REP]
  #--------------------------------------------------------------------------
  def update
    last_real_x = @real_x
    last_real_y = @real_y
    last_moving = moving?
    move_by_input unless !movable? || $game_map.interpreter.running?
    super
    update_scroll(last_real_x, last_real_y) if last_real_x != @real_x ||
                                               last_real_y != @real_y
    update_vehicle unless @followers.gathering?
    update_nonmoving(last_moving) unless moving?
    @followers.update
  end
  #--------------------------------------------------------------------------
  # * Vehicle Processing.                                               [REP]
  #--------------------------------------------------------------------------
  def update_vehicle
    return unless vehicle
    if @vehicle_getting_on
      update_vehicle_get_on
    elsif @vehicle_getting_off
      update_vehicle_get_off
    else
      vehicle.sync_with_player
    end
  end
  #--------------------------------------------------------------------------
  # * Update Scroll.                                                    [REP]
  #--------------------------------------------------------------------------
  def update_scroll(last_real_x, last_real_y)
    ax1 = $game_map.adjust_x(last_real_x)
    ay1 = $game_map.adjust_y(last_real_y)
    ax2 = $game_map.adjust_x(@real_x)
    ay2 = $game_map.adjust_y(@real_y)
    $game_map.scroll_down (ay2 - ay1) if ay2 > ay1 && ay2 > center_y
    $game_map.scroll_left (ax1 - ax2) if ax2 < ax1 && ax2 < center_x
    $game_map.scroll_right(ax2 - ax1) if ax2 > ax1 && ax2 > center_x
    $game_map.scroll_up   (ay1 - ay2) if ay2 < ay1 && ay2 < center_y
    $game_map.ms_effectus_dref_set
  end
  
end

#==============================================================================
# ** Game_Follower
#------------------------------------------------------------------------------
#  This class handles followers. A follower is an allied character, other than
# the front character, displayed in the party. It is referenced within the
# Game_Followers class.
#==============================================================================

class Game_Follower < Game_Character
  
  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_accessor :ms_effectus_position_registered
  #--------------------------------------------------------------------------
  # * Update.                                                           [REP]
  #--------------------------------------------------------------------------
  def update
    @move_speed     = $game_player.real_move_speed
    @transparent    = $game_player.transparent
    @walk_anime     = $game_player.walk_anime
    @step_anime     = $game_player.step_anime
    @direction_fix  = $game_player.direction_fix
    @opacity        = $game_player.opacity
    @blend_type     = $game_player.blend_type
    super
    if visible?
      events = $game_map.ms_effectus_party_pos
      width  = $game_map.width
      unless @ms_effectus_position_registered
        events[@y * width + @x] << self
        @ms_effectus_last_x = @x
        @ms_effectus_last_y = @y
        @ms_effectus_position_registered = true
      end
      if @x != @ms_effectus_last_x || @y != @ms_effectus_last_y
        events[@y * width + @x] <<
        events[@ms_effectus_last_y * width + @ms_effectus_last_x].delete(self)
        @ms_effectus_last_x = @x
        @ms_effectus_last_y = @y
      end
    else
      if @ms_effectus_position_registered
        @ms_effectus_position_registered = nil
        $game_map.ms_effectus_party_pos[@ms_effectus_last_y *
        $game_map.width + @ms_effectus_last_x].delete(self)
      end
    end
  end
  
end

#==============================================================================
# ** Game_Vehicle
#------------------------------------------------------------------------------
#  This class handles vehicles. It's used within the Game_Map class. If there
# are no vehicles on the current map, the coordinates are set to (-1,-1).
#==============================================================================

class Game_Vehicle < Game_Character

  #--------------------------------------------------------------------------
  # * Determine if Docking/Landing Is Possible.                         [REP]
  #--------------------------------------------------------------------------
  def land_ok?(x, y, d)
    if @type == :airship
      return false unless $game_map.airship_land_ok?(x, y)
      return false unless $game_map.events_xy(x, y).empty?
    else
      x2 = d == 4 ? x - 1 : d == 6 ? x + 1 : x
      y2 = d == 8 ? y - 1 : d == 2 ? y + 1 : y
      return false unless $game_map.valid?(x2, y2) &&
      $game_map.ms_effectus_original_passable?(x2, y2, 10 - 1)
      return false if collide_with_characters?(x2, y2)
    end
    return true
  end
  
end

#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
#  This class handles events. Functions include event page switching via
# condition determinants and running parallel process events. Used within the
# Game_Map class.
#==============================================================================

class Game_Event < Game_Character
  
  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_accessor :viewport1
  
  #--------------------------------------------------------------------------
  # * Initialize.                                                       [REP]
  #--------------------------------------------------------------------------
  def initialize(map_id, event)
    super()
    @map_id = map_id
    @event = event
    @id = @event.id
    moveto(@event.x, @event.y)
    refresh
    triggers    = $game_map.ms_effectus_etriggers
    tile_events = $game_map.ms_effectus_tile_events
    @event.pages.each do |page|
      condition = page.condition
      if condition.switch1_valid
        trigger_symbol = :"switch_#{condition.switch1_id}"
        unless triggers[trigger_symbol].include?(self)
          triggers[trigger_symbol]  << self 
        end
      end
      if condition.switch2_valid
        trigger_symbol = :"switch_#{condition.switch2_id}"
        unless triggers[trigger_symbol].include?(self)
          triggers[trigger_symbol]  << self 
        end
      end
      if condition.variable_valid
        trigger_symbol = :"variable_#{condition.variable_id}"
        unless triggers[trigger_symbol].include?(self)
          triggers[trigger_symbol]  << self 
        end
      end
      if condition.self_switch_valid
        key = [@map_id, @event.id, condition.self_switch_ch]
        unless triggers[key].include?(self)
          triggers[key] << self
        end
      end
      if condition.item_valid
        trigger_symbol = :"item_id_#{condition.item_id}"
        unless triggers[trigger_symbol].include?(self)
          triggers[trigger_symbol]  << self 
        end
      end
      if condition.actor_valid
        trigger_symbol = :"actor_id_#{condition.actor_id}"
        unless triggers[trigger_symbol].include?(self)
          triggers[trigger_symbol]  << self 
        end
      end
      if page.graphic.tile_id > 0 && page.priority_type == 0
        unless tile_events.include?(self)
          tile_events << self
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Init Public Members.                                              [REP]
  #--------------------------------------------------------------------------
  def init_public_members
    super
    @trigger = 0
    @list = nil
    @starting = false
    if $game_map.ms_effectus_event_starting == self
      $game_map.ms_effectus_event_starting = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Clear Starting Flag.                                              [REP]
  #--------------------------------------------------------------------------
  def clear_starting_flag
    @starting = false
    if $game_map.ms_effectus_event_starting == self
      $game_map.ms_effectus_event_starting = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Detect Collision with Character.                                  [REP]
  #--------------------------------------------------------------------------
  def collide_with_characters?(x, y)
    super || (normal_priority? && $game_player.collide?(x, y))
  end
  #--------------------------------------------------------------------------
  # * Start.                                                            [REP]
  #--------------------------------------------------------------------------
  def start
    return if empty?
    @starting = true
    lock if trigger_in?([0,1,2])
    $game_map.ms_effectus_event_starting = self
  end
  #--------------------------------------------------------------------------
  # * Refresh.                                                          [REP]
  #--------------------------------------------------------------------------
  def refresh
    new_page = @erased ? nil : find_proper_page
    setup_page(new_page) if !new_page || new_page != @page
    @ms_effectus_always_update = false
    if @page && @page.list
      @page.list.each do |command|
        next unless command.code == 108
        MakerSystems::Effectus::PATTERNS.each do |string| 
          next unless command.parameters[0].include?(string)
          @ms_effectus_always_update = true                
          break
        end
        break if @ms_effectus_always_update
      end
    end
    @ms_effectus_always_update = true if trigger == 3 || trigger == 4
    if $game_map.ms_effectus_hard_events.include?(self)
      unless @ms_effectus_always_update
        $game_map.ms_effectus_hard_events.delete(self)
      end
    else
      if @ms_effectus_always_update
        $game_map.ms_effectus_hard_events << self
      end
    end
    if tile? || @ms_effectus_tile
      if $game_map.ms_effectus_pass_table
        unless @ms_effectus_tile && tile?
          $game_map.ms_effectus_release(@x, @y)
        end
      end
    end
    @ms_effectus_tile = tile?
    if @ms_effectus_tile
      unless @ms_effectus_tile_registered
        @ms_effectus_tile_registered = true
        $game_map.ms_effectus_etile_pos[@y * $game_map.width + @x] << self
      end
    else
      if @ms_effectus_tile_registered
        $game_map.ms_effectus_etile_pos[@y * $game_map.width + @x].delete(self)
        @ms_effectus_tile_registered = nil
      end
    end
    unless @ms_effectus_position_registered
      $game_map.ms_effectus_event_pos[@y * $game_map.width + @x] << self
      @ms_effectus_last_x = @x
      @ms_effectus_last_y = @y
      @ms_effectus_position_registered = true
    end
    unless @character_name == @ms_effectus_last_character_name
      bitmap = Cache.character(@character_name)
      string = @character_name[/^[\!\$]./]
      if string && string.include?('$')
        @ms_effectus_bw = bitmap.width / 3 
        @ms_effectus_bh = bitmap.height / 4 
      else
        @ms_effectus_bw = bitmap.width / 12
        @ms_effectus_bh = bitmap.height / 8
      end
      @ms_effectus_last_character_name = @character_name
      @ms_effectus_special_calculus = @ms_effectus_bw > 32 ||
                                      @ms_effectus_bh > 32
    end
  end
  #--------------------------------------------------------------------------
  # * Near the Screen?                                                  [NEW]
  #--------------------------------------------------------------------------
  if MakerSystems::Effectus::SCREEN_TILE_DIVMOD
    def ms_effectus_near_the_screen?
      if @ms_effectus_special_calculus
        sx = (@real_x - $game_map.display_x) * 32 + 16
        sy = (@real_y - $game_map.display_y) * 32 + 32 - shift_y - jump_height
        sx + @ms_effectus_bw > 0 && 
        sx - @ms_effectus_bw < Graphics.width &&
        sy + @ms_effectus_bh > 0 &&
        sy - @ms_effectus_bh < Graphics.height
      else
        @real_x > $game_map.display_x - 1 &&
        @real_x < $game_map.display_x + Graphics.width  / 32 + 1 &&
        @real_y > $game_map.display_y - 1 &&
        @real_y < $game_map.display_y + Graphics.height / 32 + 1
      end
    end
  else
    def ms_effectus_near_the_screen?
      if @ms_effectus_special_calculus
        sx = (@real_x - $game_map.display_x) * 32 + 16
        sy = (@real_y - $game_map.display_y) * 32 + 32 - shift_y - jump_height
        sx + @ms_effectus_bw > 0 && 
        sx - @ms_effectus_bw < Graphics.width &&
        sy + @ms_effectus_bh > 0 &&
        sy - @ms_effectus_bh < Graphics.height
      else
        @real_x > $game_map.display_x - 1 &&
        @real_x < $game_map.display_x + Graphics.width  / 32 &&
        @real_y > $game_map.display_y - 1 &&
        @real_y < $game_map.display_y + Graphics.height / 32
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Update During Autonomous Movement.                                [REP]
  #--------------------------------------------------------------------------
  if MakerSystems::Effectus::PREVENT_OFFSCREEN_UPDATES
    def update_self_movement
      if @stop_count > 30 * (5 - @move_frequency)
        case @move_type
        when 1
          move_type_random
        when 2
          move_type_toward_player
        when 3
          move_type_custom
        end
      end
    end
  else
    def update_self_movement
      if near_the_screen? && @stop_count > stop_count_threshold
        case @move_type
        when 1
          move_type_random
        when 2
          move_type_toward_player
        when 3
          move_type_custom
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Move Type : Random.                                               [REP]
  #--------------------------------------------------------------------------
  def move_type_random
    case rand(6)
    when 0 then move_random
    when 1 then move_random
    when 2 then move_forward
    when 3 then move_forward
    when 4 then move_forward
    when 5 then @stop_count = 0
    end
  end
  #--------------------------------------------------------------------------
  # * Move Type : Approach.                                             [REP]
  #--------------------------------------------------------------------------
  def move_type_toward_player
    if near_the_player?
      case rand(6)
      when 0 then move_toward_player
      when 1 then move_toward_player
      when 2 then move_toward_player
      when 3 then move_toward_player
      when 4 then move_random
      when 5 then move_forward
      end
    else
      move_random
    end
  end
  #--------------------------------------------------------------------------
  # * Alias Update.                                                     [NEW]
  #--------------------------------------------------------------------------
  alias_method(:ms_effectus_original_update, :update)
  #--------------------------------------------------------------------------
  # * Update.                                                           [MOD]
  #--------------------------------------------------------------------------
  def update
    active = MakerSystems::Effectus::PREVENT_OFFSCREEN_UPDATES
    ms_effectus_original_update unless active
    if ms_effectus_near_the_screen? || @ms_effectus_wait_for_animation ||
      @balloon_id > 0
      ms_effectus_original_update if active
      
      # crash fix by liam: dont run if scene @spriteset doesn't exist START
      # ------------------------------------------------------------------
      
      # do not do certain event updates if there is no spriteset for the scene
      # (spriteset not defined for the scene)
      if (!((defined? (SceneManager.scene.spriteset)).nil?))
      
        # do not do certain event updates if scene spriteset is nil
        if (!SceneManager.scene.spriteset.nil?)
      
          unless $game_temp.ms_effectus_sprites[@id]
              $game_temp.ms_effectus_sprites[@id] = 
              Sprite_Character.new(SceneManager.scene.spriteset.viewport1, self)
          end
          $game_temp.ms_effectus_sprites[@id].update
          if $game_temp.ms_effectus_sprites[@id].animation?
            unless @ms_effectus_wait_for_animation
              @ms_effectus_wait_for_animation = true
              unless $game_map.ms_effectus_hard_events.include?(self)
                $game_map.ms_effectus_hard_events << self
              end
            end
          else
            if @ms_effectus_wait_for_animation
              @ms_effectus_wait_for_animation = nil
              unless @ms_effectus_always_update
                if $game_map.ms_effectus_hard_events.include?(self)
                  $game_map.ms_effectus_hard_events.delete(self)
                end
              end
            end
          end
        end
      end
      
      # crash fix by liam: dont run if scene @spriteset doesn't exist END
      # ------------------------------------------------------------------
      
    else
      ms_effectus_original_update if (@ms_effectus_always_update && active) ||
                                      @move_route_forcing
      unless @ms_effectus_always_update
        if @move_route_forcing
          unless @ms_effectus_wait_for_move_route_forcing
            @ms_effectus_wait_for_move_route_forcing = true
            unless $game_map.ms_effectus_hard_events.include?(self)
              $game_map.ms_effectus_hard_events << self
            end
          end
        else
          if @ms_effectus_wait_for_move_route_forcing
            @ms_effectus_wait_for_move_route_forcing = nil
            if $game_map.ms_effectus_hard_events.include?(self)
              $game_map.ms_effectus_hard_events.delete(self)
            end
          end
        end
      end
      if $game_temp.ms_effectus_sprites[@id]
        $game_temp.ms_effectus_sprites[@id].dispose
        $game_temp.ms_effectus_sprites.delete(@id)
      end
    end
    unless @ms_effectus_position_registered
      $game_map.ms_effectus_event_pos[@y * $game_map.width + @x] << self
      @ms_effectus_last_x = @x
      @ms_effectus_last_y = @y
      @ms_effectus_position_registered = true        
    end
    if @x != @ms_effectus_last_x || @y != @ms_effectus_last_y
      events = $game_map.ms_effectus_event_pos
      width = $game_map.width
      events[@y * width + @x] <<
      events[@ms_effectus_last_y * width + @ms_effectus_last_x].delete(self)
      if @ms_effectus_tile
        tiles = $game_map.ms_effectus_etile_pos
        tiles[@y * width + @x] << 
        tiles[@ms_effectus_last_y * width + @ms_effectus_last_x].delete(self)
      end
      @ms_effectus_last_x = @x
      @ms_effectus_last_y = @y
    end
  end
end

#==============================================================================
# ** Game_Interpreter
#------------------------------------------------------------------------------
#  An interpreter for executing event commands. This class is used within the
# Game_Map, Game_Troop, and Game_Event classes.
#==============================================================================

class Game_Interpreter
  
  #--------------------------------------------------------------------------
  # * Set Move Route
  #--------------------------------------------------------------------------
  def command_205
    $game_map.ms_effectus_trigger_refresh if $game_map.ms_effectus_need_refresh
    $game_map.refresh if $game_map.need_refresh
    character = get_character(@params[0])
    if character
      character.force_move_route(@params[1])
      Fiber.yield while character.move_route_forcing if @params[1].wait
    end
  end
  #--------------------------------------------------------------------------
  # * Change Actor Graphic
  #--------------------------------------------------------------------------
  def command_322
    actor = $game_actors[@params[0]]
    if actor
      actor.set_graphic(@params[1], @params[2], @params[3], @params[4])
    end
    $game_player.refresh
    return unless SceneManager.scene.is_a?(Scene_Map)
    SceneManager.scene.spriteset.ms_effectus_vanilla_update_sprites
  end

end

#==============================================================================
# ** Sprite_Base
#------------------------------------------------------------------------------
#  A sprite class with animation display processing added.
#==============================================================================

class Sprite_Base < Sprite
  
  #--------------------------------------------------------------------------
  # * Frame Update.                                                     [REP]
  #--------------------------------------------------------------------------
  def update
    super
    update_animation if animation?
    @@ani_checker.clear
    @@ani_spr_checker.clear
  end
  #--------------------------------------------------------------------------
  # * Update Animation.                                                 [REP]
  #--------------------------------------------------------------------------
  def update_animation
    @ani_duration -= 1
    if @ani_duration % @ani_rate == 0
      if @ani_duration > 0
        frame_index = @animation.frame_max
        frame_index -= (@ani_duration + @ani_rate - 1) / @ani_rate
        animation_set_sprites(@animation.frames[frame_index])
        @animation.timings.each do |timing|
          animation_process_timing(timing) if timing.frame == frame_index
        end
      else
        end_animation
      end
    end
  end
end

#==============================================================================
# ** Sprite_Character
#------------------------------------------------------------------------------
#  This sprite is used to display characters. It observes an instance of the
# Game_Character class and automatically changes sprite state.
#==============================================================================

class Sprite_Character < Sprite_Base
    
  MS_EFFECTUS_RATE = MakerSystems::Effectus::SPRITE_CHARACTER_FULL_UPDATE_RATE
  
  #--------------------------------------------------------------------------
  # * Object Initialization.                                            [REP]
  #--------------------------------------------------------------------------
  def initialize(viewport, character = nil)
    super(viewport)
    @character = character
    @balloon_duration = 0
    update_bitmap   if graphic_changed?
    if @tile_id == 0 && (@character.pattern != @ms_effectus_old_pattern ||
        @character.direction != @ms_effectus_old_dir)
      update_src_rect 
    end
    update_position 
    update_other
    setup_new_effect
    update_balloon  if @balloon_duration > 0
  end
  #--------------------------------------------------------------------------
  # * Frame Update.                                                     [REP]
  #--------------------------------------------------------------------------
  def update
    if Graphics.frame_count % 2 == 0 || Input.press?(:R)
      super    
      update_bitmap   if graphic_changed?
      if @tile_id == 0 && (@character.pattern != @ms_effectus_old_pattern ||
         @character.direction != @ms_effectus_old_dir)
        update_src_rect 
      end
      update_position
      update_other
      update_balloon  if @balloon_duration > 0
      setup_new_effect
    else
      super
      update_position
      update_balloon  if @balloon_duration > 0
    end
  end
  #--------------------------------------------------------------------------
  # * Vanilla Update.                                                   [NEW]
  #--------------------------------------------------------------------------
  def ms_effectus_vanilla_update
    update_bitmap   if graphic_changed?
    if @tile_id == 0 && (@character.pattern != @ms_effectus_old_pattern ||
        @character.direction != @ms_effectus_old_dir)
      update_src_rect 
    end
    update_position
    update_other
    update_balloon  if @balloon_duration > 0
    setup_new_effect
  end
  #--------------------------------------------------------------------------
  # * Update Transfer Origin Bitmap.                                    [REP]
  #--------------------------------------------------------------------------
  def update_bitmap
    @tile_id = @character.tile_id
    @character_name = @character.character_name
    @character_index = @character.character_index
    @tile_id > 0 ? set_tile_bitmap : set_character_bitmap
    @ms_effectus_old_pattern = nil
  end
  #--------------------------------------------------------------------------
  # * Update Transfer Origin Rectangle.                                 [REP]
  #--------------------------------------------------------------------------
  def update_src_rect
    @ms_effectus_old_pattern = @character.pattern
    @ms_effectus_old_dir     = @character.direction
    index = @character.character_index
    pattern = @character.pattern < 3 ? @character.pattern : 1
    sx = (index % 4 * 3 + pattern) * @cw
    sy = (index / 4 * 4 + (@character.direction - 2) / 2) * @ch
    self.src_rect.set(sx, sy, @cw, @ch)
  end
  #--------------------------------------------------------------------------
  # * Update Position.                                                  [REP]
  #--------------------------------------------------------------------------
  def update_position
    sx = (@character.real_x - $game_map.display_x) * 32 + 16
    sy = (@character.real_y - $game_map.display_y) * 32 + 32 -
          @character.shift_y - @character.jump_height
    move_animation(sx - x, sy - y) if @animation && @animation.position != 3
    if sx != @ms_effectus_old_sx
      @ms_effectus_old_sx = sx
      self.x = sx
    end
    if sy != @ms_effectus_old_sy
      @ms_effectus_old_sy = sy
      self.y = sy
    end
    self.z = @character.screen_z
  end
  #--------------------------------------------------------------------------
  # * Move Animation.                                                   [REP]
  #--------------------------------------------------------------------------
  def move_animation(dx, dy)
    @ani_ox += dx
    @ani_oy += dy
    @ani_sprites.each do |sprite|
      sprite.x += dx
      sprite.y += dy
    end
  end
  #--------------------------------------------------------------------------
  # * Update Balloon Icon.                                              [REP]
  #--------------------------------------------------------------------------
  def update_balloon
    @balloon_duration -= 1
    if @balloon_duration > 0
      @balloon_sprite.x = x
      @balloon_sprite.y = y - height
      @balloon_sprite.z = z + 200
      sx = balloon_frame_index * 32
      sy = (@balloon_id - 1) * 32
      @balloon_sprite.src_rect.set(sx, sy, 32, 32)
    else
      end_balloon
    end
  end
  
end

#==============================================================================
# ** Sprite_Picture
#------------------------------------------------------------------------------
#  This sprite is used to display pictures. It observes an instance of the
# Game_Picture class and automatically changes sprite states.
#==============================================================================

class Sprite_Picture < Sprite
  
  #--------------------------------------------------------------------------
  # * Frame Update.                                                     [REP]
  #--------------------------------------------------------------------------
  def update
    super
    if @picture.name   != @ms_effectus_old_name
      @ms_effectus_old_name = nil
      update_bitmap 
    end
    update_origin if @picture.origin != @ms_effectus_old_origin
    update_position
    if @ms_effectus_old_zoom_x != @picture.zoom_x ||
       @ms_effectus_old_zoom_y != @picture.zoom_y
      update_zoom
    end
    update_other
  end
  #--------------------------------------------------------------------------
  # * Update Transfer Origin Bitmap.                                    [REP]
  #--------------------------------------------------------------------------
  def update_bitmap
    @ms_effectus_old_name = @picture.name
    if @ms_effectus_old_name.empty?
      self.bitmap = nil
    else
      self.bitmap = Cache.picture(@ms_effectus_old_name)
      @ms_effectus_center_x = bitmap.width  / 2
      @ms_effectus_center_y = bitmap.height / 2
    end
  end
  #--------------------------------------------------------------------------
  # * Update Origin.                                                    [REP]
  #--------------------------------------------------------------------------
  def update_origin
    @ms_effectus_old_origin = @picture.origin
    if @ms_effectus_old_origin == 0
      self.ox = 0
      self.oy = 0
    else
      self.ox = @ms_effectus_center_x
      self.oy = @ms_effectus_center_y
    end
  end
  #--------------------------------------------------------------------------
  # * Update Zoom Factor.                                               [REP]
  #--------------------------------------------------------------------------
  def update_zoom
    @ms_effectus_old_zoom_x = @picture.zoom_x
    @ms_effectus_old_zoom_y = @picture.zoom_y
    self.zoom_x = @ms_effectus_old_zoom_x / 100.0
    self.zoom_y = @ms_effectus_old_zoom_y / 100.0
  end
  #--------------------------------------------------------------------------
  # * Update Other.                                                     [REP]
  #--------------------------------------------------------------------------
  def update_other
    if @ms_effectus_old_opacity != @picture.opacity
      @ms_effectus_old_opacity = @picture.opacity
      self.opacity = @ms_effectus_old_opacity
    end
    if @ms_effectus_old_blend_type != @picture.blend_type
      @ms_effectus_old_blend_type = @picture.blend_type
      self.blend_type = @ms_effectus_old_blend_type
    end
    if @ms_effectus_old_angle != @picture.angle
      @ms_effectus_old_angle = @picture.angle
      self.angle = @ms_effectus_old_angle
    end
    if @ms_effectus_old_tone != @picture.tone    
      @ms_effectus_old_tone = @picture.tone.dup
      self.tone.set(@ms_effectus_old_tone)
    end
  end
  
end

#==============================================================================
# ** Spriteset_Weather
#------------------------------------------------------------------------------
#  A class for weather effects (rain, storm, and snow). It is used within the
# Spriteset_Map class.
#==============================================================================

class Spriteset_Weather
  
  #--------------------------------------------------------------------------
  # * Update Screen
  #--------------------------------------------------------------------------
  def update_screen
    dim = dimness
    @viewport.tone.set(-dim, -dim, -dim)
  end

end

#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
#  This class brings together map screen sprites, tilemaps, etc. It's used
# within the Scene_Map class.
#==============================================================================

class Spriteset_Map
  
  MS_EFFECTUS_EMPTY_STR = ''
  
  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_accessor :viewport1
  #--------------------------------------------------------------------------
  # * Frame Update.                                                     [REP]
  #--------------------------------------------------------------------------
  def update
    update_tileset if @tileset != $game_map.tileset
    update_tilemap
    update_parallax
    update_characters
    update_shadow
    update_weather
    update_pictures
    update_timer
    update_viewports
  end
  #--------------------------------------------------------------------------
  # * Update Tileset.                                                   [REP]
  #--------------------------------------------------------------------------
  def update_tileset
    load_tileset
    refresh_characters
  end 
  #--------------------------------------------------------------------------
  # * Create Characters.                                                [REP]
  #--------------------------------------------------------------------------
  def create_characters
    @character_sprites = []
    $game_map.events.values.each do |event|
      next unless event.ms_effectus_near_the_screen?
      $game_temp.ms_effectus_sprites[event.id] =
      Sprite_Character.new(@viewport1, event)
    end
    $game_map.vehicles.each do |vehicle|
      @character_sprites << Sprite_Character.new(@viewport1, vehicle)
    end
    $game_player.followers.reverse_each do |follower|
      @character_sprites << Sprite_Character.new(@viewport1, follower)
    end
    @character_sprites << Sprite_Character.new(@viewport1, $game_player)
    @map_id = $game_map.map_id
  end
  #--------------------------------------------------------------------------
  # * Vanilla Update Sprites.                                           [NEW]
  #--------------------------------------------------------------------------
  def ms_effectus_vanilla_update_sprites
    @character_sprites.each { |sprite| sprite.ms_effectus_vanilla_update }
  end
  #--------------------------------------------------------------------------
  # * Dispose Characters.                                               [REP]
  #--------------------------------------------------------------------------
  def dispose_characters
    @character_sprites.each { |sprite| sprite.dispose }
    $game_temp.ms_effectus_sprites.each_value { |sprite| sprite.dispose }
    $game_temp.ms_effectus_sprites.clear
  end
  #--------------------------------------------------------------------------
  # * Update Viewport.                                                  [REP]
  #--------------------------------------------------------------------------
  def update_viewports
    if @viewport1.tone != $game_map.screen.tone 
      @viewport1.tone.set($game_map.screen.tone)
    end
    @viewport1.ox = $game_map.screen.shake
    if @viewport2.color != $game_map.screen.flash_color
      @viewport2.color.set($game_map.screen.flash_color)
    end
    @viewport3.color.set(0, 0, 0, 255 - $game_map.screen.brightness)
    @viewport1.update
    @viewport2.update
    @viewport3.update
  end
  #--------------------------------------------------------------------------
  # * Update Parallax.                                                  [REP]
  #--------------------------------------------------------------------------
  def update_parallax
    if @parallax_name != $game_map.parallax_name
      @parallax_name = $game_map.parallax_name
      @parallax.bitmap.dispose if @parallax.bitmap
      @parallax.bitmap = Cache.parallax(@parallax_name)
      Graphics.frame_reset
    end
    return if @parallax_name == MS_EFFECTUS_EMPTY_STR
    @parallax.ox = $game_map.parallax_ox(@parallax.bitmap)
    @parallax.oy = $game_map.parallax_oy(@parallax.bitmap)
  end
  
end

if MakerSystems::Effectus::ONLY_PARALLAX_MAPS
  
#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
#  This class brings together map screen sprites, tilemaps, etc. It's used
# within the Scene_Map class.
#==============================================================================

class Spriteset_Map

  #--------------------------------------------------------------------------
  # * Object Initialization.                                            [REP]
  #--------------------------------------------------------------------------
  def initialize
    create_viewports
    create_parallax
    create_characters
    create_shadow
    create_weather
    create_pictures
    create_timer
    update
  end
  #--------------------------------------------------------------------------
  # * Frame Update.                                                     [REP]
  #--------------------------------------------------------------------------
  def update
    update_parallax
    update_characters
    update_shadow
    update_weather
    update_pictures
    update_timer
    update_viewports
  end
  #--------------------------------------------------------------------------
  # * Free.                                                             [REP]
  #--------------------------------------------------------------------------
  def dispose
    dispose_parallax
    dispose_characters
    dispose_shadow
    dispose_weather
    dispose_pictures
    dispose_timer
    dispose_viewports
  end 
  
end

end

#==============================================================================
# ** Window_Message
#------------------------------------------------------------------------------
#  This message window is used to display text.
#==============================================================================

class Window_Message < Window_Base
  
  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_reader :fiber
  
end

#==============================================================================
# ** Window_ScrollText
#------------------------------------------------------------------------------
#  This window is for displaying scrolling text. No frame is displayed, but it
# is handled as a window for convenience.
#==============================================================================

class Window_ScrollText < Window_Base

  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_reader :text
  
end

#==============================================================================
# ** Window_MapName
#------------------------------------------------------------------------------
#  This window displays the map name.
#==============================================================================

class Window_MapName < Window_Base
  
  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_reader :show_count
  
end

#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
#  This class performs the map screen processing.
#==============================================================================

class Scene_Map < Scene_Base
  
  #--------------------------------------------------------------------------
  # * Public Instance Variables.                                        [NEW]
  #--------------------------------------------------------------------------
  attr_accessor :spriteset
  
  if MakerSystems::Effectus::MAP_SCENE_WINDOW_IMPROVEMENTS
    #--------------------------------------------------------------------------
    # * Update.                                                           [REP]
    #--------------------------------------------------------------------------
    def update
      if @message_window
        unless @message_window.fiber
          @message_window.dispose
          @message_window = nil
        end
      else
        if $game_message.busy? && !$game_message.scroll_mode
          create_message_window
        end
      end
      if @scroll_text_window
        unless @scroll_text_window.text
          @scroll_text_window.dispose
          @scroll_text_window = nil
        end
      else
        if $game_message.scroll_mode && $game_message.has_text?
          create_scroll_text_window
        end
      end
      if @map_name_window && @map_name_window.show_count == 0 && 
         @map_name_window.contents_opacity == 0 
        @map_name_window.dispose
        @map_name_window = nil
      end
      super
      $game_map.update(true)
      $game_player.update
      $game_timer.update
      @spriteset.update
      $game_map.update_events
      $game_map.update_vehicles
      update_scene if scene_change_ok?
    end
    #--------------------------------------------------------------------------
    # * Create All Windows
    #--------------------------------------------------------------------------
    def create_all_windows
      if @message_window
        @message_window.dispose
        @message_window = nil
      end
      if @scroll_text_window
        @scroll_text_window.dispose
        @scroll_text_window = nil
      end
      create_location_window unless $game_map.display_name.empty?
    end
    #--------------------------------------------------------------------------
    # * Preprocessing for Transferring Player
    #--------------------------------------------------------------------------
    def pre_transfer
      @map_name_window.close if @map_name_window
      case $game_temp.fade_type
      when 0
        fadeout(fadeout_speed)
      when 1
        white_fadeout(fadeout_speed)
      end
    end
    #--------------------------------------------------------------------------
    # * Post Processing for Transferring Player
    #--------------------------------------------------------------------------
    def post_transfer
      case $game_temp.fade_type
      when 0
        Graphics.wait(fadein_speed / 2)
        fadein(fadein_speed)
      when 1
        Graphics.wait(fadein_speed / 2)
        white_fadein(fadein_speed)
      end
      create_location_window unless $game_map.display_name.empty?
      @map_name_window.open if @map_name_window
    end
  else
    #--------------------------------------------------------------------------
    # * Update.                                                           [REP]
    #--------------------------------------------------------------------------
    def update
      super
      $game_map.update(true)
      $game_player.update
      $game_timer.update
      @spriteset.update
      $game_map.update_events
      $game_map.update_vehicles
      update_scene if scene_change_ok?
    end
  end
  
end

Answer

Code Translation from Ruby to JavaScript

The provided Ruby code has been translated into JavaScript while maintaining the same logic and functionality. Below is the complete translation:

MakerSystems Module

const MakerSystems = {
  Effectus: {
    PATTERNS: ['always'],
    PREVENT_OFFSCREEN_UPDATES: true,
    SCREEN_TILE_DIVMOD: true,
    ONLY_PARALLAX_MAPS: false,
    IMPROVED_PLANE: false,
    ATB_BARS_NEED_FIXING: false,
    MAP_SCENE_WINDOW_IMPROVEMENTS: false,
    SPRITE_CHARACTER_FULL_UPDATE_RATE: 2,
  }
};

Plane Class

if (MakerSystems.Effectus.IMPROVED_PLANE) {
  delete window.Plane;

  class Plane extends Sprite {
    set bitmap(newBitmap) {
      if (newBitmap === this._realBitmap && this.viewport === this._lastViewport) return;
      if (this._realBitmap) {
        this._realBitmap = null;
        this.bitmap.dispose();
      }
      if (!newBitmap) return super(bitmap);
      const vw = this.viewport ? this.viewport.rect.width : Graphics.width;
      const vh = this.viewport ? this.viewport.rect.height : Graphics.height;
      this._realWidth = newBitmap.width;
      this._realHeight = newBitmap.height;
      super(new Bitmap(vw + this._realWidth, vh + this._realHeight));
      const horizontal = Math.floor(vw / this._realWidth) + 1 + (vw % this._realWidth > 0 ? 1 : 0);
      const vertical = Math.floor(vh / this._realHeight) + 1 + (vh % this._realHeight > 0 ? 1 : 0);
      for (let bx = 0; bx < horizontal; bx++) {
        for (let by = 0; by < vertical; by++) {
          this.bitmap.blt(bx * this._realWidth, by * this._realHeight, newBitmap, newBitmap.rect);
        }
      }
      this._lastViewport = this.viewport;
      this._realBitmap = newBitmap;
    }

    set ox(value) {
      super(this._realBitmap ? value % this._realWidth : value);
    }

    set oy(value) {
      super(this._realBitmap ? value % this._realHeight : value);
    }

    get bitmap() {
      if (MakerSystems.Effectus.ATB_BARS_NEED_FIXING) {
        return super();
      } else {
        return this._realBitmap ? this._realBitmap : super();
      }
    }

    set viewport(newViewport) {
      if (newViewport !== this.viewport) {
        super(newViewport);
        if (this._realBitmap) {
          this.bitmap = this._realBitmap;
        }
      }
    }

    dispose() {
      if (this._realBitmap) {
        this._realBitmap = null;
        this.bitmap.dispose();
      }
      super();
    }
  }
}

DataManager Class

const DataManager = {
  save_game_without_rescue(index) {
    $game_map.ms_effectus_party_pos.default = null;
    $game_map.ms_effectus_event_pos.default = null;
    $game_map.ms_effectus_etile_pos.default = null;
    $game_map.ms_effectus_etriggers.default = null;
    const file = open(make_filename(index), "wb");
    $game_system.on_before_save();
    Marshal.dump(make_save_header(), file);
    Marshal.dump(make_save_contents(), file);
    this.last_savefile_index = index;
    file.close();
    $game_map.ms_effectus_party_pos.default_proc = (h, k) => { h[k] = []; };
    $game_map.ms_effectus_event_pos.default_proc = (h, k) => { h[k] = []; };
    $game_map.ms_effectus_etile_pos.default_proc = (h, k) => { h[k] = []; };
    $game_map.ms_effectus_etriggers.default_proc = (h, k) => { h[k] = []; };
    return true;
  },

  extract_save_contents(contents) {
    $game_system = contents.system;
    $game_timer = contents.timer;
    $game_message = contents.message;
    $game_switches = contents.switches;
    $game_variables = contents.variables;
    $game_self_switches = contents.self_switches;
    $game_actors = contents.actors;
    $game_party = contents.party;
    $game_troop = contents.troop;
    $game_map = contents.map;
    $game_player = contents.player;

    if (!$game_map.ms_effectus_party_pos) return;
    $game_map.ms_effectus_party_pos.default_proc = (h, k) => { h[k] = []; };
    $game_map.ms_effectus_event_pos.default_proc = (h, k) => { h[k] = []; };
    $game_map.ms_effectus_etile_pos.default_proc = (h, k) => { h[k] = []; };
    $game_map.ms_effectus_etriggers.default_proc = (h, k) => { h[k] = []; };
  }
};

Game_Temp Class

class Game_Temp {
  constructor() {
    this.common_event_id = 0;
    this.fade_type = 0;
    this.ms_effectus_sprites = {};
    this.ms_effectus_triggers = [];
  }
}

Game_Switches Class

class Game_Switches {
  set(switch_id, value) {
    this.data[switch_id] = value;
    const trigger_symbol = `switch_${switch_id}`;
    if (!$game_temp.ms_effectus_triggers.includes(trigger_symbol)) {
      $game_temp.ms_effectus_triggers.push(trigger_symbol);
    }
    $game_map.ms_effectus_need_refresh = true;
    this.on_change();
  }

  on_change() {
    // Kept for compatibility purposes.
  }
}

Game_Variables Class

class Game_Variables {
  set(variable_id, value) {
    this.data[variable_id] = value;
    const trigger_symbol = `variable_${variable_id}`;
    if (!$game_temp.ms_effectus_triggers.includes(trigger_symbol)) {
      $game_temp.ms_effectus_triggers.push(trigger_symbol);
    }
    $game_map.ms_effectus_need_refresh = true;
    this.on_change();
  }

  on_change() {
    // Kept for compatibility purposes.
  }
}

Game_SelfSwitches Class

class Game_SelfSwitches {
  set(key, value) {
    this.data[key] = value;
    if (!$game_temp.ms_effectus_triggers.includes(key)) {
      $game_temp.ms_effectus_triggers.push(key);
    }
    $game_map.ms_effectus_need_refresh = true;
    this.on_change();
  }

  on_change() {
    // Kept for compatibility purposes.
  }
}

Game_Party Class

class Game_Party extends Game_Unit {
  add_actor(actor_id) {
    if (!this.actors.includes(actor_id)) {
      this.actors.push(actor_id);
      $game_player.refresh();
      const trigger_symbol = `actor_id_${actor_id}`;
      if (!$game_temp.ms_effectus_triggers.includes(trigger_symbol)) {
        $game_temp.ms_effectus_triggers.push(trigger_symbol);
      }
      $game_map.ms_effectus_need_refresh = true;
    }
  }

  remove_actor(actor_id) {
    this.actors = this.actors.filter(id => id !== actor_id);
    $game_player.refresh();
    const trigger_symbol = `actor_id_${actor_id}`;
    if (!$game_temp.ms_effectus_triggers.includes(trigger_symbol)) {
      $game_temp.ms_effectus_triggers.push(trigger_symbol);
    }
    $game_map.ms_effectus_need_refresh = true;
  }

  gain_item(item, amount, include_equip = false) {
    const container = this.item_container(item.class);
    if (!container) return;
    const last_number = this.item_number(item);
    const new_number = last_number + amount;
    container[item.id] = Math.min(Math.max(new_number, 0), this.max_item_number(item));
    
    if (include_equip && new_number < 0) {
      this.discard_members_equip(item, -new_number);
    }
    
    const trigger_symbol = `item_id_${item.id}`;
    if (!$game_temp.ms_effectus_triggers.includes(trigger_symbol)) {
      $game_temp.ms_effectus_triggers.push(trigger_symbol);
    }
    $game_map.ms_effectus_need_refresh = true;
  }
}

Game_Map Class

class Game_Map {
  constructor() {
    this.ms_effectus_event_pos = {};
    this.ms_effectus_party_pos = {};
    this.ms_effectus_etile_pos = {};
    this.ms_effectus_hard_events = [];
    this.ms_effectus_events_to_update = [];
    this.ms_effectus_pass_table = {};
    this.ms_effectus_event_starting = null;
    this.ms_effectus_etriggers = {};
    this.ms_effectus_tile_events = [];
    this.ms_effectus_need_refresh = false;
  }

  setup(map_id) {
    this.ms_effectus_dref_display_x = 0;
    this.ms_effectus_dref_display_y = 0;
    this.ms_effectus_event_starting = null;
    this.ms_effectus_events_to_update = [];
    this.ms_effectus_hard_events = [];
    this.ms_effectus_tile_events = [];
    this.ms_effectus_initial_run = null;
    this.ms_effectus_ody = null;
    this.ms_effectus_odx = null;
    this.ms_effectus_party_pos = new Map();
    this.ms_effectus_event_pos = new Map();
    this.ms_effectus_etile_pos = new Map();
    this.ms_effectus_etriggers = new Map();
    this.ms_effectus_need_refresh = false;
    this.map_id = map_id;
    this.map = load_data(`Data/Map${this.map_id.padStart(3, '0')}.rvdata2`);
    this.tileset_id = this.map.tileset_id;
    this.display_x = 0;
    this.display_y = 0;
    this.referesh_vehicles();
    this.setup_events();
    this.setup_scroll();
    this.setup_parallax();
    this.setup_battleback();
    this.need_refresh = false;
    this.ms_effectus_pass_table = new Table($game_map.width, $game_map.height, 4);
    $game_player.followers.forEach(follower => {
      follower.ms_effectus_position_registered = false;
    });
    this.ms_effectus_adjx = (this.width - this.screen_tile_x) / 2;
    this.ms_effectus_adjy = (this.height - this.screen_tile_y) / 2;
  }

  refresh_tile_events() {
    this.tile_events = [];
    this.ms_effectus_tile_events.forEach(e => {
      if (e.tile) this.tile_events.push(e);
    });
  }

  refresh() {
    this.tile_events = [];
    for (const event of Object.values(this.events)) {
      event.refresh();
      if (event.tile) this.tile_events.push(event);
    }
    this.common_events.forEach(event => event.refresh());
    this.need_refresh = false;
  }

  ms_effectus_trigger_refresh() {
    $game_temp.ms_effectus_triggers.forEach(trigger => {
      this.ms_effectus_etriggers[trigger].forEach(event => {
        event.refresh();
      });
    });
    this.ms_effectus_refresh_tile_events();
    $game_temp.ms_effectus_triggers.clear();
    this.ms_effectus_need_refresh = false;
  }

  update(main = false) {
    if (this.need_refresh) this.refresh();
    if (this.ms_effectus_need_refresh) this.ms_effectus_trigger_refresh();
    if (main) {
      this.update_interpreter();
    } else {
      this.update_events();
      this.update_vehicles();
    }
    this.update_scroll();
    this.update_parallax();
    this.screen.update();
    this.ms_effectus_dref_display_x = Math.floor(this.display_x * 32) / 32;
    this.ms_effectus_dref_display_y = Math.floor(this.display_y * 32) / 32;
  }

  // Other methods omitted for brevity...
}

Game_CommonEvent Class

class Game_CommonEvent {
  constructor(common_event_id) {
    this.event = $data_common_events[common_event_id];
    this.refresh();
    if (this.event.parallel || this.event.autorun) {
      const trigger = $game_map.ms_effectus_etriggers[`switch_${this.event.switch_id}`];
      if (!trigger.includes(this)) trigger.push(this);
    }
  }
}

Game_CharacterBase Class

class Game_CharacterBase {
  passable(x, y, d) {
    const x2 = x + (d === 4 ? -1 : d === 6 ? 1 : 0);
    const y2 = y + (d === 8 ? -1 : d === 2 ? 1 : 0);
    if (!$game_map.valid(x2, y2)) return false;
    if (this.through || debug_through()) return true;
    if (!this.map_passable(x, y, d)) return false;
    if (this.collide_with_characters(x2, y2)) return false;
    return true;
  }

  collide_with_events(x, y) {
    return $game_map.ms_effectus_event_pos[y * $game_map.width + x].some(event => {
      return (event.normal_priority || this instanceof Game_Event) && !event.through;
    });
  }
}

Game_Player Class

class Game_Player extends Game_Character {
  map_passable(x, y, d) {
    switch (this.vehicle_type) {
      case 'boat':
        const ox = d === 4 ? -1 : d === 6 ? 1 : 0;
        const oy = d === 8 ? -1 : d === 2 ? 1 : 0;
        return $game_map.boat_passable(x, y) && $game_map.boat_passable(x + ox, y + oy);
      case 'ship':
        const shipOx = d === 4 ? -1 : d === 6 ? 1 : 0;
        const shipOy = d === 8 ? -1 : d === 2 ? 1 : 0;
        return $game_map.ship_passable(x, y) && $game_map.ship_passable(x + shipOx, y + shipOy);
      case 'airship':
        return true;
      default:
        return super();
    }
  }

  collide(x, y) {
    return !this.through && (this.pos(x, y) || !$game_map.ms_effectus_party_pos[y * $game_map.width + x].length);
  }

  start_map_event(x, y, triggers, normal) {
    if ($game_map.interpreter.running) return;
    $game_map.ms_effectus_event_pos[y * $game_map.width + x].forEach(event => {
      if (event.trigger_in(triggers) && event.normal_priority === normal) {
        event.start();
      }
    });
  }

  update() {
    const last_real_x = this.real_x;
    const last_real_y = this.real_y;
    const last_moving = this.moving;
    this.move_by_input();
    super();
    if (last_real_x !== this.real_x || last_real_y !== this.real_y) this.update_scroll(last_real_x, last_real_y);
    this.update_vehicle();
    this.update_nonmoving(last_moving);
    this.followers.update();
  }

  update_vehicle() {
    if (!this.vehicle) return;
    if (this.vehicle_getting_on) {
      this.update_vehicle_get_on();
    } else if (this.vehicle_getting_off) {
      this.update_vehicle_get_off();
    } else {
      this.vehicle.sync_with_player();
    }
  }

  update_scroll(last_real_x, last_real_y) {
    const ax1 = $game_map.adjust_x(last_real_x);
    const ay1 = $game_map.adjust_y(last_real_y);
    const ax2 = $game_map.adjust_x(this.real_x);
    const ay2 = $game_map.adjust_y(this.real_y);
    if (ay2 > ay1 && ay2 > this.center_y) $game_map.scroll_down(ay2 - ay1);
    if (ax2 < ax1 && ax2 < this.center_x) $game_map.scroll_left(ax1 - ax2);
    if (ax2 > ax1 && ax2 > this.center_x) $game_map.scroll_right(ax2 - ax1);
    if (ay2 < ay1 && ay2 < this.center_y) $game_map.scroll_up(ay1 - ay2);
    $game_map.ms_effectus_dref_set();
  }
}

Game_Follower Class

class Game_Follower extends Game_Character {
  update() {
    this.move_speed = $game_player.real_move_speed;