Galv’s Character Effects V.2.1

<p><strong>DOWNLOAD DEMO:</strong><br /><a href=”https://www.mediafire.com/download/5z9oo79mu4ps9yt/Character%20Effects%20v.2.1.zip”>Demo – Version 2.1 ></a></p>
<p><strong>SCRIPT:</strong></p>
<pre>

#------------------------------------------------------------------------------#
#  Galv's Character Effects
#------------------------------------------------------------------------------#
#  For: RPGMAKER VX ACE
#  Version 2.1
#------------------------------------------------------------------------------#
#  2014-01-16 - Version 2.1 - Fixed double balloon/animation bug with shadows
#  2013-12-07 - Version 2.0 - Added comments to more easily add event effects
#                           - Fixed shadow facing bug
#  2013-02-24 - Version 1.9 - added z level option for reflection and shadows
#  2013-02-23 - Version 1.8 - added multiple light sources for shadows
#  2013-02-22 - Version 1.7 - bug fixes
#  2013-02-22 - Version 1.6 - added icon effect
#  2013-02-22 - Version 1.5 - fixed mirror bug on large maps
#  2013-02-22 - Version 1.4 - added effects to vehicles
#  2013-02-21 - Version 1.3 - fixed jump reflection and other minor tweaks
#  2013-02-21 - Version 1.2 - bug with less than 4 actors (oops)
#  2013-02-21 - Version 1.1 - updated flicker effect
#  2013-02-21 - Version 1.0 - release
#------------------------------------------------------------------------------#
#  This script was made to provide some additional effects for characters such
#  as events, followers and the player on the map.
#  Currently it includes:
#
#  Shadows
#  Shadows that appear under player and events in a directions depending on
#  a light source that you choose.
#
#  Parallax Reflect
#  Reflections that appear on the parallax layer for events and actors to be
#  used for things like reflections in the water or glass floor etc. To get
#  effects like the demo, you need to edit the charset graphic to make the water
#  partially transparent.
#
#  Parallax Mirrors
#  Much like reflect but are instead actors and event are reflected in a mirror
#  on a wall designated by a region. Both mirror and reflect effects can be
#  changed so actors and events can use different charsets for their reflections
#
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  NEW - First event command as a COMMENT
#------------------------------------------------------------------------------#
#  You can add a comment as the first event command on an event page to set if
#  that event has an icon, shadow or reflection active. The tags to use are
#  below, all must be on the same line in the comment.
#
# <icon:id,x,y>      # set the event to display an icon (x,y position offset)
# <shadow>           # set the event to display a shadow
# <reflect>          # set the event to display reflections
#
#------------------------------------------------------------------------------#
#  EXAMPLE:
# <icon:1,0,0><shadow><reflect>    # to show reflect, shadow and icon 1 on event
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  SCRIPT CALLS:
#------------------------------------------------------------------------------#
#
#  char_effects(x,x,x,status)
#
#------------------------------------------------------------------------------#
#  # each effect can be true or false to enable/disable them during the game.
#  # you can change multiples of effects at once, x being the effect number
#  # 0 = reflect    1 = shadows    2 = mirror    3 = icons
#------------------------------------------------------------------------------#
#  EXAMPLES:
#  char_effects(0,true)              # turn reflections on
#  char_effects(0,2,true)            # turn reflections and mirror on
#  char_effects(1,3,false)           # turn shadows and icons off
#------------------------------------------------------------------------------#
#
#  reflect_sprite(actor_id,filename,pos)    # Change actor's reflect charset
#
#  reflect_esprite(event_id,filename,pos)   # Change event's reflect charset
#
#  reflect_vsprite(vehicle_id,filename,pos) # Change vehicle's reflect charset
#
#------------------------------------------------------------------------------#
#  EXAMPLES:
#  reflect_sprite(1,"Actor2",2)      # change actor 1's charset to use sprite
#                                    # in position 2 of "Actor2" charset.
#  reflect_esprite(3,"Actor4",5)     # event 3 will use sprite in position 5 of
#                                    # "Actor4" charset.
#  reflect_vsprite(1,"Vehicle",5)    # Ship will use sprite in position 5 of
#                                    # "Vehicle" charset.
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  SCRIPT CALLS to turn effects ON or OFF for chosen EVENTS
#------------------------------------------------------------------------------#
#
#  reflect(x,x,x,status)   # status can be true or false to turn on or off
#                          # use this to specify for mirror and reflect.
#  shadow(x,x,x,status)    # where x is the event ids you want to change
#                          # to change all events use :all
#  icon(x,x,x,icon_id)     # set which icon id to appear above character. Make
#                          # it 0 for no icon.
#
#------------------------------------------------------------------------------#
#  EXAMPLES:
#  reflect(14,17,3,1,true) # Turn events 14, 17, 3 and 1 reflections ON
#  shadow(1,false)         # Turn event 1 shadow OFF
#  reflect(:all,true)      # Turn all event reflections ON
#  icon(1,2,3,4,38)        # Events 1,2,3 and 4 will have icon 38 appear
#
#  NOTE: All events will default to NO shadows and NO reflections when entering
#        a map. This is a design decision to try to keep lag to a minimum. You
#        should use these effects sparingly and only activate them on events
#        that require them.
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  SCRIPT CALLS to turn effects ON or OFF for ACTORS and VEHICLES
#------------------------------------------------------------------------------#
#
#  actor_reflect(actor_id,status)  # reflections and shadows are ON by default
#  actor_shadow(actor_id,status)   # for actors and vehicles. Turning them off
#  actor_icon(actor_id,icon_id)    # or on will permanently change them.
#
#  v_reflect(x,x,x,status)    # use these v_ calls for changing vehicle effects
#  v_shadow(x,x,x,status)     # on and off for vehicles.
#  v_icon(x,x,x,icon_id)
#
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  SCRIPT CALLS for shadow options
#------------------------------------------------------------------------------#
#
#  shadow_source(x,y,id)       # set the x,y location for the light. id is the
#                              # light source number you wish to change (for
#                              # more than one). These are reset on map change.
#  shadow_source(event_id,id)  # use an event's x,y location for the light.
#                              # This will need to be in parallel process if you
#                              # want it to be a moving light.
#
#  shadow_options(intensity,fade,flicker)    # descriptions below
#
#    # intensity = opacity when standing next to the light source (255 is black)
#    # fade = amount shadow becomes more transparent the further away you are.
#    # flicker = true or false. Shadows will flicker as if being cast by fire.
#
#------------------------------------------------------------------------------#
#  EXAMPLE:
#  shadow_options(80,10,false)    # This is the default setting.
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  SCRIPT CALLS for reflect options
#------------------------------------------------------------------------------#
#
#  reflect_options(wave_pwr)
#
#    # wave_pwr = how strong the wave movement is. 0 is off
#
#------------------------------------------------------------------------------#
#  EXAMPLE:
#  reflect_options(1) # Turn wave power to 1
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  NOTETAG for ACTORS
#------------------------------------------------------------------------------#
#
#  <no_reflect>    # Actor will not have a reflection (for vampires of course!)
#
#  <reflect_sprite: FileName,pos>  # Actor will use this charset for reflections
#                                  # and use the character in position 'pos'
#
#------------------------------------------------------------------------------#
#  EXAMPLES:
#  <reflect_sprite: Actor2,0>    # The first character from Actor2 charset
#  <reflect_sprite: Actor3,7>    # The last character from Actor2 charset
#------------------------------------------------------------------------------#

($imported ||= {})["Galv_Character_Effects"] = true
module Galv_CEffects

#------------------------------------------------------------------------------#
#  SETUP OPTIONS
#------------------------------------------------------------------------------#

  MIRROR_REGION = 1     # Region ID used to determine mirror walls. Paint the
                        # region on the wall you want to make reflective (and
                        # then use tiles/mapping that make the parallax visible)

  ICON_OFFSET = -60     # Y offset for icons that are displayed above characters

  REFLECT_Z = -10       # Z level of reflections
  SHADOW_Z = 0          # Z level of shadows

#------------------------------------------------------------------------------#
#  END SETUP OPTIONS
#------------------------------------------------------------------------------#
end

class Game_Map
  def do_icons(refresh = true)
    @events.values.each { |e|
      next if !e.list
      if e.list[0].code == 108 && e.list[0].parameters[0] =~ /<icon:(.*),(.*),(.*)>/
        e.icon = $1.to_i
        e.icon_offset = [$2.to_i,$3.to_i]
      else
        e.icon = 0
        e.icon_offset = [0,0]
      end
    }
    SceneManager.scene.spriteset.refresh_effects if refresh
  end

  def do_shadows(refresh = true)
    @events.values.each { |e|
      next if !e.list
      if e.list[0].code == 108 && e.list[0].parameters[0] =~ /<shadow>/
        e.shadow = true
      else
        e.shadow = false
      end
    }
    SceneManager.scene.spriteset.refresh_effects if refresh
  end

  def do_reflects(refresh = true)
    @events.values.each { |e|
      next if !e.list
      if e.list[0].code == 108 && e.list[0].parameters[0] =~ /<reflect>/
        e.reflect = true
      else
        e.reflect = false
      end
    }
    SceneManager.scene.spriteset.refresh_effects if refresh
  end

  def do_all_chareffects
    do_icons(false)
    do_shadows(false)
    do_reflects(false)
  end

end # Game_Map

class Game_Interpreter

  def remove_icon
    icon(@event_id,0)
  end

#-----------------------------------#
#  REFLECTIONS
#-----------------------------------#

  # Add/Remove Reflections from selected events
  def reflect(*args,status)
    char_ids = [*args]
    if char_ids == [:all]
      $game_map.events.values.each { |e| e.reflect = status }
    else
      char_ids.each {|c| $game_map.events[c].reflect = status }
    end
    SceneManager.scene.spriteset.refresh_effects
  end

  # Change forever actor's reflect status
  def actor_reflect(actor_id,status)
    $game_actors[actor_id].reflect = status
    $game_player.refresh
  end

  # Change forever vehicle's reflect status
  def v_reflect(*args,status)
    char_ids = [*args]
    if char_ids == [:all]
      $game_map.vehicles.each { |v| v.reflect = status }
    else
      char_ids.each { |v| $game_map.vehicles[v].reflect = status }
    end
    SceneManager.scene.spriteset.refresh_effects
  end

  def reflect_options(*args)
    $game_map.reflect_options = [*args]
    SceneManager.scene.spriteset.refresh_effects
  end

  # Actor reflect sprite change
  def reflect_sprite(actor_id,filename,pos)
    $game_actors[actor_id].reflect_sprite = [filename,pos]
    $game_player.refresh
  end

  # Event reflect sprite change
  def reflect_esprite(event_id,filename,pos)
    $game_map.events[event_id].reflect_sprite = [filename,pos]
    $game_map.events[event_id].reflect = true
    SceneManager.scene.spriteset.refresh_characters
  end

  # Vehicle reflect sprite change
  def reflect_vsprite(v_id,filename,pos)
    $game_map.vehicles[v_id].reflect_sprite = [filename,pos]
    SceneManager.scene.spriteset.refresh_characters
  end

#-----------------------------------#
#  SHADOWS
#-----------------------------------#

  # Add/Remove Shadows from selected characters
  def shadow(*args,status)
    char_ids = [*args]
    if char_ids == [:all]
      $game_map.events.values.each { |e| e.shadow = status }
    else
      char_ids.each {|c| $game_map.events[c].shadow = status }
    end
    SceneManager.scene.spriteset.refresh_effects
  end

  # Change player and follower shadows
  def actor_shadows(status)
    $game_player.shadow = status
    $game_player.followers.each { |f| f.shadow = status }
    SceneManager.scene.spriteset.refresh_effects
  end

  # Change vehicle's shadow status
  def v_shadow(*args,status)
    char_ids = [*args]
    if char_ids == [:all]
      $game_map.vehicles.each { |v| v.shadow = status }
    else
      char_ids.each { |v| $game_map.vehicles[v].shadow = status }
    end
    SceneManager.scene.spriteset.refresh_effects
  end

  def shadow_options(*args)
    $game_map.shadow_options = [*args]
    SceneManager.scene.spriteset.refresh_effects
  end

  def shadow_source(*args,shad_id)
    shadsource = [*args]

    if shadsource.count == 1
      $game_map.light_source[shad_id] = [$game_map.events[shadsource[0]].real_x,
        $game_map.events[shadsource[0]].real_y]
    elsif shadsource.count > 1
      $game_map.light_source[shad_id] = shadsource
    else
      $game_map.light_source = []
    end
  end

#-----------------------------------#
#  ICONS
#-----------------------------------#

  # Add/Remove Icons from selected events
  def icon(*args,icon_id)
    char_ids = [*args]
    if char_ids == [:all]
      $game_map.events.values.each { |e|
      if e.icon <= 0
        e.icon = nil
      else
        e.icon = icon_id
      end
    }
    else
      char_ids.each {|c| $game_map.events[c].icon = icon_id }
    end
    SceneManager.scene.spriteset.refresh_effects
  end

  # Change forever actor's icon
  def actor_icon(actor_id,icon_id)
    $game_actors[actor_id].icon = icon_id
    $game_player.refresh
  end

  # Change forever vehicle's icon
  def v_icon(*args,icon_id)
    char_ids = [*args]
    if char_ids == [:all]
      $game_map.vehicles.each { |v| v.icon = icon_id }
    else
      char_ids.each { |v| $game_map.vehicles[v].icon = icon_id }
    end
    SceneManager.scene.spriteset.refresh_effects
  end

#-----------------------------------#
#  GENERAL
#-----------------------------------#

  # Turn on/off effects
    # 0 = reflect
    # 1 = shadow
    # 2 = mirror
    # 3 = icon

  def char_effects(*args,status)
    [*args].each { |e| $game_map.char_effects[e] = status }
    SceneManager.scene.spriteset.refresh_effects
  end

end # Game_Interpreter

#-------------------------------------------------------------------------------
#  Spriteset_Map
#-------------------------------------------------------------------------------

class Spriteset_Map
  alias galv_reflect_sm_initialize initialize
  def initialize
    create_effects
    galv_reflect_sm_initialize
    refresh_characters
  end

  alias galv_reflect_sm_refresh_characters refresh_characters
  def refresh_characters
    galv_reflect_sm_refresh_characters
    create_effects
  end

  def refresh_effects
    dispose_effects
    create_effects
  end

  def create_effects
    @shadow_sprites = []
    @reflect_sprites = []
    @mirror_sprites = []
    @icon_sprites = []

    # Do reflections
    if $game_map.char_effects[0]
      $game_map.events.values.each { |e|
        @reflect_sprites.push(Sprite_Reflect.new(@viewport1, e)) if e.reflect
      }
      $game_player.followers.each { |f|
        @reflect_sprites.push(Sprite_Reflect.new(@viewport1, f)) if f.reflect
      }
      if $game_player.reflect
        @reflect_sprites.push(Sprite_Reflect.new(@viewport1, $game_player))
      end
      $game_map.vehicles.each { |v|
        @reflect_sprites.push(Sprite_Reflect.new(@viewport1, v)) if v.reflect
      }
    end

    # Do mirrors
    if $game_map.char_effects[2]
      $game_map.events.values.each { |e|
        @mirror_sprites.push(Sprite_Mirror.new(@viewport1, e)) if e.reflect
      }
      $game_player.followers.each { |f|
        @mirror_sprites.push(Sprite_Mirror.new(@viewport1, f)) if f.reflect
      }
      if $game_player.reflect
        @mirror_sprites.push(Sprite_Mirror.new(@viewport1, $game_player))
      end
      $game_map.vehicles.each { |v|
        @mirror_sprites.push(Sprite_Mirror.new(@viewport1, v)) if v.reflect
      }
    end

    # Do Shadows
    if $game_map.char_effects[1]
      return if $game_map.light_source.empty?
      $game_map.light_source.count.times { |s|
        $game_map.events.values.each { |e|
          @shadow_sprites.push(Sprite_Shadow.new(@viewport1, e, s)) if e.shadow
        }
        $game_player.followers.each { |f|
          @shadow_sprites.push(Sprite_Shadow.new(@viewport1, f, s)) if f.shadow
        }
        if $game_player.shadow
          @shadow_sprites.push(Sprite_Shadow.new(@viewport1, $game_player, s))
        end
        $game_map.vehicles.each { |v|
          @shadow_sprites.push(Sprite_Shadow.new(@viewport1, v, s)) if v.shadow
        }
      }
    end

    # Do icons
    if $game_map.char_effects[3]
      $game_map.events.values.each { |e|
        @icon_sprites.push(Sprite_Icon.new(@viewport1, e)) if e.icon
      }
      $game_player.followers.each { |f|
        @icon_sprites.push(Sprite_Icon.new(@viewport1, f)) if f.icon
      }
      if $game_player.icon
        @icon_sprites.push(Sprite_Icon.new(@viewport1, $game_player))
      end
      $game_map.vehicles.each { |v|
        @icon_sprites.push(Sprite_Icon.new(@viewport1, v)) if v.icon
      }
    end
  end

  alias galv_reflect_sm_update update
  def update
    galv_reflect_sm_update
    @reflect_sprites.each {|s| s.update} if $game_map.char_effects[0]
    @mirror_sprites.each {|s| s.update} if $game_map.char_effects[2]
    @shadow_sprites.each {|s| s.update} if $game_map.char_effects[1]
    @icon_sprites.each {|s| s.update} if $game_map.char_effects[3]
  end

  alias galv_reflect_sm_dispose_characters dispose_characters
  def dispose_characters
    galv_reflect_sm_dispose_characters
    dispose_effects
  end

  def dispose_effects
    @reflect_sprites.each {|s| s.dispose}
    @shadow_sprites.each {|s| s.dispose}
    @mirror_sprites.each {|s| s.dispose}
    @icon_sprites.each {|s| s.dispose}
  end
end # Spriteset_Map

#-------------------------------------------------------------------------------
#  Sprite_Reflect
#-------------------------------------------------------------------------------

class Sprite_Reflect < Sprite_Character
  def initialize(viewport, character = nil)
    super(viewport, character)
  end

  def update
    super
  end

  def update_balloon; end
  def setup_new_effect; end

  def set_character_bitmap
    if @character.reflect_sprite
      self.bitmap = Cache.character(@character.reflect_sprite[0])
    else
      self.bitmap = Cache.character(@character_name)
    end
    self.mirror = true
    self.angle = 180
    self.opacity = 220
    self.z = Galv_CEffects::REFLECT_Z
    self.wave_amp = $game_map.reflect_options[0]

    sign = @character_name[/^[\!\$]./]
    if sign && sign.include?('
)
      @cw = bitmap.width / 3
      @ch = bitmap.height / 4
    else
      @cw = bitmap.width / 12
      @ch = bitmap.height / 8
    end
    self.ox = @cw / 2
    self.oy = @ch
  end

  def update_position
    self.x = @character.screen_x
    jump = @character.jumping? ? @character.jump_height * 2 : 0
    alt = @character.altitude ? @character.altitude * 2 : 0
    self.y = @character.screen_y - 3 + jump + alt
  end

  def update_other
    self.blend_type = @character.blend_type
    self.visible = !@character.transparent
  end

  def update_src_rect
    if @character.reflect_sprite
      index = @character.reflect_sprite[1]
    else
      index = @character.character_index
    end
    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
end # Sprite_Reflect < Sprite_Character

#-------------------------------------------------------------------------------
#  Sprite_Mirror
#-------------------------------------------------------------------------------

class Sprite_Mirror < Sprite_Character
  def initialize(viewport, character = nil)
    @distance = 0
    super(viewport, character)
  end

  def update
    super
  end

  def update_balloon; end
  def setup_new_effect; end

  def set_character_bitmap
    if @character.reflect_sprite
      self.bitmap = Cache.character(@character.reflect_sprite[0])
    else
      self.bitmap = Cache.character(@character_name)
    end
    self.mirror = true
    self.opacity = 255
    self.z = Galv_CEffects::REFLECT_Z

    sign = @character_name[/^[\!\$]./]
    if sign && sign.include?('
)
      @cw = bitmap.width / 3
      @ch = bitmap.height / 4
    else
      @cw = bitmap.width / 12
      @ch = bitmap.height / 8
    end
    self.ox = @cw / 2
    self.oy = @ch
  end

  def update_src_rect
    if @character.reflect_sprite
      index = @character.reflect_sprite[1]
    else
      index = @character.character_index
    end
    pattern = @character.pattern < 3 ? @character.pattern : 1
    sx = (index % 4 * 3 + pattern) * @cw
    sy = (index / 4 * 4 + (10 - @character.direction - 2) / 2) * @ch
    self.src_rect.set(sx, sy, @cw, @ch)
  end

  def get_mirror_y
    20.times {|i|
      if $game_map.region_id(@character.x, @character.y - i) == Galv_CEffects::MIRROR_REGION
        @distance = (i - 1) * 0.05
        @display = @character.y - i - $game_map.display_y + $game_map.height
        self.opacity = 255
        return (@character.y - i + 1 - $game_map.display_y) * 32 - i * 4
      end
    }
    self.opacity = 0
    return @ch
  end

  def update_position
    self.x = @character.screen_x
    self.y = get_mirror_y - 6
    self.zoom_x = 1 - @distance
    self.zoom_y = 1 - @distance
  end

  def update_other
    self.blend_type = @character.blend_type
    self.visible = !@character.transparent
  end
end # Sprite_Mirror < Sprite_Character

#-------------------------------------------------------------------------------
#  Sprite_Shadow
#-------------------------------------------------------------------------------

class Sprite_Shadow < Sprite_Character
  def initialize(viewport, character = nil, source)
    @flicker = 0
    @famount = 0
    @aamount = 0
    @source = source
    super(viewport, character)
  end

  def update_balloon; end
  def setup_new_effect; end

  def update
    super
    update_bitmap
    update_src_rect
    update_position
    update_other
    update_facing
  end

  def set_character_bitmap
    self.bitmap = Cache.character(@character_name)

    self.color = Color.new(0, 0, 0, 255)
    self.z = Galv_CEffects::SHADOW_Z
    self.wave_amp = 1 if $game_map.shadow_options[2]
    self.wave_speed = 1000

    sign = @character_name[/^[\!\$]./]
    if sign && sign.include?('
)
      @cw = bitmap.width / 3
      @ch = bitmap.height / 4
    else
      @cw = bitmap.width / 12
      @ch = bitmap.height / 8
    end
    self.ox = @cw / 2
    self.oy = @ch
  end

  def update_position
    self.x = @character.screen_x
    self.y = @character.screen_y - 10
    get_angle
  end

  def get_angle
    x = $game_map.light_source[@source][0] - @character.real_x
    y = $game_map.light_source[@source][1] - @character.real_y
    self.opacity = $game_map.shadow_options[0] -
      Math::sqrt(x * x + y * y) * $game_map.shadow_options[1]

    if x == 0 && y == 0 || self.opacity <= 0
      self.opacity = 0
    else
      self.angle = Math::atan2(x, y) * 180 / Math::PI + @aamount
    end
  end

  def update_facing
    if @character.y < $game_map.light_source[@source][1]
      self.mirror = false
    else
      self.mirror = true
    end
  end

  def update_other
    self.blend_type = @character.blend_type
    self.visible = !@character.transparent
  end
end # Sprite_Shadow < Sprite_Character

#-------------------------------------------------------------------------------
#  Sprite_Icon
#-------------------------------------------------------------------------------

class Sprite_Icon < Sprite_Character
  def initialize(viewport, character = nil)
    @icon_sprite ||= Sprite.new
    @icon_sprite.bitmap ||= Cache.system("Iconset")
    @icon = nil
    super(viewport, character)
  end

  def dispose
    super
    if @icon_sprite
      @icon_sprite.dispose
      @icon_sprite = nil
    end
  end

  def update
    super
    update_icon
  end

  def update_icon
    return if !@character.icon
    draw_icon(@character.icon)
  end

  def draw_icon(icon_index)
    return if !@icon.nil?
    rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
    @icon_sprite.src_rect  = rect
    @icon = icon_index
  end

  def update_position
    @icon_sprite.x = @character.screen_x - 12
    @icon_sprite.y = @character.screen_y + Galv_CEffects::ICON_OFFSET
  end

  def update_other
    self.blend_type = @character.blend_type
    @icon_sprite.visible = !@character.transparent
  end
end # Sprite_Icon < Sprite_Character

#-------------------------------------------------------------------------------
#  Other Stuff
#-------------------------------------------------------------------------------

class Game_Character < Game_CharacterBase
  attr_reader    :altitude
  attr_accessor  :reflect
  attr_accessor  :reflect_sprite
  attr_accessor  :shadow
  attr_accessor  :icon
  attr_accessor  :icon_offset
end

class Game_Event < Game_Character
  alias galv_reflect_ge_initialize initialize
  def initialize(map_id, event)
    @reflect = false
    @shadow = false
    @icon_offset = [0,0]
    galv_reflect_ge_initialize(map_id, event)
  end
end # Game_Event < Game_Character

class Game_Vehicle < Game_Character
  attr_reader :map_id

  alias galv_reflect_gv_initialize initialize
  def initialize(type)
    @reflect = true
    @shadow = true
    @icon_offset = [0,0]
    galv_reflect_gv_initialize(type)
  end
end # Game_Vehicle < Game_Character

class Game_Follower < Game_Character
  alias galv_reflect_gf_initialize initialize
  def initialize(member_index, preceding_character)
    galv_reflect_gf_initialize(member_index, preceding_character)
    @reflect = true
    @shadow = true
  end

  alias galv_reflect_gf_refresh refresh
  def refresh
    galv_reflect_gf_refresh
    return if actor.nil?
    @reflect = actor.reflect
    @reflect_sprite = actor.reflect_sprite
    @icon = actor.icon
    if SceneManager.scene_is?(Scene_Map)
      SceneManager.scene.spriteset.refresh_effects
    end
  end
end # Game_Follower < Game_Character

class Game_Player < Game_Character
  alias galv_reflect_gp_initialize initialize
  def initialize
    galv_reflect_gp_initialize
    @reflect = true
    @shadow = true
  end

  alias galv_reflect_gp_refresh refresh
  def refresh
    galv_reflect_gp_refresh
    @reflect = actor.reflect
    @reflect_sprite = actor.reflect_sprite
    @icon = actor.icon
    if SceneManager.scene_is?(Scene_Map)
      SceneManager.scene.spriteset.refresh_effects
    end
  end
end # Game_Player < Game_Character

class Scene_Map < Scene_Base
  attr_accessor :spriteset
end # Scene_Map

class Game_Map
  attr_accessor :char_effects
  attr_accessor :light_source
  attr_accessor :shadow_options
  attr_accessor :reflect_options

  alias galv_reflect_game_map_initialize initialize
  def initialize
    @light_source = []
    @shadow_options = [80,10,false]
    @reflect_options = [0]
    @char_effects = [false,false,false,false]
    #[reflect,shadow,mirror,icon]
    galv_reflect_game_map_initialize
  end

  alias galv_reflect_game_map_setup setup
  def setup(map_id)
    galv_reflect_game_map_setup(map_id)
    reset_char_effects
    do_all_chareffects
    if SceneManager.scene_is?(Scene_Map)
      SceneManager.scene.spriteset.refresh_effects
    end
  end

  def reset_char_effects
    @light_source = []
    @events.values.each { |e|
      e.reflect = false
      e.icon = nil }
  end
end # Game_Map

class Game_Actor < Game_Battler
  attr_accessor :reflect
  attr_accessor :reflect_sprite
  attr_accessor :icon

  alias galv_reflect_game_actor_initialize initialize
  def initialize(actor_id)
    galv_reflect_game_actor_initialize(actor_id)
    @reflect = $data_actors[actor_id].reflect
    @reflect_sprite = $data_actors[actor_id].reflect_sprite
    @icon_offset = [0,0]
  end
end # Game_Actor < Game_Battler

class RPG::Actor
  def reflect_sprite
    if @reflect_sprite.nil?
      if @note =~ /<reflect_sprite:[ ](.*),(.*)>/i
        @reflect_sprite = [$1.to_s,$2.to_i]
      else
        @reflect_sprite = nil
      end
    end
    @reflect_sprite
  end
  def reflect
    if @reflect.nil?
      if @note =~ /<no_reflect>/i
        @reflect = false
      else
        @reflect = true
      end
    end
    @reflect
  end
end # RPG::Actor

</pre>

101 thoughts on “Galv’s Character Effects V.2.1

  1. Dennis says:

    This is so cool, thanks.

  2. CrunchyPelvis says:

    …and with this you got yourself another fan :)
    Been looking for a shadow/reflection script for a long time, and you got ’em both in one place, yay! ^^
    I just love people who not only bring awesome functionality to the table but care for the aesthetic part of the system too (I’m referring to your latest “Magic Shards” system – ‘was blown away).
    Just a suggestion: How about you add a “Sun” option (A.K.A a constant light source that won’t change opacity/angle regardless of player’s position on map), there was this script for VX that had this option so I thought it would be useful if your script had it too ^^ (also, I didn’t have time to check out all functions of your script so I’m sorry if this is already possible, but at first glance I didn’t seen anything like that in it). Keep up the great work maestro!

    • Galv says:

      That’s not currently possible in the script, but it is a pretty good idea. I’ll add in it when I have some time one day :)

      • OceanShark says:

        I can’t use V1.9, the older versions works fine though.
        “Script’Galv’s Character Effects 1.9′ line 285: SyntaxError occured.
        unexpecter ‘]’, expecting keyword_end
        $game_map.events1].real_y]”
        It would be great if you could help me out, thanks!
        Great script by the way.

      • Galv says:

        Thanks for letting me know. Some certain code on the page was being re-written when I pasted it there. I fixed that issue and also uploaded the latest version in the demo just in case.

  3. junior Molina says:

    As I can select the tilesets as reflected in the water?

    • Galv says:

      I’m not sure what you are asking there. The lower reflection works by drawing the character reflections over the parallax layer. To see the reflection in tilesets, you need some graphics knowledge and make the water in the tilesets partially transparent so you can see it below.

      I believe there is a more user-friendly that’s more advanced in adding reflections above tiles somewhere.

  4. junior Molina says:

    my question is, how I can add reflections to other tilesets?

    • Galv says:

      The answer to your question is in my last reply to your comment… and in the script header… and on the script page of this blog that has a screenshot and description of what the script does.

      The reflections are drawn on top of the parallax image – meaning, you will need some basic skills such as using a graphics program to make water tiles partially transparent or using parallax mapping. The reflections can be seen because they are beneath the tileset water… and the tileset water was made partially transparent – giving the illusion of the reflection being in the water.

      If you do not have those skills or do not know what I mean, then you might consider looking for another reflection script, I have seen one that looked to apply the reflection above the tileset.

  5. junior Molina says:

    Hooo . I see, thanks friend!

  6. OceanShark says:

    Just another little note, this script isn’t compatible with Victor Engine’s Diagonal Movement, it’s not a really big problem but if there could be a patch/fix that would be awesome, Thank you!

    • Galv says:

      I just did a quick test with Victor’s script and it indeed does crash when moving diagonally in an area with shadows on. I might look into it one day, but probably not, sorry. It works fine with other diagonal movement scripts (that don’t change the diagonal charset) I have tried, though.

  7. Marcos Luna says:

    Cool,i love this script Galv. Thanks you very much for your hard work,just a little sugestion. It is possible to make some events not afected by screen tone changes?

    • Galv says:

      I think I saw another script that did that floating around but cannot find it again. But it won’t be possible with this script, sorry

      • Marcos Luna says:

        No problem… Thanks for your fast response.
        Yes,three Is a script that does that,created by a Japanese scripter named Cwinter. But it has a few bugs and i dont know how to contact him… Excuse me for my bad English and greetings from Argentina.

  8. zebtal says:

    (It seems that the post aren’t be posted so i repost here, sorry for double post. And so It’s the “previous” post)

    Hello,

    First thank you for this script. I search for a long time a good script like this … a long long time …

    I have juste an error with your script : “undefined method ‘spriteset’ for #”

    I’m a noob in rgss3 scripting, but i tried to run my game without your script and the error disappeared. The scene itembank is from your script of item bank. I’ve the same error with Scene_Shop and the scene is from your script of shop update too.

    When the character effects script is off, there is no error, when is on, Scene_shop and scene_itembank are down.

    Any ideas?

    Hope you can help me …

    • Galv says:

      You posts didn’t appear because I have to approve them first – else I get spam.
      This error makes me think the script wasn’t copied fully, another script is conflicting or you made a mistake in one of the script calls. You might need to run some tests yourself to discover this.
      Copy the script from the demo to be sure you get it all

      • zebtal says:

        Nope the script was copied in the good way, it’s not a copy/paste error. Maybe conflict With Victor’s engine animated battler (I discover his scripts before yours, so I use it, because I’ve made many configuration for this script can run for my game) because it rewrite many sprite classes (but once Again I’m a noob in RGSS3 so I could be wrong). It’s not script call error because I verify them again and again.

        The error appears only if i use (on parallel process) something like shadow(:All,true) or reflect(:all,true) or if I switch on effects on the event where the script call to the custom scene is ( With somthing like reflect(event_with_script_call_id,true) )

        So I set effect for events one by one and don’t include script call events (because your script is very wonderful and I Want to use it).

        Oh and I put the script over all other scripts between materials and main. I don’t Know if it’s important but, if it could help someone else…

        But I don’t find more on this error.

        Thank you for your fast answer and sorry for the spam. Hope you’ll continue to make wonderful scripts for VX Ace :)

  9. Hairomi says:

    amazing!!! XD

  10. ThunderKitty says:

    omg the demo was so cool XD

  11. ThunderKitty says:

    So I tried it out and I got an error message “Script ‘Galv’s Character Effects’ line 801: NoMethodError occurred. undefined method ‘reflect’ for nil:NilClass”, help??

    • Galv says:

      I think I made this script too complicated, I even mess up myself using it haha.

      Okay not sure why this is happening yet, though. Did you start a new test game after adding the script?

      • ThunderKitty says:

        New test game? like a new project? If that’s the case no haha I add it onto my current game (though I had just started it)

      • Galv says:

        Not a new project, a new playtest of your current project :)

      • Sylevar says:

        I too have this problem except that mine says line 890.. I have compared just about everything I can between the demo and my game but to no avail. Yes, I’m starting a new test game after adding the script.. (made that mistake with your fishing one, not doing it again)

        Read further down, noticed you asking someone to try to duplicate another error in a brand new test file.. attempted this and did not have this problem. Therefore it has to be something with my game but I do not understand what I am doing wrong.

        Will continue to work on it myself, but please let me know when you can..

      • Sylevar says:

        FIGURED IT OUT!!!!

        Because my game starts without an actor in the active party selected (because I have a cut scene starting my game), it’s saying “Hey.. I can’t reflect something that isn’t there!!!” Maybe this will help the other person out too.. if they read this!

  12. EvilHero says:

    Im running into a script conflict with your character effects script and : CACAO’s Start map which can be find

    http://translate.googleusercontent.com/translate_c?depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=en&u=http://cacaosoft.web.fc2.com/tkool/script/rgss3/cao_sp.html&usg=ALkJrhjqhYlCjgLrB_KMXR0wU1utRgZyPA

    The script error im getting is “line 801: No Method Error occurred. undefined method `reflect’ for nil:NilClass”

    I am probably using your script wrong because it seemed to work without using CACAO’s script

    • Galv says:

      I’m currently very busy at the moment so not sure when I’ll have time to look into this.

    • Sylevar says:

      I got the same error dude.. though the line was different but that only accounts for the updates and stuff.. make sure the CACAO’s Start Map doesn’t make it where your starting actor is nil. You have to have an actor in the slot or you will get this error. What I did was made an NPC an actor and just used that but you can also pro’lly assign an actor and just not give him a sprite.. don’t know.. didn’t try that. Hope this helps ya out though!

  13. Drbigt says:

    When I try and start a test play with this in my project I get

    “Script ‘Character effects’ line 894; NoMethodError occured.

    Undefined method ‘refresh_effects’ for nil:NilClass”

    • Galv says:

      Hmm interesting. Apparently your map doesn’t haven’t a spriteset.
      Did you start a new game? Did you test for script conflicts?

      • Drbigt says:

        Yes, my map is a corridor with only the actor being the one who’s being reflected and the other things (such as teleport) are designed as no shade.

      • Galv says:

        Make sure you have the latest script. If so, can you duplicate this error in a new project? If so, can you please send me that project?

  14. Sylevar says:

    Question for you Mr. Galv..

    Is there a way to set up, through common events or otherwise, a change in reflection based upon good or evil (like an alignment shift)

    For example: Character starts out good but through a series of bad choices, ends up murdering a village. Now this person is “evil” Is there a way to change their reflection without changing the actor or would I have to change the actor to do that…

    • Galv says:

      The script calls to change reflections should be in the script heading. You would event the rest.

      • Draxicor says:

        Hello. I seem to be having some trouble with this script. The mirror reflctions work great to start with, but when I use the script call “reflect_sprite(1,”demon”,1)” to change my actors reflection sprite, the reflection disappears! I even tried putting your Test_sprite.png on my project and testing with it, but the same issue happens. Do you know what could be causing this? Sorry for troubling you!

      • Galv says:

        Try doing some tests. Here’s a checklist that runs through common problems and things to check: https://galvs-scripts.com/errors-using-scripts/

  15. Sekhmet86 says:

    Great script! I did notice that in the event that you show a balloon icon on a map with a shadow source, two separate balloons pop up. Is there any work around with this? Even in the demo, if you put the show balloon icon on one of the events in the shadow test map, two balloons pop up instead of one.

  16. Hi there Galv. After seeing your script in action i wanted to try it out, unfortunately i`m getting this error message:
    line:777 typeerror occured superclass missmatch for class Sprite_Icon I tryied removing all the scripts that i have seen mentioned here as incompatible, is it just script compatibility, or something else?
    Thanks for your time.

  17. Caleb says:

    @Fallen Valkyrie Studio: Hey, thought I’d help you. Just Use CTRL F inside of Script Editor to find every instance of Sprite_Icon. Rename it to something like Sprite_Icom.

    The problem arises because you have another script that has defined Sprite_Icon in a different way. I had the same problem. :)

  18. chris says:

    hi awesome script, I love the way the reflection is on the parallax layer because bye using the right parallax and making the water transparent enough you can get some amazing water effects :D

    I do have one question, Is it possible to turn off shadows for individual light sources? I am using zeus lighting effects script along side yours and would like to be able to turn individual “tourches” off or on, However the only way I found I could do this is to change the shadow options so that the intensity was 0, But this changes the option for all the light sources, So if I turn one light off I loose the shadows on the ones that are still on.

    Is there anyway you can think of that I an do this?? or is it a case of the script doesn’t do this ??

    your help would be greatly appreciated

    thankyou

    • Galv says:

      Unfortunately I didn’t think to add a way to remove light sources. I’m going to definitely add these feature one day when I have time, I just don’t have time at the moment currently I’m afraid. Too busy

  19. “Script ‘Character effects’ line 894; NoMethodError occured.

    Undefined method ‘refresh_effects’ for nil:NilClass”
    D:

    • Galv says:

      Please provide more details… when does the error occur? For example… when you transfer to a new map… during a certain event…)
      Did you check for script conflicts?
      Did you start a new game?
      Do you have the latest version seeing as the error doesn’t match the latest version line number? :/

      If you want help, you need to give more details, us scripters are not psychic :)

  20. BViVi says:

    Hello there sir. I just downloaded your script and enjoyed the demo. However, when i plugged it into my project. I got an error before i could start the game:
    Script ‘Galv’s Character Effects 2.1′ line 898:NoMethodError occurred.
    undefined method `refresh_effects’ for nil:NilClass.

    So, i went to script editor and line 898 is:
    SceneManager.scene.spriteset.refresh_effects

    I deleted that line and the game runs fine without any errors. However, i found that the reflection feature doesn’t show up for the game actors but has no problem showing all the event reflections; the problem is it doesn’t show the game actor reflection. The mirror feature seems to work fine for both game actors and events, so, the mirror feature is okay. I haven’t tried the other features such as The Display Icon and Shadow features because i’m not using those feature in my project. I am only interested in the Mirror and Reflect feature for this script. So, the script that i found to have an issue with is Schala Battle System V2.0 which i am using at the moment. Please sir help me solve this issue because its really bothering me to find this script working but not the features that i really want =/… My luck just happens to be the worst one in the world and have the feature of the scripts that i like not working aside from the ones that i don’t like =(

  21. BViVi says:

    Oh sorry to catch you in a really busy time, LoL! My luck i tell ya, lol, worst one in the world, lol. THanks for reading the issue though, hope this is on the “To Do List” and i don’t care if means years from now, LoL… ill keep checking for updates from time to time. THanks =)

  22. Sly says:

    Hi, amazing effects Galv. Has some way to make the reflection system work like the mirrors, only in a specific region?
    I want use Panomaps and need of power to select where in the parallax (with regions, like the mirrors system) i want the reflections.

    How i do it?

    Thanks.

  23. RecklessMoron says:

    Hello there, Galv. First off, This script here is really well done! The demo explained everything that it can do. (as well as the risk of lag it can bring with overlighting) I’ll be using it in my project, but unfortunately, when I plug it into my game, the reflections are backwards. The characters are going right but the reflection shows them going left (as if they were moonwalking right). I think it may be because I’m using Mack styled sprites, but I’m otherwise clueless. What can I do to fix this?

    • Galv says:

      Sprite style shouldn’t affect it, it would likely be a conflict with another script. You need to do some tests removing other scripts and testing to see which ones do it.

      Errors Using VX/VX Ace Scripts

      • RecklessMoron says:

        Ah, Thank you very much, Galv! It appears that the problem was caused by a Script Clash like you said. The script “Eventing: Fine Tuning v3.1” was the cause of the problem. It bugs me that I have to remove one of them as they are both really useful to my project.

        Thank you again for your Help!

  24. Akian says:

    I have to said that you’re amazing! i don’t said this cause your script (they’re great, ofc!) but* i said this cause u make me laught every time i see your coments on scripts, photos and other stuff! seems like u’re a non-bad people (lol)
    Sry for my english! nice scripts btw!

  25. CaptainBinary says:

    Hey great script, however i cannot seem to get anything to work.

    I have put the script below materials and above main. In a pushed event (On a cat) i have the event call this script “actor_icon(1,10030)” (10030 is the right icon number, this also does not work with 1 or 2, so icon id range does not seem to be a problem). I also have it call up a sound so i know if the event has triggered.

    When i activate the event, the sound plays but no icon is displayed above the actors head. I have also tried using icon(1,2,3) just for testing and nothing happens.

    I am sure i am doing something really stupid and over looking it. However if anyone on here could give me a hand i would appreciate it.

    Thanks for your time.

    • CaptainBinary says:

      ….. I was just being stupid. Ignore this. For anyone else having a similar problem the solution is: You need to add in a script “char_effects(3,true)” As it states in the header =P

  26. JayBlion says:

    Cool ! That’s what I just want ,I really appreciate it!
    ……But there seems to be some problem for me to understand the script as I’m a beginner . What’s more ,I’m a Chinese high school student ,having graduated recently .My friend and I hope to make a game in honor of my class and my teacher, but with my limited English ability , it’s impossible to read much in this site . What I only want now is the whole project (the example project). The problem is I could hardly download anything abroad as I’m in China(I really hate this ,the damned network of China drives me crazy .) ,so I’m wondering whether you can send me an E-mail with it.
    PS:My E-mail address is bujie314@163.com

  27. JayBlion says:

    That’s all right . Brilliant people are always more busy.

  28. zaenheart says:

    all in the game runs well except one thing. When I try to test a battle it says Scrip ‘Game_Map’ line 202: NoMethodError occurred:undefined method ‘width’ for nil:Nilclass. If someone could help me would be great since I’ve been trying several things.

  29. shironeku says:

    Would it be possible to make it so that a specific class doesn’t have a shadow?

  30. LlNK says:

    I seem to be having problems with the shadowing. My “Player” seems to be casting random shadow behind itself, whenever

    I walk up to an event that I did not ask it to cast from.
    Any Ideas Galv?

  31. Link says:

    I completely understand if your busy…

  32. I love this and it works perfectly with the test game… To note i think the issue is that i am using custom sprites as actors and party members… I get the error NoMethod on 459 undefined ‘[]’ for nil class or something like that… anyways… I do some more experiments with it

  33. Draxicor says:

    I checked everything on the checklist, and everything checks out, but the issue remains. The mirror reflection works perfectly when the game starts. I can even use script calls to turn it on or off. but when I try to change the actor refletion charset, using the reflect_sprite(1,”Actor2″,2) cal the reflections just disapear and i cant even turn them on using the char_effects(2,true) script calls

  34. CM Franz says:

    Just want to let you know that all your scripts are fucking awesome! Please keep on sharing! – a fan. :)

  35. Another Fen says:

    Nice script. :)
    However, one thing that it can cause errors when the script commands are used in the same frame I call the shop window (Undefined method “spriteset” for Scene_Shop)

    • Galv says:

      If you need to, put a wait 1 frame before the two commands. Unfortunately I don’t have time to fix some issues with this one. Thanks for the report, though :)

  36. The Less Intelligent Guy says:

    I’ve tried to look through anything, I’ve also gone through the instructions of the script but are too silly to understand and doesn’t manage to crate any reflection.

    • Galv says:

      It’s not newbie friendly unfortunately. Best I can do is there is a demo download link at the top of this page. Try to copy what was done in it.

  37. Mztivin says:

    I have a problem getting Icons to work.
    I have mirrors and water reflection working great! But when I use “actor_icon(1,11)” nothing happens. In fact any Icon call is a dud. I have icons(3) set true on that map.

    • Galv says:

      Unfortunately the only help I can offer you is the demo. You might have a conflicting script or something – you’ll have to try to find that out

      • Mztivin says:

        Okay! I didn’t even consider a conflicting script. Thank you for replying. Great scripts btw!!

      • Mztivin says:

        Okay lol… so I found the problem.
        Ima say it here encase anyone has the same problem.
        I was using the same event for other parallel processes for another script call (for a clock/time set script). I had to put the “char_effects(x,x,true)” call in its own event entirely.

  38. Discovery says:

    Hello again Galv… So I’m having a huge issue with this script…Anytime I use it, it comes with the error: Script ‘Game_Interpreter’ line 1411: No Method Ocurred. undefined method ‘[]’ for nil:NilClass, is it a bug or a compatibility problem? Does it have a fix?

  39. Panda says:

    This is almost exactly like what I was trying to accomplish for a puzzle. One query though; while the reflections in the mirror are neat and I can see where you’re going with on the sprite shrinking or growing depending on how far away the player is, is it possible to make the mirrors work like the NPC movement? What I mean is if I moved down, the reflection would move up in the mirror. If I then went down again then the reflection would move up off of the mirror entirely, becoming no longer visible.

  40. thelegendofwolf says:

    I love this script and I am happy to be able to use it, as it is really useful!
    However, my game popped up an error message when I used an event with the texture of one of the Tilesets.
    The game crashed when the script tried to create the reflection of the events with the tileset texture.
    Luckily the script contains not only a script call to enable all events, but also a way where you can enable the reflect effect by creating a comment in the event. This way you can select only the events with no tileset texture. And if you still want an event with a tileset texture, then just add a png with the texture in the characters folder.

    I posted this for the slight possibility someone else gets into the same problem.

    Also when combining the reflections and the MoveRouteExtra script, the reflections are still on when the fadeout script is used. Just make sure you also add “Transparent on” to the move route, problem gone.

    Thank you for making these scripts, I enjoy the many possibilities of them!

    Wolf

  41. peddlerenterprisesllc says:

    I tried transferring the script to my game but an error bar saying ” script Galvs Character Effects 2.0 line 459 NoMethodError occurred. Undefined method ‘[ ]’ for nil’NilClass ” . I know this is probably caused by the name change in sprites and events but I’m having trouble finding what needs to be changed in the script. HELP!

    • Galv says:

      Here’s a checklist to try error trapping:

      Errors Using VX/VX Ace Scripts

      Make sure you read the help documentation and study the demo to check what you’ve done against it.

      • peddlerenterprisesllc says:

        Im using RPG Maker VX Ace. Also I think I know where the conflict is coming from. I’m using “Galvs animations 2” so I did have to restart the game for it to work. However I’ve come across a new problem. Is with line 33 in the Script_Base

      • Galv says:

        I don’t know what “Galvs animations 2” is. And unfortunately I cannot help with just a line number – the error trapping checklist I sent you to suggests ways to help you find which plugin might be causing an issue, for example it might be scripts conflicting and you need to discover which ones are.

  42. Itta says:

    …So how do I make it _work_? installing the script, setting up the map, nothing seems to actually reflect in the water, no shadows show up, and the only thing it did was be incompatible with another plugin. (that I didn’t really need, so whatever)

  43. Erviyo says:

    is there any chance that you would port this script to js?

Leave a comment