<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[Save-Point - HiddenChest (RGSS1-3) Engine]]></title>
		<link>https://www.save-point.org/</link>
		<description><![CDATA[Save-Point - https://www.save-point.org]]></description>
		<pubDate>Wed, 29 Apr 2026 16:49:37 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[KChangeKeys HC]]></title>
			<link>https://www.save-point.org/thread-13382.html</link>
			<pubDate>Sat, 10 Jan 2026 11:04:25 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-13382.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KChangeKeys HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b">by Kyonides</span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
Usually, a typical RM game would only let you change your key mappings via pressing the F1 button, and then you would be able to pick a few options for a minimal set of virtual buttons like A or C or R. Later on, mkxp let you set up to 4 different keys for a single target button. These keys can be actual keys or gamepad's buttons or axes or hats. None of those menus look very eye-catching, do they? <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /><br />
<br />
Now KChangeKeys HC for <span style="font-weight: bold;" class="mycode_b">HiddenChest version 1.2.06 or higher</span> is a real game changer. Now you CAN CHANGE your key bindings at will using this relatively simple script! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /> Just keep pressing keys or buttons <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /> to get impressed by it! <img src="https://www.save-point.org/images/smilies/ejlol/thumbs.gif" alt="Two Thumbs Up!" title="Two Thumbs Up!" class="smilie smilie_61" /> <br />
<br />
<div class="tborder">
  			<div class="thead" style="padding:4px; margin:1px;"><input type="button" class="button" value="+" style="font-family:Monospace; padding:0px" onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].style.display=='none'){ this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='';this.value='-';} else {this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='none';this.value='+';}"/> Screenshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<img src="https://i.postimg.cc/K8gtmX1K/kchangekeyshc-xp01.jpg" loading="lazy"  alt="[Image: kchangekeyshc-xp01.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/Sxzcm0n2/kchangekeyshc-xp02.jpg" loading="lazy"  alt="[Image: kchangekeyshc-xp02.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/g263G9xZ/kchangekeyshc-xp1280.jpg" loading="lazy"  alt="[Image: kchangekeyshc-xp1280.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">Script for RMXP</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KChangeKeys HC for XP * #<br />
#   Scripter : Kyonides<br />
#   2026-01-11<br />
<br />
# * This scripts depends on HiddenChest v1.2.06 or higher. * #<br />
<br />
# With this scriptlet you are now able to change the keys that are normally<br />
# mapped to any of RMXP's default buttons like A, B, C, etc. without pressing<br />
# the F1, F2 &amp; F12 buttons!<br />
<br />
# * Script Call * #<br />
# &#36;scene = KChangeKeys::Scene.new<br />
<br />
module KChangeKeys<br />
  BACKDROP = "dwarven mine"<br />
  HELP_BAR = "help bar"<br />
  TARGET_BOX = "target box"<br />
  CURSOR = "cursor"<br />
  HEADING = "Key Bindings"<br />
  CHOOSE_KEY = "Please select a key to edit"<br />
  ENTER_KEY = "Please enter a key now"<br />
# These are the default virtual buttons' names the RM editors have always used,<br />
# but feel free to change them if ever needed.<br />
  TARGETS = %w{Up Down L L2 Left Right R R2 A B C X Y Z}<br />
<br />
class Scene<br />
  def main<br />
    setup<br />
    create_sprites<br />
    Graphics.transition<br />
    while @stage<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def setup<br />
    Font.default_outline = true<br />
    @stage = :main<br />
    @index = 0<br />
    @col_index = 0<br />
    @gamepad = Input.gamepad<br />
    @bindings = Input.bindings<br />
    @list = @bindings.list<br />
    @target_names = []<br />
    @bind_names = []<br />
    @binds = []<br />
    @key_names = []<br />
    @changes = []<br />
    @sprites = []<br />
    case Graphics.width<br />
    when 544<br />
      @rows = 1<br />
    when 640<br />
      @rows = 2<br />
    when 800<br />
      @rows = 3<br />
    else<br />
      @rows = 4<br />
    end<br />
    @list.each {|bg| @binds += bg.data.take(@rows) }<br />
    @key_names = @binds.map {|b| b.name || "" }<br />
    @init_names = @key_names.dup<br />
    @temp_names = @key_names.dup<br />
    @back_color = Color.new(0, 0, 0, 120)<br />
    @target_color = Color.new(255, 200, 80)<br />
  end<br />
<br />
  def create_sprites<br />
    gw = Graphics.width<br />
    fn = BACKDROP + gw.to_s<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = RPG::Cache.title(fn).dup<br />
    b = Bitmap.new(gw, 48)<br />
    b.font.size = 32<br />
    b.draw_text(:rect, HEADING, 1)<br />
    @heading = Sprite.new<br />
    @heading.y = 4<br />
    @heading.bitmap = b<br />
    b = RPG::Cache.picture(HELP_BAR)<br />
    bx = (gw - b.width) / 2<br />
    @help_backdrop = Sprite.new<br />
    @help_backdrop.set_xy(bx, 60)<br />
    @help_backdrop.bitmap = b<br />
    @help_bit = Bitmap.new(gw, 32)<br />
    @help_bit.font.size = 24<br />
    @help_bit.draw_text(:rect, CHOOSE_KEY, 1)<br />
    @help = Sprite.new<br />
    @help.y = 60<br />
    @help.z = 20<br />
    @help.bitmap = @help_bit<br />
    @cursor = Sprite.new<br />
    @cursor.z = 10<br />
    @cursor.bitmap = RPG::Cache.picture(CURSOR)<br />
    sw = gw / 206<br />
    ix = (gw - sw * 206) / 2<br />
    b = RPG::Cache.picture(TARGET_BOX)<br />
    @key_max = TARGETS.size<br />
    @key_max.times do |n|<br />
      sx = ix + n % sw * 206<br />
      sy = 108 + n / sw * @rows * 32<br />
      @backdrop.bitmap.blt(sx + 2, sy - 2, b, b.rect)<br />
      s = Sprite.new<br />
      s.set_xyz(sx, sy, 20)<br />
      s.bitmap = Bitmap.new(80, 28)<br />
      s.bitmap.font.color = @target_color<br />
      s.bitmap.draw_text(:rect, TARGETS[n], 1)<br />
      @target_names &lt;&lt; s<br />
      @rows.times {|i| create_button_box(sx + 84, sy + i * 32) }<br />
    end<br />
    s = @bind_names[0]<br />
    @cursor.set_xy(s.x - 4, s.y - 2)<br />
    b.dispose<br />
    @sprites += @target_names + @bind_names<br />
    @sprites += [@heading, @help, @cursor, @help_backdrop, @backdrop]<br />
  end<br />
<br />
  def create_button_box(sx, sy)<br />
    name = @temp_names.shift<br />
    s = Sprite.new<br />
    s.set_xyz(sx, sy, 20)<br />
    b = Bitmap.new(112, 28)<br />
    b.draw_text(:rect, name, 1)<br />
    s.bitmap = b<br />
    @bind_names &lt;&lt; s<br />
    rect = b.rect.dup<br />
    rect.x = sx<br />
    rect.y = sy<br />
    @backdrop.bitmap.fill_rect(rect, @back_color)<br />
  end<br />
<br />
  def terminate<br />
    @sprites.each do |s|<br />
      s.bitmap.dispose<br />
      s.dispose<br />
    end<br />
    @changes = @changes.flatten.compact<br />
    return if @changes.empty?<br />
    Input.save_key_bindings<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :main<br />
      update_main<br />
    when :key<br />
      update_key<br />
    end<br />
  end<br />
<br />
  def box_index<br />
    @index * @rows + @col_index<br />
  end<br />
<br />
  def update_main<br />
    if Input.trigger?(:B)<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Map.new<br />
      return @stage = nil<br />
    elsif Input.trigger?(:Up)<br />
      update_cursor(0, -1)<br />
      return<br />
    elsif Input.trigger?(:Down)<br />
      update_cursor(0, 1)<br />
      return<br />
    elsif Input.trigger?(:Left)<br />
      update_cursor(-1, 0)<br />
      return<br />
    elsif Input.trigger?(:Right)<br />
      update_cursor(1, 0)<br />
      return<br />
    elsif Input.trigger?(:Delete)<br />
      &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
      n = box_index<br />
      bind = @binds[n]<br />
      bind.value = 0<br />
      @key_names[n] = ""<br />
      b = @bind_names[n].bitmap<br />
      b.clear<br />
      b.draw_text(:rect, "", 1)<br />
      @changes[n] = true<br />
      return<br />
    elsif Input.trigger?(:C)<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      Input.keymap_mode!<br />
      Input.update<br />
      n = box_index<br />
      @bind = @binds[n]<br />
      @help_bit.clear<br />
      @help_bit.draw_text(:rect, ENTER_KEY, 1)<br />
      @bind_bit = @bind_names[n].bitmap<br />
      @bind_bit.clear<br />
      @stage = :key<br />
    end<br />
  end<br />
<br />
  def update_cursor(m, n)<br />
    &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
    @index = (@index + m) % @key_max<br />
    @col_index = (@col_index + n) % @rows<br />
    s = @bind_names[box_index]<br />
    @cursor.set_xy(s.x - 4, s.y - 2)<br />
  end<br />
<br />
  def reset_help<br />
    Input.play_mode!<br />
    Input.update<br />
    @bind_bit = @bind = nil<br />
    @help_bit.clear<br />
    @help_bit.draw_text(:rect, CHOOSE_KEY, 1)<br />
    @stage = :main<br />
  end<br />
<br />
  def update_key<br />
    if Input.trigger?(:MouseRight)<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      name = @key_names[box_index]<br />
      @bind_bit.draw_text(:rect, name, 1)<br />
      reset_help<br />
      return<br />
    elsif Input.trigger_any?<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      case Input.trigger_type<br />
      when 0<br />
        @bind.value = 0<br />
      when 1<br />
        @bind.value = Input.trigger_last<br />
      else<br />
        @bind.value = Input.trigger_gp_value<br />
      end<br />
      n = box_index<br />
      name = @bind.name<br />
      @key_names[n] = name<br />
      @bind_bit.clear<br />
      @bind_bit.draw_text(:rect, name, 1)<br />
      reset_help<br />
      @changes[n] = true<br />
    end<br />
  end<br />
end<br />
<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RMVX &amp; VX ACE</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KChangeKeys HC for VX + ACE * #<br />
#   Scripter : Kyonides<br />
#   2026-01-11<br />
<br />
# * This scripts depends on HiddenChest v1.2.06 or higher. * #<br />
<br />
# With this scriptlet you are now able to change the keys that are normally<br />
# mapped to any of RMXP's default buttons like A, B, C, etc. without pressing<br />
# the F1, F2 &amp; F12 buttons!<br />
<br />
# For VX:<br />
# &#36;scene = KChangeKeys::Scene.new<br />
# For VX ACE:<br />
# SceneManager.call(KChangeKeys::Scene)<br />
<br />
module KChangeKeys<br />
  BACKDROP = "dwarven mine"<br />
  HELP_BAR = "help bar"<br />
  TARGET_BOX = "target box"<br />
  CURSOR = "cursor"<br />
  HEADING = "Key Bindings"<br />
  CHOOSE_KEY = "Please select a key to edit"<br />
  ENTER_KEY = "Please enter a key now"<br />
# These are the default virtual buttons' names the RM editors have always used,<br />
# but feel free to change them if ever needed.<br />
  TARGETS = %w{Up Down L L2 Left Right R R2 A B C X Y Z}<br />
<br />
class Scene<br />
  def main<br />
    setup<br />
    create_sprites<br />
    Graphics.transition<br />
    while @stage<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def setup<br />
    @vx_ace = Game::RGSS_VERSION == 3<br />
    Font.default_outline = true<br />
    @stage = :main<br />
    @index = 0<br />
    @col_index = 0<br />
    @gamepad = Input.gamepad<br />
    @bindings = Input.bindings<br />
    @list = @bindings.list<br />
    @target_names = []<br />
    @bind_names = []<br />
    @binds = []<br />
    @key_names = []<br />
    @changes = []<br />
    @sprites = []<br />
    case Graphics.width<br />
    when 544<br />
      @rows = 1<br />
    when 640<br />
      @rows = 2<br />
    when 800<br />
      @rows = 3<br />
    else<br />
      @rows = 4<br />
    end<br />
    @list.each {|bg| @binds += bg.data.take(@rows) }<br />
    @key_names = @binds.map {|b| b.name || "" }<br />
    @init_names = @key_names.dup<br />
    @temp_names = @key_names.dup<br />
    @back_color = Color.new(0, 0, 0, 120)<br />
    @target_color = Color.new(255, 200, 80)<br />
  end<br />
<br />
  def create_sprites<br />
    gw = Graphics.width<br />
    fn = BACKDROP + gw.to_s<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = Cache.system(fn).dup<br />
    b = Bitmap.new(Graphics.width, 48)<br />
    b.font.size = 32<br />
    b.draw_text(:rect, HEADING, 1)<br />
    @heading = Sprite.new<br />
    @heading.y = 4<br />
    @heading.bitmap = b<br />
    b = Cache.picture(HELP_BAR)<br />
    bx = (gw - b.width) / 2<br />
    @help_backdrop = Sprite.new<br />
    @help_backdrop.set_xy(bx, 60)<br />
    @help_backdrop.bitmap = b<br />
    @help_bit = Bitmap.new(gw, 32)<br />
    @help_bit.font.size = 24<br />
    @help_bit.draw_text(:rect, CHOOSE_KEY, 1)<br />
    @help = Sprite.new<br />
    @help.y = 60<br />
    @help.z = 20<br />
    @help.bitmap = @help_bit<br />
    @cursor = Sprite.new<br />
    @cursor.z = 10<br />
    @cursor.bitmap = Cache.picture(CURSOR)<br />
    sw = gw / 206<br />
    ix = (gw - sw * 206) / 2<br />
    b = Cache.picture(TARGET_BOX)<br />
    @key_max = TARGETS.size<br />
    @key_max.times do |n|<br />
      sx = ix + n % sw * 206<br />
      sy = 108 + n / sw * @rows * 32<br />
      @backdrop.bitmap.blt(sx + 2, sy - 2, b, b.rect)<br />
      s = Sprite.new<br />
      s.set_xyz(sx, sy, 20)<br />
      s.bitmap = Bitmap.new(80, 28)<br />
      s.bitmap.font.color = @target_color<br />
      s.bitmap.draw_text(:rect, TARGETS[n], 1)<br />
      @target_names &lt;&lt; s<br />
      @rows.times {|i| create_button_box(sx + 84, sy + i * 32) }<br />
    end<br />
    s = @bind_names[0]<br />
    @cursor.set_xy(s.x - 4, s.y - 2)<br />
    b.dispose<br />
    @sprites += @target_names + @bind_names<br />
    @sprites += [@heading, @help, @cursor, @help_backdrop, @backdrop]<br />
  end<br />
<br />
  def create_button_box(sx, sy)<br />
    name = @temp_names.shift<br />
    s = Sprite.new<br />
    s.set_xyz(sx, sy, 20)<br />
    b = Bitmap.new(112, 28)<br />
    b.draw_text(:rect, name, 1)<br />
    s.bitmap = b<br />
    @bind_names &lt;&lt; s<br />
    rect = b.rect.dup<br />
    rect.x = sx<br />
    rect.y = sy<br />
    @backdrop.bitmap.fill_rect(rect, @back_color)<br />
  end<br />
<br />
  def terminate<br />
    @sprites.each do |s|<br />
      s.bitmap.dispose<br />
      s.dispose<br />
    end<br />
    @changes = @changes.flatten.compact<br />
    return if @changes.empty?<br />
    Input.save_key_bindings<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :main<br />
      update_main<br />
    when :key<br />
      update_key<br />
    end<br />
  end<br />
<br />
  def box_index<br />
    @index * @rows + @col_index<br />
  end<br />
<br />
  def update_main<br />
    if Input.trigger?(:B)<br />
      Sound.play_cancel<br />
      &#36;scene = Scene_Map.new<br />
      return @stage = nil<br />
    elsif Input.trigger?(:Up)<br />
      update_cursor(0, -1)<br />
      return<br />
    elsif Input.trigger?(:Down)<br />
      update_cursor(0, 1)<br />
      return<br />
    elsif Input.trigger?(:Left)<br />
      update_cursor(-1, 0)<br />
      return<br />
    elsif Input.trigger?(:Right)<br />
      update_cursor(1, 0)<br />
      return<br />
    elsif Input.trigger?(:Delete)<br />
      Sound.play_buzzer<br />
      n = box_index<br />
      bind = @binds[n]<br />
      bind.value = 0<br />
      @key_names[n] = ""<br />
      b = @bind_names[n].bitmap<br />
      b.clear<br />
      b.draw_text(:rect, "", 1)<br />
      @changes[n] = true<br />
      return<br />
    elsif Input.trigger?(:C)<br />
      @vx_ace ? Sound.play_ok : Sound.play_decision<br />
      Input.keymap_mode!<br />
      Input.update<br />
      n = box_index<br />
      @bind = @binds[n]<br />
      @help_bit.clear<br />
      @help_bit.draw_text(:rect, ENTER_KEY, 1)<br />
      @bind_bit = @bind_names[n].bitmap<br />
      @bind_bit.clear<br />
      @stage = :key<br />
    end<br />
  end<br />
<br />
  def update_cursor(m, n)<br />
    Sound.play_cursor<br />
    @index = (@index + m) % @key_max<br />
    @col_index = (@col_index + n) % @rows<br />
    s = @bind_names[box_index]<br />
    @cursor.set_xy(s.x - 4, s.y - 2)<br />
  end<br />
<br />
  def reset_help<br />
    Input.play_mode!<br />
    Input.update<br />
    @bind_bit = @bind = nil<br />
    @help_bit.clear<br />
    @help_bit.draw_text(:rect, CHOOSE_KEY, 1)<br />
    @stage = :main<br />
  end<br />
<br />
  def update_key<br />
    if Input.trigger?(:MouseRight)<br />
      Sound.play_cancel<br />
      name = @key_names[box_index]<br />
      @bind_bit.draw_text(:rect, name, 1)<br />
      reset_help<br />
      return<br />
    elsif Input.trigger_any?<br />
      @vx_ace ? Sound.play_ok : Sound.play_decision<br />
      case Input.trigger_type<br />
      when 0<br />
        @bind.value = 0<br />
      when 1<br />
        @bind.value = Input.trigger_last<br />
      else<br />
        @bind.value = Input.trigger_gp_value<br />
      end<br />
      n = box_index<br />
      name = @bind.name<br />
      @key_names[n] = name<br />
      @bind_bit.clear<br />
      @bind_bit.draw_text(:rect, name, 1)<br />
      reset_help<br />
      @changes[n] = true<br />
    end<br />
  end<br />
end<br />
<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KChangeKeys HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b">by Kyonides</span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
Usually, a typical RM game would only let you change your key mappings via pressing the F1 button, and then you would be able to pick a few options for a minimal set of virtual buttons like A or C or R. Later on, mkxp let you set up to 4 different keys for a single target button. These keys can be actual keys or gamepad's buttons or axes or hats. None of those menus look very eye-catching, do they? <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /><br />
<br />
Now KChangeKeys HC for <span style="font-weight: bold;" class="mycode_b">HiddenChest version 1.2.06 or higher</span> is a real game changer. Now you CAN CHANGE your key bindings at will using this relatively simple script! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /> Just keep pressing keys or buttons <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /> to get impressed by it! <img src="https://www.save-point.org/images/smilies/ejlol/thumbs.gif" alt="Two Thumbs Up!" title="Two Thumbs Up!" class="smilie smilie_61" /> <br />
<br />
<div class="tborder">
  			<div class="thead" style="padding:4px; margin:1px;"><input type="button" class="button" value="+" style="font-family:Monospace; padding:0px" onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].style.display=='none'){ this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='';this.value='-';} else {this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='none';this.value='+';}"/> Screenshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<img src="https://i.postimg.cc/K8gtmX1K/kchangekeyshc-xp01.jpg" loading="lazy"  alt="[Image: kchangekeyshc-xp01.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/Sxzcm0n2/kchangekeyshc-xp02.jpg" loading="lazy"  alt="[Image: kchangekeyshc-xp02.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/g263G9xZ/kchangekeyshc-xp1280.jpg" loading="lazy"  alt="[Image: kchangekeyshc-xp1280.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">Script for RMXP</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KChangeKeys HC for XP * #<br />
#   Scripter : Kyonides<br />
#   2026-01-11<br />
<br />
# * This scripts depends on HiddenChest v1.2.06 or higher. * #<br />
<br />
# With this scriptlet you are now able to change the keys that are normally<br />
# mapped to any of RMXP's default buttons like A, B, C, etc. without pressing<br />
# the F1, F2 &amp; F12 buttons!<br />
<br />
# * Script Call * #<br />
# &#36;scene = KChangeKeys::Scene.new<br />
<br />
module KChangeKeys<br />
  BACKDROP = "dwarven mine"<br />
  HELP_BAR = "help bar"<br />
  TARGET_BOX = "target box"<br />
  CURSOR = "cursor"<br />
  HEADING = "Key Bindings"<br />
  CHOOSE_KEY = "Please select a key to edit"<br />
  ENTER_KEY = "Please enter a key now"<br />
# These are the default virtual buttons' names the RM editors have always used,<br />
# but feel free to change them if ever needed.<br />
  TARGETS = %w{Up Down L L2 Left Right R R2 A B C X Y Z}<br />
<br />
class Scene<br />
  def main<br />
    setup<br />
    create_sprites<br />
    Graphics.transition<br />
    while @stage<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def setup<br />
    Font.default_outline = true<br />
    @stage = :main<br />
    @index = 0<br />
    @col_index = 0<br />
    @gamepad = Input.gamepad<br />
    @bindings = Input.bindings<br />
    @list = @bindings.list<br />
    @target_names = []<br />
    @bind_names = []<br />
    @binds = []<br />
    @key_names = []<br />
    @changes = []<br />
    @sprites = []<br />
    case Graphics.width<br />
    when 544<br />
      @rows = 1<br />
    when 640<br />
      @rows = 2<br />
    when 800<br />
      @rows = 3<br />
    else<br />
      @rows = 4<br />
    end<br />
    @list.each {|bg| @binds += bg.data.take(@rows) }<br />
    @key_names = @binds.map {|b| b.name || "" }<br />
    @init_names = @key_names.dup<br />
    @temp_names = @key_names.dup<br />
    @back_color = Color.new(0, 0, 0, 120)<br />
    @target_color = Color.new(255, 200, 80)<br />
  end<br />
<br />
  def create_sprites<br />
    gw = Graphics.width<br />
    fn = BACKDROP + gw.to_s<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = RPG::Cache.title(fn).dup<br />
    b = Bitmap.new(gw, 48)<br />
    b.font.size = 32<br />
    b.draw_text(:rect, HEADING, 1)<br />
    @heading = Sprite.new<br />
    @heading.y = 4<br />
    @heading.bitmap = b<br />
    b = RPG::Cache.picture(HELP_BAR)<br />
    bx = (gw - b.width) / 2<br />
    @help_backdrop = Sprite.new<br />
    @help_backdrop.set_xy(bx, 60)<br />
    @help_backdrop.bitmap = b<br />
    @help_bit = Bitmap.new(gw, 32)<br />
    @help_bit.font.size = 24<br />
    @help_bit.draw_text(:rect, CHOOSE_KEY, 1)<br />
    @help = Sprite.new<br />
    @help.y = 60<br />
    @help.z = 20<br />
    @help.bitmap = @help_bit<br />
    @cursor = Sprite.new<br />
    @cursor.z = 10<br />
    @cursor.bitmap = RPG::Cache.picture(CURSOR)<br />
    sw = gw / 206<br />
    ix = (gw - sw * 206) / 2<br />
    b = RPG::Cache.picture(TARGET_BOX)<br />
    @key_max = TARGETS.size<br />
    @key_max.times do |n|<br />
      sx = ix + n % sw * 206<br />
      sy = 108 + n / sw * @rows * 32<br />
      @backdrop.bitmap.blt(sx + 2, sy - 2, b, b.rect)<br />
      s = Sprite.new<br />
      s.set_xyz(sx, sy, 20)<br />
      s.bitmap = Bitmap.new(80, 28)<br />
      s.bitmap.font.color = @target_color<br />
      s.bitmap.draw_text(:rect, TARGETS[n], 1)<br />
      @target_names &lt;&lt; s<br />
      @rows.times {|i| create_button_box(sx + 84, sy + i * 32) }<br />
    end<br />
    s = @bind_names[0]<br />
    @cursor.set_xy(s.x - 4, s.y - 2)<br />
    b.dispose<br />
    @sprites += @target_names + @bind_names<br />
    @sprites += [@heading, @help, @cursor, @help_backdrop, @backdrop]<br />
  end<br />
<br />
  def create_button_box(sx, sy)<br />
    name = @temp_names.shift<br />
    s = Sprite.new<br />
    s.set_xyz(sx, sy, 20)<br />
    b = Bitmap.new(112, 28)<br />
    b.draw_text(:rect, name, 1)<br />
    s.bitmap = b<br />
    @bind_names &lt;&lt; s<br />
    rect = b.rect.dup<br />
    rect.x = sx<br />
    rect.y = sy<br />
    @backdrop.bitmap.fill_rect(rect, @back_color)<br />
  end<br />
<br />
  def terminate<br />
    @sprites.each do |s|<br />
      s.bitmap.dispose<br />
      s.dispose<br />
    end<br />
    @changes = @changes.flatten.compact<br />
    return if @changes.empty?<br />
    Input.save_key_bindings<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :main<br />
      update_main<br />
    when :key<br />
      update_key<br />
    end<br />
  end<br />
<br />
  def box_index<br />
    @index * @rows + @col_index<br />
  end<br />
<br />
  def update_main<br />
    if Input.trigger?(:B)<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Map.new<br />
      return @stage = nil<br />
    elsif Input.trigger?(:Up)<br />
      update_cursor(0, -1)<br />
      return<br />
    elsif Input.trigger?(:Down)<br />
      update_cursor(0, 1)<br />
      return<br />
    elsif Input.trigger?(:Left)<br />
      update_cursor(-1, 0)<br />
      return<br />
    elsif Input.trigger?(:Right)<br />
      update_cursor(1, 0)<br />
      return<br />
    elsif Input.trigger?(:Delete)<br />
      &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
      n = box_index<br />
      bind = @binds[n]<br />
      bind.value = 0<br />
      @key_names[n] = ""<br />
      b = @bind_names[n].bitmap<br />
      b.clear<br />
      b.draw_text(:rect, "", 1)<br />
      @changes[n] = true<br />
      return<br />
    elsif Input.trigger?(:C)<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      Input.keymap_mode!<br />
      Input.update<br />
      n = box_index<br />
      @bind = @binds[n]<br />
      @help_bit.clear<br />
      @help_bit.draw_text(:rect, ENTER_KEY, 1)<br />
      @bind_bit = @bind_names[n].bitmap<br />
      @bind_bit.clear<br />
      @stage = :key<br />
    end<br />
  end<br />
<br />
  def update_cursor(m, n)<br />
    &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
    @index = (@index + m) % @key_max<br />
    @col_index = (@col_index + n) % @rows<br />
    s = @bind_names[box_index]<br />
    @cursor.set_xy(s.x - 4, s.y - 2)<br />
  end<br />
<br />
  def reset_help<br />
    Input.play_mode!<br />
    Input.update<br />
    @bind_bit = @bind = nil<br />
    @help_bit.clear<br />
    @help_bit.draw_text(:rect, CHOOSE_KEY, 1)<br />
    @stage = :main<br />
  end<br />
<br />
  def update_key<br />
    if Input.trigger?(:MouseRight)<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      name = @key_names[box_index]<br />
      @bind_bit.draw_text(:rect, name, 1)<br />
      reset_help<br />
      return<br />
    elsif Input.trigger_any?<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      case Input.trigger_type<br />
      when 0<br />
        @bind.value = 0<br />
      when 1<br />
        @bind.value = Input.trigger_last<br />
      else<br />
        @bind.value = Input.trigger_gp_value<br />
      end<br />
      n = box_index<br />
      name = @bind.name<br />
      @key_names[n] = name<br />
      @bind_bit.clear<br />
      @bind_bit.draw_text(:rect, name, 1)<br />
      reset_help<br />
      @changes[n] = true<br />
    end<br />
  end<br />
end<br />
<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RMVX &amp; VX ACE</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KChangeKeys HC for VX + ACE * #<br />
#   Scripter : Kyonides<br />
#   2026-01-11<br />
<br />
# * This scripts depends on HiddenChest v1.2.06 or higher. * #<br />
<br />
# With this scriptlet you are now able to change the keys that are normally<br />
# mapped to any of RMXP's default buttons like A, B, C, etc. without pressing<br />
# the F1, F2 &amp; F12 buttons!<br />
<br />
# For VX:<br />
# &#36;scene = KChangeKeys::Scene.new<br />
# For VX ACE:<br />
# SceneManager.call(KChangeKeys::Scene)<br />
<br />
module KChangeKeys<br />
  BACKDROP = "dwarven mine"<br />
  HELP_BAR = "help bar"<br />
  TARGET_BOX = "target box"<br />
  CURSOR = "cursor"<br />
  HEADING = "Key Bindings"<br />
  CHOOSE_KEY = "Please select a key to edit"<br />
  ENTER_KEY = "Please enter a key now"<br />
# These are the default virtual buttons' names the RM editors have always used,<br />
# but feel free to change them if ever needed.<br />
  TARGETS = %w{Up Down L L2 Left Right R R2 A B C X Y Z}<br />
<br />
class Scene<br />
  def main<br />
    setup<br />
    create_sprites<br />
    Graphics.transition<br />
    while @stage<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def setup<br />
    @vx_ace = Game::RGSS_VERSION == 3<br />
    Font.default_outline = true<br />
    @stage = :main<br />
    @index = 0<br />
    @col_index = 0<br />
    @gamepad = Input.gamepad<br />
    @bindings = Input.bindings<br />
    @list = @bindings.list<br />
    @target_names = []<br />
    @bind_names = []<br />
    @binds = []<br />
    @key_names = []<br />
    @changes = []<br />
    @sprites = []<br />
    case Graphics.width<br />
    when 544<br />
      @rows = 1<br />
    when 640<br />
      @rows = 2<br />
    when 800<br />
      @rows = 3<br />
    else<br />
      @rows = 4<br />
    end<br />
    @list.each {|bg| @binds += bg.data.take(@rows) }<br />
    @key_names = @binds.map {|b| b.name || "" }<br />
    @init_names = @key_names.dup<br />
    @temp_names = @key_names.dup<br />
    @back_color = Color.new(0, 0, 0, 120)<br />
    @target_color = Color.new(255, 200, 80)<br />
  end<br />
<br />
  def create_sprites<br />
    gw = Graphics.width<br />
    fn = BACKDROP + gw.to_s<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = Cache.system(fn).dup<br />
    b = Bitmap.new(Graphics.width, 48)<br />
    b.font.size = 32<br />
    b.draw_text(:rect, HEADING, 1)<br />
    @heading = Sprite.new<br />
    @heading.y = 4<br />
    @heading.bitmap = b<br />
    b = Cache.picture(HELP_BAR)<br />
    bx = (gw - b.width) / 2<br />
    @help_backdrop = Sprite.new<br />
    @help_backdrop.set_xy(bx, 60)<br />
    @help_backdrop.bitmap = b<br />
    @help_bit = Bitmap.new(gw, 32)<br />
    @help_bit.font.size = 24<br />
    @help_bit.draw_text(:rect, CHOOSE_KEY, 1)<br />
    @help = Sprite.new<br />
    @help.y = 60<br />
    @help.z = 20<br />
    @help.bitmap = @help_bit<br />
    @cursor = Sprite.new<br />
    @cursor.z = 10<br />
    @cursor.bitmap = Cache.picture(CURSOR)<br />
    sw = gw / 206<br />
    ix = (gw - sw * 206) / 2<br />
    b = Cache.picture(TARGET_BOX)<br />
    @key_max = TARGETS.size<br />
    @key_max.times do |n|<br />
      sx = ix + n % sw * 206<br />
      sy = 108 + n / sw * @rows * 32<br />
      @backdrop.bitmap.blt(sx + 2, sy - 2, b, b.rect)<br />
      s = Sprite.new<br />
      s.set_xyz(sx, sy, 20)<br />
      s.bitmap = Bitmap.new(80, 28)<br />
      s.bitmap.font.color = @target_color<br />
      s.bitmap.draw_text(:rect, TARGETS[n], 1)<br />
      @target_names &lt;&lt; s<br />
      @rows.times {|i| create_button_box(sx + 84, sy + i * 32) }<br />
    end<br />
    s = @bind_names[0]<br />
    @cursor.set_xy(s.x - 4, s.y - 2)<br />
    b.dispose<br />
    @sprites += @target_names + @bind_names<br />
    @sprites += [@heading, @help, @cursor, @help_backdrop, @backdrop]<br />
  end<br />
<br />
  def create_button_box(sx, sy)<br />
    name = @temp_names.shift<br />
    s = Sprite.new<br />
    s.set_xyz(sx, sy, 20)<br />
    b = Bitmap.new(112, 28)<br />
    b.draw_text(:rect, name, 1)<br />
    s.bitmap = b<br />
    @bind_names &lt;&lt; s<br />
    rect = b.rect.dup<br />
    rect.x = sx<br />
    rect.y = sy<br />
    @backdrop.bitmap.fill_rect(rect, @back_color)<br />
  end<br />
<br />
  def terminate<br />
    @sprites.each do |s|<br />
      s.bitmap.dispose<br />
      s.dispose<br />
    end<br />
    @changes = @changes.flatten.compact<br />
    return if @changes.empty?<br />
    Input.save_key_bindings<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :main<br />
      update_main<br />
    when :key<br />
      update_key<br />
    end<br />
  end<br />
<br />
  def box_index<br />
    @index * @rows + @col_index<br />
  end<br />
<br />
  def update_main<br />
    if Input.trigger?(:B)<br />
      Sound.play_cancel<br />
      &#36;scene = Scene_Map.new<br />
      return @stage = nil<br />
    elsif Input.trigger?(:Up)<br />
      update_cursor(0, -1)<br />
      return<br />
    elsif Input.trigger?(:Down)<br />
      update_cursor(0, 1)<br />
      return<br />
    elsif Input.trigger?(:Left)<br />
      update_cursor(-1, 0)<br />
      return<br />
    elsif Input.trigger?(:Right)<br />
      update_cursor(1, 0)<br />
      return<br />
    elsif Input.trigger?(:Delete)<br />
      Sound.play_buzzer<br />
      n = box_index<br />
      bind = @binds[n]<br />
      bind.value = 0<br />
      @key_names[n] = ""<br />
      b = @bind_names[n].bitmap<br />
      b.clear<br />
      b.draw_text(:rect, "", 1)<br />
      @changes[n] = true<br />
      return<br />
    elsif Input.trigger?(:C)<br />
      @vx_ace ? Sound.play_ok : Sound.play_decision<br />
      Input.keymap_mode!<br />
      Input.update<br />
      n = box_index<br />
      @bind = @binds[n]<br />
      @help_bit.clear<br />
      @help_bit.draw_text(:rect, ENTER_KEY, 1)<br />
      @bind_bit = @bind_names[n].bitmap<br />
      @bind_bit.clear<br />
      @stage = :key<br />
    end<br />
  end<br />
<br />
  def update_cursor(m, n)<br />
    Sound.play_cursor<br />
    @index = (@index + m) % @key_max<br />
    @col_index = (@col_index + n) % @rows<br />
    s = @bind_names[box_index]<br />
    @cursor.set_xy(s.x - 4, s.y - 2)<br />
  end<br />
<br />
  def reset_help<br />
    Input.play_mode!<br />
    Input.update<br />
    @bind_bit = @bind = nil<br />
    @help_bit.clear<br />
    @help_bit.draw_text(:rect, CHOOSE_KEY, 1)<br />
    @stage = :main<br />
  end<br />
<br />
  def update_key<br />
    if Input.trigger?(:MouseRight)<br />
      Sound.play_cancel<br />
      name = @key_names[box_index]<br />
      @bind_bit.draw_text(:rect, name, 1)<br />
      reset_help<br />
      return<br />
    elsif Input.trigger_any?<br />
      @vx_ace ? Sound.play_ok : Sound.play_decision<br />
      case Input.trigger_type<br />
      when 0<br />
        @bind.value = 0<br />
      when 1<br />
        @bind.value = Input.trigger_last<br />
      else<br />
        @bind.value = Input.trigger_gp_value<br />
      end<br />
      n = box_index<br />
      name = @bind.name<br />
      @key_names[n] = name<br />
      @bind_bit.clear<br />
      @bind_bit.draw_text(:rect, name, 1)<br />
      reset_help<br />
      @changes[n] = true<br />
    end<br />
  end<br />
end<br />
<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[KEnterText HC]]></title>
			<link>https://www.save-point.org/thread-13345.html</link>
			<pubDate>Wed, 10 Dec 2025 00:27:27 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-13345.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KEnterText HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
Ever since HiddenChest version <span style="font-weight: bold;" class="mycode_b">1.1.98</span> was released, game developers are now able to implement a very simple text input interface in their games.<br />
It heavily depends on the new additions to the Input module to make it work normally.<br />
<br />
<blockquote class="mycode_quote"><cite>kyonides Wrote:</cite><span style="font-size: medium;" class="mycode_size">Running HiddenChest version <span style="font-weight: bold;" class="mycode_b">1.1.99</span> is HIGHLY recommended here.</span></blockquote><br />
The CapsLock and Shift keys DO alter the outcome while typing a text.<br />
<br />
You can delete characters with Backspace or Delete keys if you use my script.<br />
<br />
You can count on the basic ASCII characters to enter a name or nickname or even a number. Hyphen -, period ., and space " " are recognized automatically.<br />
WARNING: Accents will be ignored by default. Sorry about that. <img src="https://www.save-point.org/images/smilies/ejlol/laughingtongue.gif" alt="Laughing + Tongue sticking out" title="Laughing + Tongue sticking out" class="smilie smilie_30" /><br />
<br />
<div class="tborder">
  			<div class="thead" style="padding:4px; margin:1px;"><input type="button" class="button" value="+" style="font-family:Monospace; padding:0px" onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].style.display=='none'){ this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='';this.value='-';} else {this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='none';this.value='+';}"/> Screenshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<img src="https://i.postimg.cc/Vkf1R9X7/kentertext-hc001.jpg" loading="lazy"  alt="[Image: kentertext-hc001.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/VLPq0L1p/kentertext-hc002.jpg" loading="lazy"  alt="[Image: kentertext-hc002.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/ncFwPDQp/kentertext-hc003.jpg" loading="lazy"  alt="[Image: kentertext-hc003.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">RMXP</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KEnterText HC for XP * #<br />
#   Scripter : Kyonides<br />
#   2025-12-18<br />
<br />
# &#36;scene = KEnter::TextScene.new<br />
<br />
module KEnter<br />
<br />
class TextBox<br />
  REGEX_INT = /&#92;-?[0-9]/<br />
  REGEX_DBL = /&#92;-?[0-9]+[&#92;.,]?[0-9]?/<br />
  def initialize(bw, bh, color)<br />
    @index = 0<br />
    @char_limit = 1<br />
    @number_mode = nil<br />
    @viewport = Viewport.new(0, 0, bw, bh)<br />
    bitmap = Bitmap.new(bw, bh)<br />
    bitmap.fill_rect(bitmap.rect, color)<br />
    @box = Sprite.new(@viewport)<br />
    @box.bitmap = bitmap<br />
    @bitmap = Bitmap.new(bw - 8, bh - 4)<br />
    @bitmap.font.size = 24<br />
    @bitmap.font.outline = true<br />
    @rect = @bitmap.rect<br />
    @text = Sprite.new(@viewport)<br />
    @text.bitmap = @bitmap<br />
    bitmap = Bitmap.new(20, 28)<br />
    bitmap.font.size = 24<br />
    bitmap.font.outline = true<br />
    bitmap.draw_text(bitmap.rect, "|")<br />
    @cursor = Sprite.new(@viewport)<br />
    @cursor.visible = false<br />
    @cursor.bitmap = bitmap<br />
    @sprites = [@text, @box, @cursor]<br />
  end<br />
<br />
  def move2(bx, by, n, lh)<br />
    @viewport.x = bx<br />
    @viewport.y = by + n * lh<br />
    @text.set_xy(4, 2)<br />
    @cursor.set_xy(8, 2)<br />
  end<br />
<br />
  def reset_cursor<br />
    @index = @chars.size - 1<br />
    set_cursor(@chars.join)<br />
  end<br />
<br />
  def chars=(ary)<br />
    @chars = ary<br />
    @index = ary.size - 1<br />
    refresh<br />
    set_cursor(@chars.join)<br />
  end<br />
<br />
  def move_back<br />
    @index -= 1 if @index &gt; 0<br />
    text = @chars[0, @index] || [""]<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def move_forward<br />
    @index += 1 if @index &lt; @chars.size - 1<br />
    text = @chars[0, @index] || [""]<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def process_char<br />
    char = Input.last_char<br />
    return unless char<br />
    case @number_mode<br />
    when :int<br />
      char = char[REGEX_INT]<br />
    when :dbl<br />
      char = char[REGEX_DBL]<br />
    else<br />
      if Input.press?(Input::SHIFT)<br />
        char = Input.capslock_state ? char.downcase : char.upcase<br />
      end<br />
    end<br />
    return unless char<br />
    @index += 1<br />
    if @chars.size == @index<br />
      @chars &lt;&lt; char<br />
    else<br />
      @chars[@index, 0] = char<br />
    end<br />
    @chars.compact!<br />
    text = @chars[0, @index]<br />
    refresh<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def delete_prev_char<br />
    if @chars.size - 1 == @index<br />
      @chars.pop<br />
      @index = [@chars.size - 1, 0].max<br />
      text = @chars<br />
    else<br />
      @chars.delete_at(@index)<br />
      @index = [@index - 1, 0].max<br />
      text = @chars[0, @index] || [""]<br />
    end<br />
    refresh<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def delete_next_char<br />
    @chars.delete_at(@index + 1)<br />
    refresh<br />
  end<br />
<br />
  def refresh<br />
    @bitmap.clear<br />
    @bitmap.draw_text(@rect, @chars.join)<br />
  end<br />
<br />
  def set_cursor(text)<br />
    tw = @bitmap.text_width(text)<br />
    @cursor.x = tw + 8<br />
  end<br />
<br />
  def char_max?<br />
    @chars.size == @char_limit<br />
  end<br />
<br />
  def integer_only!<br />
    @number_mode = :int<br />
  end<br />
<br />
  def double_only!<br />
    @number_mode = :dbl<br />
  end<br />
<br />
  def include_all!<br />
    @number_mode = nil<br />
  end<br />
<br />
  def dispose<br />
    @sprites.each do |sprite|<br />
      sprite.bitmap.dispose<br />
      sprite.dispose<br />
    end<br />
    @sprites.clear<br />
    @viewport.dispose<br />
  end<br />
  attr_writer :char_limit<br />
  attr_reader :chars, :index, :cursor<br />
end<br />
<br />
class TextScene<br />
  CHAR_LIMIT = 18<br />
  NUM_LIMIT = 2<br />
  BACKDROP = "catacombs"<br />
  LABELS = ["Your Name", "Your Nickname", "Your Age"]<br />
  @@texts = Array.new(3) {[]}<br />
  def main<br />
    @stage = :main<br />
    @blink_timer = Graphics.frame_rate / 5<br />
    @blink_state = false<br />
    @index = 0<br />
    @text_sprites = []<br />
    black = Color.new(0, 0, 0)<br />
    @blue = Color.new(80, 80, 255)<br />
    custom = Color.new(255, 255, 40)<br />
    lbit = Bitmap.new(208, 180)<br />
    lbit.font.outline = true<br />
    3.times {|n| lbit.draw_text(16, 78 * n, 220, 24, LABELS[n]) }<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = RPG::Cache.title(BACKDROP)<br />
    @label_sprite = Sprite.new<br />
    @label_sprite.set_xy(16, 12)<br />
    @label_sprite.bitmap = lbit<br />
    make_box_text_sprites<br />
    cb = Bitmap.new(208, 4)<br />
    @main_cursor = Sprite.new<br />
    @main_cursor.set_xy(20, 38)<br />
    @main_cursor.bitmap = cb<br />
    cb.fill_rect(cb.rect, black)<br />
    cb.fill_rect(2, 1, 204, 2, custom)<br />
    @text_cursor = @text_sprites[0].cursor<br />
    Graphics.transition<br />
    while @stage<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
    Graphics.freeze<br />
    cb.dispose<br />
    @main_cursor.dispose<br />
    @text_sprites.each_with_index do |box, n|<br />
      box.dispose<br />
      @@texts[n] = box.chars<br />
    end<br />
    @label_sprite.dispose<br />
    @backdrop.bitmap.dispose<br />
    @backdrop.dispose<br />
  end<br />
<br />
  def make_box_text_sprites<br />
    3.times do |n|<br />
      textbox = TextBox.new(n &lt; 2 ? 228 : 116, 32, @blue)<br />
      textbox.move2(16, 48, n, 78)<br />
      textbox.chars = @@texts[n]<br />
      textbox.char_limit = n &lt; 2 ? CHAR_LIMIT : NUM_LIMIT<br />
      textbox.integer_only! if n == 2<br />
      @text_sprites &lt;&lt; textbox<br />
    end<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :main<br />
      update_index<br />
    when :text_input<br />
      update_text_input<br />
    end<br />
  end<br />
<br />
  def update_blink<br />
    @blink_timer -= 1<br />
    if @blink_timer == 0<br />
      @blink_timer = Graphics.frame_rate / 5<br />
      @blink_state = !@blink_state<br />
      @text_cursor.visible = @blink_state<br />
    end<br />
  end<br />
<br />
  def update_index<br />
    if Input.trigger?(Input::Escape)<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Map.new<br />
      return @sprite = @stage = nil<br />
    elsif Input.trigger?(Input::UP)<br />
      set_index(-1)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      set_index(1)<br />
      return<br />
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      Input.text_input = true<br />
      Input.update<br />
      @stage = :text_input<br />
      @sprite = @text_sprites[@index]<br />
      @blink_timer = Graphics.frame_rate / 5<br />
      @text_cursor.visible = @blink_state = true<br />
    end<br />
  end<br />
<br />
  def set_index(n)<br />
    &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
    @index = (@index + n) % 3<br />
    @main_cursor.y = 38 + @index * 78<br />
    @text_cursor = @text_sprites[@index].cursor<br />
  end<br />
<br />
  def update_text_input<br />
    update_blink<br />
    if Input.trigger?(Input::Left)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @sprite.move_back<br />
      return<br />
    elsif Input.trigger?(Input::Right)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @sprite.move_forward<br />
      return<br />
    elsif Input.trigger?(Input::Escape)<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      process_text_box_cancel<br />
      return<br />
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      Graphics.screenshot<br />
      process_text_box_cancel<br />
      return<br />
    elsif Input.repeat?(Input::Backspace)<br />
      &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
      @sprite.delete_prev_char<br />
      return<br />
    elsif Input.repeat?(Input::Delete)<br />
      &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
      @sprite.delete_next_char<br />
      return<br />
    elsif Input.trigger_any? and Input.last_key?<br />
      if @sprite.char_max?<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      &#36;game_system.se_play(&#36;data_system.equip_se)<br />
      @sprite.process_char<br />
    end<br />
  end<br />
<br />
  def process_text_box_cancel<br />
    Input.text_input = false<br />
    Input.clear_text_input<br />
    Input.update<br />
    @sprite.reset_cursor<br />
    @text_cursor.visible = @blink_state = false<br />
    @blink_timer = Graphics.frame_rate / 5<br />
    @stage = :main<br />
  end<br />
end<br />
  <br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">RMVX + RMVX ACE</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KEnterText HC for VX + ACE * #<br />
#   Scripter : Kyonides<br />
#   2025-12-18<br />
<br />
# For VX:<br />
# &#36;scene = KEnter::TextScene.new<br />
<br />
# For VX ACE:<br />
# SceneManager.call(KEnter::TextScene)<br />
<br />
module KEnter<br />
<br />
class TextBox<br />
  REGEX_INT = /&#92;-?[0-9]/<br />
  REGEX_DBL = /&#92;-?[0-9]+[&#92;.,]?[0-9]?/<br />
  def initialize(bw, bh, color)<br />
    @index = 0<br />
    @char_limit = 1<br />
    @number_mode = nil<br />
    @viewport = Viewport.new(0, 0, bw, bh)<br />
    bitmap = Bitmap.new(bw, bh)<br />
    bitmap.fill_rect(bitmap.rect, color)<br />
    @box = Sprite.new(@viewport)<br />
    @box.bitmap = bitmap<br />
    @bitmap = Bitmap.new(bw - 8, bh - 4)<br />
    @bitmap.font.size = 24<br />
    @bitmap.font.outline = true<br />
    @rect = @bitmap.rect<br />
    @text = Sprite.new(@viewport)<br />
    @text.bitmap = @bitmap<br />
    bitmap = Bitmap.new(20, 28)<br />
    bitmap.font.size = 24<br />
    bitmap.font.outline = true<br />
    bitmap.draw_text(bitmap.rect, "|")<br />
    @cursor = Sprite.new(@viewport)<br />
    @cursor.visible = false<br />
    @cursor.bitmap = bitmap<br />
    @sprites = [@text, @box, @cursor]<br />
  end<br />
<br />
  def move2(bx, by, n, lh)<br />
    @viewport.x = bx<br />
    @viewport.y = by + n * lh<br />
    @text.set_xy(4, 2)<br />
    @cursor.set_xy(8, 2)<br />
  end<br />
<br />
  def reset_cursor<br />
    @index = @chars.size - 1<br />
    set_cursor(@chars.join)<br />
  end<br />
<br />
  def chars=(ary)<br />
    @chars = ary<br />
    @index = ary.size - 1<br />
    refresh<br />
    set_cursor(@chars.join)<br />
  end<br />
<br />
  def move_back<br />
    @index -= 1 if @index &gt; 0<br />
    text = @chars[0, @index] || [""]<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def move_forward<br />
    @index += 1 if @index &lt; @chars.size - 1<br />
    text = @chars[0, @index] || [""]<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def process_char<br />
    char = Input.last_char<br />
    return unless char<br />
    case @number_mode<br />
    when :int<br />
      char = char[REGEX_INT]<br />
    when :dbl<br />
      char = char[REGEX_DBL]<br />
    else<br />
      if Input.press?(Input::SHIFT)<br />
        char = Input.capslock_state ? char.downcase : char.upcase<br />
      end<br />
    end<br />
    return unless char<br />
    @index += 1<br />
    if @chars.size == @index<br />
      @chars &lt;&lt; char<br />
    else<br />
      @chars[@index, 0] = char<br />
    end<br />
    @chars.compact!<br />
    text = @chars[0, @index]<br />
    refresh<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def delete_prev_char<br />
    if @chars.size - 1 == @index<br />
      @chars.pop<br />
      @index = [@chars.size - 1, 0].max<br />
      text = @chars<br />
    else<br />
      @chars.delete_at(@index)<br />
      @index = [@index - 1, 0].max<br />
      text = @chars[0, @index] || [""]<br />
    end<br />
    refresh<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def delete_next_char<br />
    @chars.delete_at(@index + 1)<br />
    refresh<br />
  end<br />
<br />
  def refresh<br />
    @bitmap.clear<br />
    @bitmap.draw_text(@rect, @chars.join)<br />
  end<br />
<br />
  def set_cursor(text)<br />
    tw = @bitmap.text_width(text)<br />
    @cursor.x = tw + 8<br />
  end<br />
<br />
  def char_max?<br />
    @chars.size == @char_limit<br />
  end<br />
<br />
  def integer_only!<br />
    @number_mode = :int<br />
  end<br />
<br />
  def double_only!<br />
    @number_mode = :dbl<br />
  end<br />
<br />
  def include_all!<br />
    @number_mode = nil<br />
  end<br />
<br />
  def dispose<br />
    @sprites.each do |sprite|<br />
      sprite.bitmap.dispose<br />
      sprite.dispose<br />
    end<br />
    @sprites.clear<br />
    @viewport.dispose<br />
  end<br />
  attr_writer :char_limit<br />
  attr_reader :chars, :index, :cursor<br />
end<br />
<br />
class TextScene<br />
  CHAR_LIMIT = 18<br />
  BACKDROP = "catacombs"<br />
  LABELS = ["Your Name", "Your Nickname", "Your Age"]<br />
  @@texts = Array.new(3) {[]}<br />
  def main<br />
    @vx_ace = Game::RGSS_VERSION == 3<br />
    @stage = :main<br />
    @blink_timer = Graphics.frame_rate / 5<br />
    @blink_state = false<br />
    @index = 0<br />
    @text_sprites = []<br />
    black = Color.new(0, 0, 0)<br />
    @blue = Color.new(80, 80, 255)<br />
    custom = Color.new(255, 255, 40)<br />
    lbit = Bitmap.new(208, 180)<br />
    lbit.font.outline = true<br />
    3.times {|n| lbit.draw_text(16, 78 * n, 220, 24, LABELS[n]) }<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = Cache.system(BACKDROP)<br />
    @label_sprite = Sprite.new<br />
    @label_sprite.set_xy(16, 12)<br />
    @label_sprite.bitmap = lbit<br />
    make_box_text_sprites<br />
    cb = Bitmap.new(208, 4)<br />
    @main_cursor = Sprite.new<br />
    @main_cursor.set_xy(20, 38)<br />
    @main_cursor.bitmap = cb<br />
    cb.fill_rect(cb.rect, black)<br />
    cb.fill_rect(2, 1, 204, 2, custom)<br />
    @text_cursor = @text_sprites[0].cursor<br />
    Graphics.transition<br />
    while @stage<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
    Graphics.freeze<br />
    cb.dispose<br />
    @main_cursor.dispose<br />
    @text_sprites.each_with_index do |box, n|<br />
      box.dispose<br />
      @@texts[n] = box.chars<br />
    end<br />
    @label_sprite.dispose<br />
    @backdrop.bitmap.dispose<br />
    @backdrop.dispose<br />
  end<br />
<br />
  def make_box_text_sprites<br />
    3.times do |n|<br />
      textbox = TextBox.new(n &lt; 2 ? 228 : 116, 32, @blue)<br />
      textbox.move2(16, 48, n, 78)<br />
      textbox.chars = @@texts[n]<br />
      textbox.char_limit = n &lt; 2 ? CHAR_LIMIT : NUM_LIMIT<br />
      textbox.integer_only! if n == 2<br />
      @text_sprites &lt;&lt; textbox<br />
    end<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :main<br />
      update_index<br />
    when :text_input<br />
      update_text_input<br />
    end<br />
  end<br />
<br />
  def update_blink<br />
    @blink_timer -= 1<br />
    if @blink_timer == 0<br />
      @blink_timer = Graphics.frame_rate / 5<br />
      @blink_state = !@blink_state<br />
      @text_cursor.visible = @blink_state<br />
    end<br />
  end<br />
<br />
  def update_index<br />
    if Input.trigger?(Input::Escape)<br />
      Sound.play_cancel<br />
      &#36;scene = Scene_Map.new<br />
      return @sprite = @stage = nil<br />
    elsif Input.trigger?(Input::UP)<br />
      set_index(-1)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      set_index(1)<br />
      return<br />
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)<br />
      @vx_ace ? Sound.play_ok : Sound.play_decision<br />
      Input.text_input = true<br />
      Input.update<br />
      @stage = :text_input<br />
      @sprite = @text_sprites[@index]<br />
      @blink_timer = Graphics.frame_rate / 5<br />
      @text_cursor.visible = @blink_state = true<br />
    end<br />
  end<br />
<br />
  def set_index(n)<br />
    Sound.play_cursor<br />
    @index = (@index + n) % 3<br />
    @main_cursor.y = 38 + @index * 78<br />
    @text_cursor = @text_sprites[@index].cursor<br />
  end<br />
<br />
  def update_text_input<br />
    update_blink<br />
    if Input.trigger?(Input::Left)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @sprite.move_back<br />
      return<br />
    elsif Input.trigger?(Input::Right)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @sprite.move_forward<br />
      return<br />
    elsif Input.trigger?(Input::Escape)<br />
      Sound.play_cancel<br />
      process_text_box_cancel<br />
      return<br />
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)<br />
      @vx_ace ? Sound.play_ok : Sound.play_decision<br />
      Graphics.screenshot<br />
      process_text_box_cancel<br />
      return<br />
    elsif Input.repeat?(Input::Backspace)<br />
      Sound.play_buzzer<br />
      @sprite.delete_char<br />
      return<br />
    elsif Input.repeat?(Input::Delete)<br />
      &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
      @sprite.delete_next_char<br />
      return<br />
    elsif Input.trigger_any? and Input.last_key?<br />
      if @sprite.char_max?<br />
        Sound.play_buzzer<br />
        return<br />
      end<br />
      Sound.play_equip<br />
      @sprite.process_char<br />
    end<br />
  end<br />
<br />
  def process_text_box_cancel<br />
    Input.text_input = false<br />
    Input.clear_text_input<br />
    Input.update<br />
    @sprite.reset_cursor<br />
    @text_cursor.visible = @blink_state = false<br />
    @blink_timer = Graphics.frame_rate / 5<br />
    @stage = :main<br />
  end<br />
end<br />
<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
The same as HiddenChest's.<br />
That's it!  <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KEnterText HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
Ever since HiddenChest version <span style="font-weight: bold;" class="mycode_b">1.1.98</span> was released, game developers are now able to implement a very simple text input interface in their games.<br />
It heavily depends on the new additions to the Input module to make it work normally.<br />
<br />
<blockquote class="mycode_quote"><cite>kyonides Wrote:</cite><span style="font-size: medium;" class="mycode_size">Running HiddenChest version <span style="font-weight: bold;" class="mycode_b">1.1.99</span> is HIGHLY recommended here.</span></blockquote><br />
The CapsLock and Shift keys DO alter the outcome while typing a text.<br />
<br />
You can delete characters with Backspace or Delete keys if you use my script.<br />
<br />
You can count on the basic ASCII characters to enter a name or nickname or even a number. Hyphen -, period ., and space " " are recognized automatically.<br />
WARNING: Accents will be ignored by default. Sorry about that. <img src="https://www.save-point.org/images/smilies/ejlol/laughingtongue.gif" alt="Laughing + Tongue sticking out" title="Laughing + Tongue sticking out" class="smilie smilie_30" /><br />
<br />
<div class="tborder">
  			<div class="thead" style="padding:4px; margin:1px;"><input type="button" class="button" value="+" style="font-family:Monospace; padding:0px" onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].style.display=='none'){ this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='';this.value='-';} else {this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='none';this.value='+';}"/> Screenshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<img src="https://i.postimg.cc/Vkf1R9X7/kentertext-hc001.jpg" loading="lazy"  alt="[Image: kentertext-hc001.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/VLPq0L1p/kentertext-hc002.jpg" loading="lazy"  alt="[Image: kentertext-hc002.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/ncFwPDQp/kentertext-hc003.jpg" loading="lazy"  alt="[Image: kentertext-hc003.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">RMXP</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KEnterText HC for XP * #<br />
#   Scripter : Kyonides<br />
#   2025-12-18<br />
<br />
# &#36;scene = KEnter::TextScene.new<br />
<br />
module KEnter<br />
<br />
class TextBox<br />
  REGEX_INT = /&#92;-?[0-9]/<br />
  REGEX_DBL = /&#92;-?[0-9]+[&#92;.,]?[0-9]?/<br />
  def initialize(bw, bh, color)<br />
    @index = 0<br />
    @char_limit = 1<br />
    @number_mode = nil<br />
    @viewport = Viewport.new(0, 0, bw, bh)<br />
    bitmap = Bitmap.new(bw, bh)<br />
    bitmap.fill_rect(bitmap.rect, color)<br />
    @box = Sprite.new(@viewport)<br />
    @box.bitmap = bitmap<br />
    @bitmap = Bitmap.new(bw - 8, bh - 4)<br />
    @bitmap.font.size = 24<br />
    @bitmap.font.outline = true<br />
    @rect = @bitmap.rect<br />
    @text = Sprite.new(@viewport)<br />
    @text.bitmap = @bitmap<br />
    bitmap = Bitmap.new(20, 28)<br />
    bitmap.font.size = 24<br />
    bitmap.font.outline = true<br />
    bitmap.draw_text(bitmap.rect, "|")<br />
    @cursor = Sprite.new(@viewport)<br />
    @cursor.visible = false<br />
    @cursor.bitmap = bitmap<br />
    @sprites = [@text, @box, @cursor]<br />
  end<br />
<br />
  def move2(bx, by, n, lh)<br />
    @viewport.x = bx<br />
    @viewport.y = by + n * lh<br />
    @text.set_xy(4, 2)<br />
    @cursor.set_xy(8, 2)<br />
  end<br />
<br />
  def reset_cursor<br />
    @index = @chars.size - 1<br />
    set_cursor(@chars.join)<br />
  end<br />
<br />
  def chars=(ary)<br />
    @chars = ary<br />
    @index = ary.size - 1<br />
    refresh<br />
    set_cursor(@chars.join)<br />
  end<br />
<br />
  def move_back<br />
    @index -= 1 if @index &gt; 0<br />
    text = @chars[0, @index] || [""]<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def move_forward<br />
    @index += 1 if @index &lt; @chars.size - 1<br />
    text = @chars[0, @index] || [""]<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def process_char<br />
    char = Input.last_char<br />
    return unless char<br />
    case @number_mode<br />
    when :int<br />
      char = char[REGEX_INT]<br />
    when :dbl<br />
      char = char[REGEX_DBL]<br />
    else<br />
      if Input.press?(Input::SHIFT)<br />
        char = Input.capslock_state ? char.downcase : char.upcase<br />
      end<br />
    end<br />
    return unless char<br />
    @index += 1<br />
    if @chars.size == @index<br />
      @chars &lt;&lt; char<br />
    else<br />
      @chars[@index, 0] = char<br />
    end<br />
    @chars.compact!<br />
    text = @chars[0, @index]<br />
    refresh<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def delete_prev_char<br />
    if @chars.size - 1 == @index<br />
      @chars.pop<br />
      @index = [@chars.size - 1, 0].max<br />
      text = @chars<br />
    else<br />
      @chars.delete_at(@index)<br />
      @index = [@index - 1, 0].max<br />
      text = @chars[0, @index] || [""]<br />
    end<br />
    refresh<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def delete_next_char<br />
    @chars.delete_at(@index + 1)<br />
    refresh<br />
  end<br />
<br />
  def refresh<br />
    @bitmap.clear<br />
    @bitmap.draw_text(@rect, @chars.join)<br />
  end<br />
<br />
  def set_cursor(text)<br />
    tw = @bitmap.text_width(text)<br />
    @cursor.x = tw + 8<br />
  end<br />
<br />
  def char_max?<br />
    @chars.size == @char_limit<br />
  end<br />
<br />
  def integer_only!<br />
    @number_mode = :int<br />
  end<br />
<br />
  def double_only!<br />
    @number_mode = :dbl<br />
  end<br />
<br />
  def include_all!<br />
    @number_mode = nil<br />
  end<br />
<br />
  def dispose<br />
    @sprites.each do |sprite|<br />
      sprite.bitmap.dispose<br />
      sprite.dispose<br />
    end<br />
    @sprites.clear<br />
    @viewport.dispose<br />
  end<br />
  attr_writer :char_limit<br />
  attr_reader :chars, :index, :cursor<br />
end<br />
<br />
class TextScene<br />
  CHAR_LIMIT = 18<br />
  NUM_LIMIT = 2<br />
  BACKDROP = "catacombs"<br />
  LABELS = ["Your Name", "Your Nickname", "Your Age"]<br />
  @@texts = Array.new(3) {[]}<br />
  def main<br />
    @stage = :main<br />
    @blink_timer = Graphics.frame_rate / 5<br />
    @blink_state = false<br />
    @index = 0<br />
    @text_sprites = []<br />
    black = Color.new(0, 0, 0)<br />
    @blue = Color.new(80, 80, 255)<br />
    custom = Color.new(255, 255, 40)<br />
    lbit = Bitmap.new(208, 180)<br />
    lbit.font.outline = true<br />
    3.times {|n| lbit.draw_text(16, 78 * n, 220, 24, LABELS[n]) }<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = RPG::Cache.title(BACKDROP)<br />
    @label_sprite = Sprite.new<br />
    @label_sprite.set_xy(16, 12)<br />
    @label_sprite.bitmap = lbit<br />
    make_box_text_sprites<br />
    cb = Bitmap.new(208, 4)<br />
    @main_cursor = Sprite.new<br />
    @main_cursor.set_xy(20, 38)<br />
    @main_cursor.bitmap = cb<br />
    cb.fill_rect(cb.rect, black)<br />
    cb.fill_rect(2, 1, 204, 2, custom)<br />
    @text_cursor = @text_sprites[0].cursor<br />
    Graphics.transition<br />
    while @stage<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
    Graphics.freeze<br />
    cb.dispose<br />
    @main_cursor.dispose<br />
    @text_sprites.each_with_index do |box, n|<br />
      box.dispose<br />
      @@texts[n] = box.chars<br />
    end<br />
    @label_sprite.dispose<br />
    @backdrop.bitmap.dispose<br />
    @backdrop.dispose<br />
  end<br />
<br />
  def make_box_text_sprites<br />
    3.times do |n|<br />
      textbox = TextBox.new(n &lt; 2 ? 228 : 116, 32, @blue)<br />
      textbox.move2(16, 48, n, 78)<br />
      textbox.chars = @@texts[n]<br />
      textbox.char_limit = n &lt; 2 ? CHAR_LIMIT : NUM_LIMIT<br />
      textbox.integer_only! if n == 2<br />
      @text_sprites &lt;&lt; textbox<br />
    end<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :main<br />
      update_index<br />
    when :text_input<br />
      update_text_input<br />
    end<br />
  end<br />
<br />
  def update_blink<br />
    @blink_timer -= 1<br />
    if @blink_timer == 0<br />
      @blink_timer = Graphics.frame_rate / 5<br />
      @blink_state = !@blink_state<br />
      @text_cursor.visible = @blink_state<br />
    end<br />
  end<br />
<br />
  def update_index<br />
    if Input.trigger?(Input::Escape)<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Map.new<br />
      return @sprite = @stage = nil<br />
    elsif Input.trigger?(Input::UP)<br />
      set_index(-1)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      set_index(1)<br />
      return<br />
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      Input.text_input = true<br />
      Input.update<br />
      @stage = :text_input<br />
      @sprite = @text_sprites[@index]<br />
      @blink_timer = Graphics.frame_rate / 5<br />
      @text_cursor.visible = @blink_state = true<br />
    end<br />
  end<br />
<br />
  def set_index(n)<br />
    &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
    @index = (@index + n) % 3<br />
    @main_cursor.y = 38 + @index * 78<br />
    @text_cursor = @text_sprites[@index].cursor<br />
  end<br />
<br />
  def update_text_input<br />
    update_blink<br />
    if Input.trigger?(Input::Left)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @sprite.move_back<br />
      return<br />
    elsif Input.trigger?(Input::Right)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @sprite.move_forward<br />
      return<br />
    elsif Input.trigger?(Input::Escape)<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      process_text_box_cancel<br />
      return<br />
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      Graphics.screenshot<br />
      process_text_box_cancel<br />
      return<br />
    elsif Input.repeat?(Input::Backspace)<br />
      &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
      @sprite.delete_prev_char<br />
      return<br />
    elsif Input.repeat?(Input::Delete)<br />
      &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
      @sprite.delete_next_char<br />
      return<br />
    elsif Input.trigger_any? and Input.last_key?<br />
      if @sprite.char_max?<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      &#36;game_system.se_play(&#36;data_system.equip_se)<br />
      @sprite.process_char<br />
    end<br />
  end<br />
<br />
  def process_text_box_cancel<br />
    Input.text_input = false<br />
    Input.clear_text_input<br />
    Input.update<br />
    @sprite.reset_cursor<br />
    @text_cursor.visible = @blink_state = false<br />
    @blink_timer = Graphics.frame_rate / 5<br />
    @stage = :main<br />
  end<br />
end<br />
  <br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">RMVX + RMVX ACE</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KEnterText HC for VX + ACE * #<br />
#   Scripter : Kyonides<br />
#   2025-12-18<br />
<br />
# For VX:<br />
# &#36;scene = KEnter::TextScene.new<br />
<br />
# For VX ACE:<br />
# SceneManager.call(KEnter::TextScene)<br />
<br />
module KEnter<br />
<br />
class TextBox<br />
  REGEX_INT = /&#92;-?[0-9]/<br />
  REGEX_DBL = /&#92;-?[0-9]+[&#92;.,]?[0-9]?/<br />
  def initialize(bw, bh, color)<br />
    @index = 0<br />
    @char_limit = 1<br />
    @number_mode = nil<br />
    @viewport = Viewport.new(0, 0, bw, bh)<br />
    bitmap = Bitmap.new(bw, bh)<br />
    bitmap.fill_rect(bitmap.rect, color)<br />
    @box = Sprite.new(@viewport)<br />
    @box.bitmap = bitmap<br />
    @bitmap = Bitmap.new(bw - 8, bh - 4)<br />
    @bitmap.font.size = 24<br />
    @bitmap.font.outline = true<br />
    @rect = @bitmap.rect<br />
    @text = Sprite.new(@viewport)<br />
    @text.bitmap = @bitmap<br />
    bitmap = Bitmap.new(20, 28)<br />
    bitmap.font.size = 24<br />
    bitmap.font.outline = true<br />
    bitmap.draw_text(bitmap.rect, "|")<br />
    @cursor = Sprite.new(@viewport)<br />
    @cursor.visible = false<br />
    @cursor.bitmap = bitmap<br />
    @sprites = [@text, @box, @cursor]<br />
  end<br />
<br />
  def move2(bx, by, n, lh)<br />
    @viewport.x = bx<br />
    @viewport.y = by + n * lh<br />
    @text.set_xy(4, 2)<br />
    @cursor.set_xy(8, 2)<br />
  end<br />
<br />
  def reset_cursor<br />
    @index = @chars.size - 1<br />
    set_cursor(@chars.join)<br />
  end<br />
<br />
  def chars=(ary)<br />
    @chars = ary<br />
    @index = ary.size - 1<br />
    refresh<br />
    set_cursor(@chars.join)<br />
  end<br />
<br />
  def move_back<br />
    @index -= 1 if @index &gt; 0<br />
    text = @chars[0, @index] || [""]<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def move_forward<br />
    @index += 1 if @index &lt; @chars.size - 1<br />
    text = @chars[0, @index] || [""]<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def process_char<br />
    char = Input.last_char<br />
    return unless char<br />
    case @number_mode<br />
    when :int<br />
      char = char[REGEX_INT]<br />
    when :dbl<br />
      char = char[REGEX_DBL]<br />
    else<br />
      if Input.press?(Input::SHIFT)<br />
        char = Input.capslock_state ? char.downcase : char.upcase<br />
      end<br />
    end<br />
    return unless char<br />
    @index += 1<br />
    if @chars.size == @index<br />
      @chars &lt;&lt; char<br />
    else<br />
      @chars[@index, 0] = char<br />
    end<br />
    @chars.compact!<br />
    text = @chars[0, @index]<br />
    refresh<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def delete_prev_char<br />
    if @chars.size - 1 == @index<br />
      @chars.pop<br />
      @index = [@chars.size - 1, 0].max<br />
      text = @chars<br />
    else<br />
      @chars.delete_at(@index)<br />
      @index = [@index - 1, 0].max<br />
      text = @chars[0, @index] || [""]<br />
    end<br />
    refresh<br />
    set_cursor(text.join)<br />
  end<br />
<br />
  def delete_next_char<br />
    @chars.delete_at(@index + 1)<br />
    refresh<br />
  end<br />
<br />
  def refresh<br />
    @bitmap.clear<br />
    @bitmap.draw_text(@rect, @chars.join)<br />
  end<br />
<br />
  def set_cursor(text)<br />
    tw = @bitmap.text_width(text)<br />
    @cursor.x = tw + 8<br />
  end<br />
<br />
  def char_max?<br />
    @chars.size == @char_limit<br />
  end<br />
<br />
  def integer_only!<br />
    @number_mode = :int<br />
  end<br />
<br />
  def double_only!<br />
    @number_mode = :dbl<br />
  end<br />
<br />
  def include_all!<br />
    @number_mode = nil<br />
  end<br />
<br />
  def dispose<br />
    @sprites.each do |sprite|<br />
      sprite.bitmap.dispose<br />
      sprite.dispose<br />
    end<br />
    @sprites.clear<br />
    @viewport.dispose<br />
  end<br />
  attr_writer :char_limit<br />
  attr_reader :chars, :index, :cursor<br />
end<br />
<br />
class TextScene<br />
  CHAR_LIMIT = 18<br />
  BACKDROP = "catacombs"<br />
  LABELS = ["Your Name", "Your Nickname", "Your Age"]<br />
  @@texts = Array.new(3) {[]}<br />
  def main<br />
    @vx_ace = Game::RGSS_VERSION == 3<br />
    @stage = :main<br />
    @blink_timer = Graphics.frame_rate / 5<br />
    @blink_state = false<br />
    @index = 0<br />
    @text_sprites = []<br />
    black = Color.new(0, 0, 0)<br />
    @blue = Color.new(80, 80, 255)<br />
    custom = Color.new(255, 255, 40)<br />
    lbit = Bitmap.new(208, 180)<br />
    lbit.font.outline = true<br />
    3.times {|n| lbit.draw_text(16, 78 * n, 220, 24, LABELS[n]) }<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = Cache.system(BACKDROP)<br />
    @label_sprite = Sprite.new<br />
    @label_sprite.set_xy(16, 12)<br />
    @label_sprite.bitmap = lbit<br />
    make_box_text_sprites<br />
    cb = Bitmap.new(208, 4)<br />
    @main_cursor = Sprite.new<br />
    @main_cursor.set_xy(20, 38)<br />
    @main_cursor.bitmap = cb<br />
    cb.fill_rect(cb.rect, black)<br />
    cb.fill_rect(2, 1, 204, 2, custom)<br />
    @text_cursor = @text_sprites[0].cursor<br />
    Graphics.transition<br />
    while @stage<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
    Graphics.freeze<br />
    cb.dispose<br />
    @main_cursor.dispose<br />
    @text_sprites.each_with_index do |box, n|<br />
      box.dispose<br />
      @@texts[n] = box.chars<br />
    end<br />
    @label_sprite.dispose<br />
    @backdrop.bitmap.dispose<br />
    @backdrop.dispose<br />
  end<br />
<br />
  def make_box_text_sprites<br />
    3.times do |n|<br />
      textbox = TextBox.new(n &lt; 2 ? 228 : 116, 32, @blue)<br />
      textbox.move2(16, 48, n, 78)<br />
      textbox.chars = @@texts[n]<br />
      textbox.char_limit = n &lt; 2 ? CHAR_LIMIT : NUM_LIMIT<br />
      textbox.integer_only! if n == 2<br />
      @text_sprites &lt;&lt; textbox<br />
    end<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :main<br />
      update_index<br />
    when :text_input<br />
      update_text_input<br />
    end<br />
  end<br />
<br />
  def update_blink<br />
    @blink_timer -= 1<br />
    if @blink_timer == 0<br />
      @blink_timer = Graphics.frame_rate / 5<br />
      @blink_state = !@blink_state<br />
      @text_cursor.visible = @blink_state<br />
    end<br />
  end<br />
<br />
  def update_index<br />
    if Input.trigger?(Input::Escape)<br />
      Sound.play_cancel<br />
      &#36;scene = Scene_Map.new<br />
      return @sprite = @stage = nil<br />
    elsif Input.trigger?(Input::UP)<br />
      set_index(-1)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      set_index(1)<br />
      return<br />
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)<br />
      @vx_ace ? Sound.play_ok : Sound.play_decision<br />
      Input.text_input = true<br />
      Input.update<br />
      @stage = :text_input<br />
      @sprite = @text_sprites[@index]<br />
      @blink_timer = Graphics.frame_rate / 5<br />
      @text_cursor.visible = @blink_state = true<br />
    end<br />
  end<br />
<br />
  def set_index(n)<br />
    Sound.play_cursor<br />
    @index = (@index + n) % 3<br />
    @main_cursor.y = 38 + @index * 78<br />
    @text_cursor = @text_sprites[@index].cursor<br />
  end<br />
<br />
  def update_text_input<br />
    update_blink<br />
    if Input.trigger?(Input::Left)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @sprite.move_back<br />
      return<br />
    elsif Input.trigger?(Input::Right)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @sprite.move_forward<br />
      return<br />
    elsif Input.trigger?(Input::Escape)<br />
      Sound.play_cancel<br />
      process_text_box_cancel<br />
      return<br />
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)<br />
      @vx_ace ? Sound.play_ok : Sound.play_decision<br />
      Graphics.screenshot<br />
      process_text_box_cancel<br />
      return<br />
    elsif Input.repeat?(Input::Backspace)<br />
      Sound.play_buzzer<br />
      @sprite.delete_char<br />
      return<br />
    elsif Input.repeat?(Input::Delete)<br />
      &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
      @sprite.delete_next_char<br />
      return<br />
    elsif Input.trigger_any? and Input.last_key?<br />
      if @sprite.char_max?<br />
        Sound.play_buzzer<br />
        return<br />
      end<br />
      Sound.play_equip<br />
      @sprite.process_char<br />
    end<br />
  end<br />
<br />
  def process_text_box_cancel<br />
    Input.text_input = false<br />
    Input.clear_text_input<br />
    Input.update<br />
    @sprite.reset_cursor<br />
    @text_cursor.visible = @blink_state = false<br />
    @blink_timer = Graphics.frame_rate / 5<br />
    @stage = :main<br />
  end<br />
end<br />
<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
The same as HiddenChest's.<br />
That's it!  <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[KGamePad HC]]></title>
			<link>https://www.save-point.org/thread-13320.html</link>
			<pubDate>Mon, 24 Nov 2025 06:13:09 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-13320.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KGamePad HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
This scriptlet shows you how you can easily implement a gamepad disconnection script.<br />
<br />
The custom module includes all the methods the modified scene scripts would need to include. I also provide you with some XP's Scene_Title script add-on to allow it to display a gamepad icon based on its current status. This script will show you how easily you can implement the module's contents with very few lines of code.<br />
<br />
Just don't forget to <span style="font-weight: bold;" class="mycode_b">include</span> the <span style="font-weight: bold;" class="mycode_b">KGamePad</span> module! <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
<br />
<span style="font-weight: bold;" class="mycode_b">NOTES</span><br />
<br />
The <span style="font-weight: bold;" class="mycode_b">Input.gamepad_update</span> call will return either some <span style="font-weight: bold;" class="mycode_b">:add</span> or <span style="font-weight: bold;" class="mycode_b">:remove</span> symbol. That symbol is first converted to a string and then it is used by my script to define which gamepad icon it should show next.<br />
<br />
<div class="tborder">
  			<div class="thead" style="padding:4px; margin:1px;"><input type="button" class="button" value="+" style="font-family:Monospace; padding:0px" onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].style.display=='none'){ this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='';this.value='-';} else {this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='none';this.value='+';}"/> Screenshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<img src="https://i.postimg.cc/fRTFg06m/gamepad-script001.jpg" loading="lazy"  alt="[Image: gamepad-script001.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/MpK4rjh1/gamepad-script002.jpg" loading="lazy"  alt="[Image: gamepad-script002.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">The Module Script<br />
</span><span style="font-weight: bold;" class="mycode_b">For RMXP</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KGamePad HC for XP * #<br />
#  Scripter : Kyonides<br />
#  2025-11-24<br />
<br />
module KGamePad<br />
  GAMEPAD_PIC = "gamepad_black"<br />
  GAMEPAD_XY = [12, 12]<br />
  GAMEPAD_FRAMES = 90<br />
<br />
  def create_gamepad_icon<br />
    @gamepad_timer = 0<br />
    @gamepad = Sprite.new<br />
    @gamepad.set_xy(*GAMEPAD_XY)<br />
    @gamepad.z = 10000<br />
    @gamepad.visible = false<br />
    @gamepad.bitmap = Bitmap.new(32, 32)<br />
  end<br />
<br />
  def dispose_gamepad_icon<br />
    @gamepad.bitmap.dispose<br />
    @gamepad.dispose<br />
  end<br />
<br />
  def update_gamepad_status<br />
    return if Input.gamepad_updates.empty?<br />
    type = Input.gamepad_update.to_s<br />
    @gamepad.bitmap.dispose<br />
    @gamepad.bitmap = RPG::Cache.picture(GAMEPAD_PIC + "_" + type)<br />
    @gamepad.visible = true<br />
    @gamepad_timer = GAMEPAD_FRAMES<br />
    @gamepad_pause = true<br />
  end<br />
<br />
  def update_gamepad_timer<br />
    return unless @gamepad_pause<br />
    @gamepad_timer -= 1<br />
    @gamepad_pause = @gamepad_timer &gt; 0<br />
    @gamepad.bitmap.clear unless @gamepad_pause<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">For RMVX &amp; RMVX ACE</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KGamePad HC for VX &amp; ACE * #<br />
#  Scripter : Kyonides<br />
#  2025-11-24<br />
<br />
module KGamePad<br />
  GAMEPAD_PIC = "gamepad_black"<br />
  GAMEPAD_XY = [12, 12]<br />
  GAMEPAD_FRAMES = 90<br />
<br />
  def create_gamepad_icon<br />
    @gamepad_timer = 0<br />
    @gamepad = Sprite.new<br />
    @gamepad.set_xy(*GAMEPAD_XY)<br />
    @gamepad.z = 10000<br />
    @gamepad.visible = false<br />
    @gamepad.bitmap = Bitmap.new(32, 32)<br />
  end<br />
<br />
  def dispose_gamepad_icon<br />
    @gamepad.bitmap.dispose<br />
    @gamepad.dispose<br />
  end<br />
<br />
  def update_gamepad_status<br />
    return if Input.gamepad_updates.empty?<br />
    type = Input.gamepad_update.to_s<br />
    @gamepad.bitmap.dispose<br />
    @gamepad.bitmap = Cache.picture(GAMEPAD_PIC + "_" + type)<br />
    @gamepad.visible = true<br />
    @gamepad_timer = GAMEPAD_FRAMES<br />
    @gamepad_pause = true<br />
  end<br />
<br />
  def update_gamepad_timer<br />
    return unless @gamepad_pause<br />
    @gamepad_timer -= 1<br />
    @gamepad_pause = @gamepad_timer &gt; 0<br />
    @gamepad.bitmap.clear unless @gamepad_pause<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Scene_Title Add-On</span><br />
<span style="font-weight: bold;" class="mycode_b">Works on RMXP, RMVX &amp; RMVX ACE</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>class Scene_Title<br />
  include KGamePad<br />
  alias :kyon_gamepad_scn_ttl_main :main<br />
  alias :kyon_gamepad_scn_ttl_up :update<br />
  def main<br />
    create_gamepad_icon unless &#36;BTEST<br />
    kyon_gamepad_scn_ttl_main<br />
    dispose_gamepad_icon unless &#36;BTEST<br />
  end<br />
<br />
  def update<br />
    update_gamepad_status<br />
    update_gamepad_timer<br />
    kyon_gamepad_scn_ttl_up<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Terms &amp; Conditions</span></span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KGamePad HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
This scriptlet shows you how you can easily implement a gamepad disconnection script.<br />
<br />
The custom module includes all the methods the modified scene scripts would need to include. I also provide you with some XP's Scene_Title script add-on to allow it to display a gamepad icon based on its current status. This script will show you how easily you can implement the module's contents with very few lines of code.<br />
<br />
Just don't forget to <span style="font-weight: bold;" class="mycode_b">include</span> the <span style="font-weight: bold;" class="mycode_b">KGamePad</span> module! <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
<br />
<span style="font-weight: bold;" class="mycode_b">NOTES</span><br />
<br />
The <span style="font-weight: bold;" class="mycode_b">Input.gamepad_update</span> call will return either some <span style="font-weight: bold;" class="mycode_b">:add</span> or <span style="font-weight: bold;" class="mycode_b">:remove</span> symbol. That symbol is first converted to a string and then it is used by my script to define which gamepad icon it should show next.<br />
<br />
<div class="tborder">
  			<div class="thead" style="padding:4px; margin:1px;"><input type="button" class="button" value="+" style="font-family:Monospace; padding:0px" onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].style.display=='none'){ this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='';this.value='-';} else {this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='none';this.value='+';}"/> Screenshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<img src="https://i.postimg.cc/fRTFg06m/gamepad-script001.jpg" loading="lazy"  alt="[Image: gamepad-script001.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/MpK4rjh1/gamepad-script002.jpg" loading="lazy"  alt="[Image: gamepad-script002.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">The Module Script<br />
</span><span style="font-weight: bold;" class="mycode_b">For RMXP</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KGamePad HC for XP * #<br />
#  Scripter : Kyonides<br />
#  2025-11-24<br />
<br />
module KGamePad<br />
  GAMEPAD_PIC = "gamepad_black"<br />
  GAMEPAD_XY = [12, 12]<br />
  GAMEPAD_FRAMES = 90<br />
<br />
  def create_gamepad_icon<br />
    @gamepad_timer = 0<br />
    @gamepad = Sprite.new<br />
    @gamepad.set_xy(*GAMEPAD_XY)<br />
    @gamepad.z = 10000<br />
    @gamepad.visible = false<br />
    @gamepad.bitmap = Bitmap.new(32, 32)<br />
  end<br />
<br />
  def dispose_gamepad_icon<br />
    @gamepad.bitmap.dispose<br />
    @gamepad.dispose<br />
  end<br />
<br />
  def update_gamepad_status<br />
    return if Input.gamepad_updates.empty?<br />
    type = Input.gamepad_update.to_s<br />
    @gamepad.bitmap.dispose<br />
    @gamepad.bitmap = RPG::Cache.picture(GAMEPAD_PIC + "_" + type)<br />
    @gamepad.visible = true<br />
    @gamepad_timer = GAMEPAD_FRAMES<br />
    @gamepad_pause = true<br />
  end<br />
<br />
  def update_gamepad_timer<br />
    return unless @gamepad_pause<br />
    @gamepad_timer -= 1<br />
    @gamepad_pause = @gamepad_timer &gt; 0<br />
    @gamepad.bitmap.clear unless @gamepad_pause<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">For RMVX &amp; RMVX ACE</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KGamePad HC for VX &amp; ACE * #<br />
#  Scripter : Kyonides<br />
#  2025-11-24<br />
<br />
module KGamePad<br />
  GAMEPAD_PIC = "gamepad_black"<br />
  GAMEPAD_XY = [12, 12]<br />
  GAMEPAD_FRAMES = 90<br />
<br />
  def create_gamepad_icon<br />
    @gamepad_timer = 0<br />
    @gamepad = Sprite.new<br />
    @gamepad.set_xy(*GAMEPAD_XY)<br />
    @gamepad.z = 10000<br />
    @gamepad.visible = false<br />
    @gamepad.bitmap = Bitmap.new(32, 32)<br />
  end<br />
<br />
  def dispose_gamepad_icon<br />
    @gamepad.bitmap.dispose<br />
    @gamepad.dispose<br />
  end<br />
<br />
  def update_gamepad_status<br />
    return if Input.gamepad_updates.empty?<br />
    type = Input.gamepad_update.to_s<br />
    @gamepad.bitmap.dispose<br />
    @gamepad.bitmap = Cache.picture(GAMEPAD_PIC + "_" + type)<br />
    @gamepad.visible = true<br />
    @gamepad_timer = GAMEPAD_FRAMES<br />
    @gamepad_pause = true<br />
  end<br />
<br />
  def update_gamepad_timer<br />
    return unless @gamepad_pause<br />
    @gamepad_timer -= 1<br />
    @gamepad_pause = @gamepad_timer &gt; 0<br />
    @gamepad.bitmap.clear unless @gamepad_pause<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Scene_Title Add-On</span><br />
<span style="font-weight: bold;" class="mycode_b">Works on RMXP, RMVX &amp; RMVX ACE</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>class Scene_Title<br />
  include KGamePad<br />
  alias :kyon_gamepad_scn_ttl_main :main<br />
  alias :kyon_gamepad_scn_ttl_up :update<br />
  def main<br />
    create_gamepad_icon unless &#36;BTEST<br />
    kyon_gamepad_scn_ttl_main<br />
    dispose_gamepad_icon unless &#36;BTEST<br />
  end<br />
<br />
  def update<br />
    update_gamepad_status<br />
    update_gamepad_timer<br />
    kyon_gamepad_scn_ttl_up<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Terms &amp; Conditions</span></span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[FileIni HC]]></title>
			<link>https://www.save-point.org/thread-11612.html</link>
			<pubDate>Tue, 15 Jul 2025 06:24:18 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-11612.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">FileIni HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
This is a scripting tool that allows you to read or write or comment out entries in Windows INI files using <span style="font-weight: bold;" class="mycode_b">Ruby 2.7 syntax</span>.<br />
It is totally cross-platform due to using pure <img src="https://www.save-point.org/images/smilies/ejlol/ruby.gif" alt="Ruby" title="Ruby" class="smilie smilie_233" /> Ruby code only.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">The Basics</span></span><br />
<br />
This script differs from the typical Win32API calls that let you access the INI files.<br />
Instead of opening the file every single time you want to read or write an entry to the file, opening the INI file first is a mandatory step here.<br />
<br />
There are 2 ways to open the file:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>handle = FileIni.new("File.ini")<br />
handle2 = FileIni.open("Some.ini")</code></div></div><br />
Once it has been opened, you can call the read, write and comment_out methods at will.<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>handle.read("Section1", "Entry1", "Default1")<br />
handle.write("Section2", "Entry10", "NewValue")<br />
handle.comment_out("Section3", "Entry20", "Default")</code></div></div><br />
There is no need to close the target file because the script only access it via new or open and when it is writing a new or old entry to that file.<br />
<br />
If the file does not exist at all, you will be able to read an error message like the following:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>YourFile.ini file could not be found!<br />
A new INI file will be created!<br />
Backtrace:<br />
FileIni:in 'initialize'<br />
FileIni:in 'exist?'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">The Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * FileIni Class - HC Version * #<br />
#  Scripter : Kyonides<br />
#  2025-07-15<br />
<br />
# This scripting tool lets you open, cache and write contents to INI files.<br />
<br />
class FileIni<br />
  class NoError<br />
    def initialize<br />
      @message = "Everything is working fine."<br />
      @backtrace = []<br />
    end<br />
    attr_accessor :message<br />
    attr_reader :backtrace<br />
  end<br />
<br />
  class NoFileError &lt; NoError<br />
    def set(filename)<br />
      @message = filename + " file could not be found!&#92;n" +<br />
                "A new INI file will be created!"<br />
      if @backtrace.empty?<br />
        @backtrace &lt;&lt; "Backtrace:"<br />
        @backtrace &lt;&lt; "FileIni:in 'initialize'"<br />
        @backtrace &lt;&lt; "FileIni:in 'exist?'"<br />
      end<br />
    end<br />
  end<br />
<br />
  class Section<br />
    def initialize(name)<br />
      @name = name<br />
      @keys = []<br />
      @values = []<br />
      @lines = []<br />
    end<br />
    attr_reader :name, :keys, :values, :lines<br />
  end<br />
<br />
  @@last = nil<br />
  @@last_error = NoError.new<br />
  attr_reader :filename, :section_names<br />
  def initialize(filename)<br />
    @filename = filename<br />
    @section_names = []<br />
    @sections = []<br />
    @@last = self<br />
    if File.exist?(filename)<br />
      lines = File.readlines(filename)<br />
    else<br />
      @@last_error = NoFileError.new<br />
      @@last_error.set(filename)<br />
      version = Game::RGSS_VERSION<br />
      if version == 3<br />
        msgbox set_error_str<br />
      else<br />
        print set_error_str<br />
      end<br />
      File.open(filename, "w") {}<br />
      return<br />
    end<br />
    section = nil<br />
    lines.size.times do |n|<br />
      line = lines[n]<br />
      key, value = line.split(/[&#92;s]{0,}=[&#92;s]{0,}/i)<br />
      if !value and !line[/=/]<br />
        name = key.gsub(/&#92;[|&#92;]/, "").chomp<br />
        @section_names &lt;&lt; name<br />
        @sections &lt;&lt; section = Section.new(name)<br />
        next<br />
      end<br />
      section.keys &lt;&lt; key<br />
      section.values &lt;&lt; (value ? value.chomp : "")<br />
      section.lines &lt;&lt; line<br />
    end<br />
  end<br />
<br />
  def self.open(filename)<br />
    FileIni.new(filename)<br />
  end<br />
<br />
  def self.last<br />
    unless @@last<br />
      raise "Failed to load INI data!&#92;n" +<br />
            "Did you forget to open that file first?"<br />
      return<br />
    end<br />
    @@last.filename<br />
  end<br />
<br />
  def self.get_last_error<br />
    set_error_str<br />
  end<br />
<br />
  def self.flush_error<br />
    @@last_error = NoError.new<br />
  end<br />
<br />
  def read(section_name, key, default)<br />
    n = @section_names.index(section_name)<br />
    section = @sections[n]<br />
    n = section.keys.index(key)<br />
    value = section.values[n]<br />
    value&amp;.empty? ? default : value<br />
  rescue<br />
    default<br />
  end<br />
<br />
  def write(section_name, key, value)<br />
    section = find_section(section_name)<br />
    keys = section.keys<br />
    n = find_key_index(section.keys, key, false)<br />
    section.keys[n] = key<br />
    section.values[n] = value.to_s<br />
    section.lines[n] = key + "=#{value}&#92;r&#92;n"<br />
    write_all_entries<br />
    return value.size<br />
  rescue =&gt; @@last_error<br />
    return 0<br />
  end<br />
<br />
  def comment_out(section_name, key, default)<br />
    section = find_section(section_name)<br />
    keys = section.keys<br />
    n = find_key_index(section.keys, key, true)<br />
    section.keys[n] = ";" + key<br />
    value = section.values[n] || default.to_s<br />
    section.values[n] = value<br />
    section.lines[n] = ";#{key}=#{value}&#92;r&#92;n"<br />
    write_all_entries<br />
    return value.size<br />
  rescue =&gt; @@last_error<br />
    return 0<br />
  end<br />
  private<br />
  def set_error_str<br />
    msg = "#{@@last_error.class}&#92;n#{@@last_error.message}&#92;n"<br />
    msg += @@last_error.backtrace.join("&#92;n")<br />
    msg<br />
  end<br />
<br />
  def find_section(section_name)<br />
    n = @section_names.index(section_name)<br />
    section = @sections[n]<br />
    unless section<br />
      section = Section.new(section_name)<br />
      @sections &lt;&lt; section<br />
    end<br />
    section<br />
  end<br />
<br />
  def find_key_index(keys, key, commented)<br />
    this_key = commented ? ";" + key : key<br />
    n = keys.index(this_key)<br />
    unless n<br />
      this_key = commented ? key : ";" + key<br />
      n = keys.index(this_key) || keys.size<br />
    end<br />
    n<br />
  end<br />
<br />
  def write_all_entries<br />
    File.open(@filename, "w") do |f|<br />
      @sections.each do |section|<br />
        f.puts "[#{section.name}]"<br />
        f.puts section.lines<br />
      end<br />
    end<br />
  end<br />
end</code></div></div><br />
Basic Online Help File Now Available on <span style="font-weight: bold;" class="mycode_b"><a href="https://github.com/kyonides/hiddenchest_linux/tree/main/extras/help" target="_blank" rel="noopener" class="mycode_url">hiddenchest/extras/help</a></span>.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Terms &amp; Conditions</span></span><br />
<br />
The same as HiddenChest Engine's. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" />]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">FileIni HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
This is a scripting tool that allows you to read or write or comment out entries in Windows INI files using <span style="font-weight: bold;" class="mycode_b">Ruby 2.7 syntax</span>.<br />
It is totally cross-platform due to using pure <img src="https://www.save-point.org/images/smilies/ejlol/ruby.gif" alt="Ruby" title="Ruby" class="smilie smilie_233" /> Ruby code only.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">The Basics</span></span><br />
<br />
This script differs from the typical Win32API calls that let you access the INI files.<br />
Instead of opening the file every single time you want to read or write an entry to the file, opening the INI file first is a mandatory step here.<br />
<br />
There are 2 ways to open the file:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>handle = FileIni.new("File.ini")<br />
handle2 = FileIni.open("Some.ini")</code></div></div><br />
Once it has been opened, you can call the read, write and comment_out methods at will.<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>handle.read("Section1", "Entry1", "Default1")<br />
handle.write("Section2", "Entry10", "NewValue")<br />
handle.comment_out("Section3", "Entry20", "Default")</code></div></div><br />
There is no need to close the target file because the script only access it via new or open and when it is writing a new or old entry to that file.<br />
<br />
If the file does not exist at all, you will be able to read an error message like the following:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>YourFile.ini file could not be found!<br />
A new INI file will be created!<br />
Backtrace:<br />
FileIni:in 'initialize'<br />
FileIni:in 'exist?'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">The Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * FileIni Class - HC Version * #<br />
#  Scripter : Kyonides<br />
#  2025-07-15<br />
<br />
# This scripting tool lets you open, cache and write contents to INI files.<br />
<br />
class FileIni<br />
  class NoError<br />
    def initialize<br />
      @message = "Everything is working fine."<br />
      @backtrace = []<br />
    end<br />
    attr_accessor :message<br />
    attr_reader :backtrace<br />
  end<br />
<br />
  class NoFileError &lt; NoError<br />
    def set(filename)<br />
      @message = filename + " file could not be found!&#92;n" +<br />
                "A new INI file will be created!"<br />
      if @backtrace.empty?<br />
        @backtrace &lt;&lt; "Backtrace:"<br />
        @backtrace &lt;&lt; "FileIni:in 'initialize'"<br />
        @backtrace &lt;&lt; "FileIni:in 'exist?'"<br />
      end<br />
    end<br />
  end<br />
<br />
  class Section<br />
    def initialize(name)<br />
      @name = name<br />
      @keys = []<br />
      @values = []<br />
      @lines = []<br />
    end<br />
    attr_reader :name, :keys, :values, :lines<br />
  end<br />
<br />
  @@last = nil<br />
  @@last_error = NoError.new<br />
  attr_reader :filename, :section_names<br />
  def initialize(filename)<br />
    @filename = filename<br />
    @section_names = []<br />
    @sections = []<br />
    @@last = self<br />
    if File.exist?(filename)<br />
      lines = File.readlines(filename)<br />
    else<br />
      @@last_error = NoFileError.new<br />
      @@last_error.set(filename)<br />
      version = Game::RGSS_VERSION<br />
      if version == 3<br />
        msgbox set_error_str<br />
      else<br />
        print set_error_str<br />
      end<br />
      File.open(filename, "w") {}<br />
      return<br />
    end<br />
    section = nil<br />
    lines.size.times do |n|<br />
      line = lines[n]<br />
      key, value = line.split(/[&#92;s]{0,}=[&#92;s]{0,}/i)<br />
      if !value and !line[/=/]<br />
        name = key.gsub(/&#92;[|&#92;]/, "").chomp<br />
        @section_names &lt;&lt; name<br />
        @sections &lt;&lt; section = Section.new(name)<br />
        next<br />
      end<br />
      section.keys &lt;&lt; key<br />
      section.values &lt;&lt; (value ? value.chomp : "")<br />
      section.lines &lt;&lt; line<br />
    end<br />
  end<br />
<br />
  def self.open(filename)<br />
    FileIni.new(filename)<br />
  end<br />
<br />
  def self.last<br />
    unless @@last<br />
      raise "Failed to load INI data!&#92;n" +<br />
            "Did you forget to open that file first?"<br />
      return<br />
    end<br />
    @@last.filename<br />
  end<br />
<br />
  def self.get_last_error<br />
    set_error_str<br />
  end<br />
<br />
  def self.flush_error<br />
    @@last_error = NoError.new<br />
  end<br />
<br />
  def read(section_name, key, default)<br />
    n = @section_names.index(section_name)<br />
    section = @sections[n]<br />
    n = section.keys.index(key)<br />
    value = section.values[n]<br />
    value&amp;.empty? ? default : value<br />
  rescue<br />
    default<br />
  end<br />
<br />
  def write(section_name, key, value)<br />
    section = find_section(section_name)<br />
    keys = section.keys<br />
    n = find_key_index(section.keys, key, false)<br />
    section.keys[n] = key<br />
    section.values[n] = value.to_s<br />
    section.lines[n] = key + "=#{value}&#92;r&#92;n"<br />
    write_all_entries<br />
    return value.size<br />
  rescue =&gt; @@last_error<br />
    return 0<br />
  end<br />
<br />
  def comment_out(section_name, key, default)<br />
    section = find_section(section_name)<br />
    keys = section.keys<br />
    n = find_key_index(section.keys, key, true)<br />
    section.keys[n] = ";" + key<br />
    value = section.values[n] || default.to_s<br />
    section.values[n] = value<br />
    section.lines[n] = ";#{key}=#{value}&#92;r&#92;n"<br />
    write_all_entries<br />
    return value.size<br />
  rescue =&gt; @@last_error<br />
    return 0<br />
  end<br />
  private<br />
  def set_error_str<br />
    msg = "#{@@last_error.class}&#92;n#{@@last_error.message}&#92;n"<br />
    msg += @@last_error.backtrace.join("&#92;n")<br />
    msg<br />
  end<br />
<br />
  def find_section(section_name)<br />
    n = @section_names.index(section_name)<br />
    section = @sections[n]<br />
    unless section<br />
      section = Section.new(section_name)<br />
      @sections &lt;&lt; section<br />
    end<br />
    section<br />
  end<br />
<br />
  def find_key_index(keys, key, commented)<br />
    this_key = commented ? ";" + key : key<br />
    n = keys.index(this_key)<br />
    unless n<br />
      this_key = commented ? key : ";" + key<br />
      n = keys.index(this_key) || keys.size<br />
    end<br />
    n<br />
  end<br />
<br />
  def write_all_entries<br />
    File.open(@filename, "w") do |f|<br />
      @sections.each do |section|<br />
        f.puts "[#{section.name}]"<br />
        f.puts section.lines<br />
      end<br />
    end<br />
  end<br />
end</code></div></div><br />
Basic Online Help File Now Available on <span style="font-weight: bold;" class="mycode_b"><a href="https://github.com/kyonides/hiddenchest_linux/tree/main/extras/help" target="_blank" rel="noopener" class="mycode_url">hiddenchest/extras/help</a></span>.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Terms &amp; Conditions</span></span><br />
<br />
The same as HiddenChest Engine's. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" />]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[KPointsLotto HC]]></title>
			<link>https://www.save-point.org/thread-9402.html</link>
			<pubDate>Sun, 15 Sep 2024 06:51:49 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-9402.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-size: x-large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">KPointsLotto HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Introduction</span></span><br />
<br />
This is a short script that will let you configure two kinds of twin skills, an HP or an SP alias MP regeneration skill. What's new here? It will let you set the points percent your hero might earn or lose! That's pretty much why I say it's a good skill for bosses! <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /> <br />
<br />
<span style="font-weight: bold;" class="mycode_b">HiddenChest and mkxp Version (XP only)</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KPointsLotto HiddenChest<br />
#   Scripter : Kyonides Arkanthes<br />
#   2019-10-25<br />
# This scriptlet will let you define skills that might heal or damage its<br />
# target or recover or burn its mana depending on luck alone!<br />
# It might be some good skills for boss battles...<br />
module KPLotto<br />
  LIFE_SKILL_ID = 3<br />
  MANA_SKILL_ID = 4<br />
  LIFE_RANGE = -40..25 # Percent you can lose or earn<br />
  MANA_RANGE = -35..10 # Percent you can lose or earn<br />
end<br />
# HiddenChest and mkxp<br />
class Game_Battler<br />
  alias :kyon_plotto_gm_battler_se :skill_effect<br />
  def skill_effect(user, skill)<br />
    result = kyon_plotto_gm_battler_se(user, skill)<br />
    if result<br />
      if KPLotto::LIFE_SKILL_ID == skill.id<br />
        @damage = @hp * rand(KPLotto::LIFE_RANGE) / 100<br />
        self.hp += @damage<br />
      elsif KPLotto::MANA_SKILL_ID == skill.id<br />
        @damage = @sp * rand(KPLotto::MANA_RANGE) / 100<br />
        self.sp += @damage<br />
      end<br />
    end<br />
    result<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
You must include my nickname and the current website's URL in your game credits.<br />
I don't know if this scriptlet should be 100% free or not so stay tune! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
Give me a free copy of your completed game if you include at least 2 of my scripts! <img src="https://www.save-point.org/images/smilies/ejlol/laughingtongue.gif" alt="Laughing + Tongue sticking out" title="Laughing + Tongue sticking out" class="smilie smilie_30" />]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-size: x-large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">KPointsLotto HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Introduction</span></span><br />
<br />
This is a short script that will let you configure two kinds of twin skills, an HP or an SP alias MP regeneration skill. What's new here? It will let you set the points percent your hero might earn or lose! That's pretty much why I say it's a good skill for bosses! <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /> <br />
<br />
<span style="font-weight: bold;" class="mycode_b">HiddenChest and mkxp Version (XP only)</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KPointsLotto HiddenChest<br />
#   Scripter : Kyonides Arkanthes<br />
#   2019-10-25<br />
# This scriptlet will let you define skills that might heal or damage its<br />
# target or recover or burn its mana depending on luck alone!<br />
# It might be some good skills for boss battles...<br />
module KPLotto<br />
  LIFE_SKILL_ID = 3<br />
  MANA_SKILL_ID = 4<br />
  LIFE_RANGE = -40..25 # Percent you can lose or earn<br />
  MANA_RANGE = -35..10 # Percent you can lose or earn<br />
end<br />
# HiddenChest and mkxp<br />
class Game_Battler<br />
  alias :kyon_plotto_gm_battler_se :skill_effect<br />
  def skill_effect(user, skill)<br />
    result = kyon_plotto_gm_battler_se(user, skill)<br />
    if result<br />
      if KPLotto::LIFE_SKILL_ID == skill.id<br />
        @damage = @hp * rand(KPLotto::LIFE_RANGE) / 100<br />
        self.hp += @damage<br />
      elsif KPLotto::MANA_SKILL_ID == skill.id<br />
        @damage = @sp * rand(KPLotto::MANA_RANGE) / 100<br />
        self.sp += @damage<br />
      end<br />
    end<br />
    result<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
You must include my nickname and the current website's URL in your game credits.<br />
I don't know if this scriptlet should be 100% free or not so stay tune! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
Give me a free copy of your completed game if you include at least 2 of my scripts! <img src="https://www.save-point.org/images/smilies/ejlol/laughingtongue.gif" alt="Laughing + Tongue sticking out" title="Laughing + Tongue sticking out" class="smilie smilie_30" />]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[BGM No Loop]]></title>
			<link>https://www.save-point.org/thread-8961.html</link>
			<pubDate>Thu, 06 Jun 2024 05:32:22 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-8961.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">BGM No Loop </span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">HiddenChest Exclusive!</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">XP Related<br />
<br />
by Kyonides</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
This is a simple scriplet that will let RMXP users play one BGM after another based on which map ID's are included in the MAP_BGM array.<br />
<br />
There still is one important detail you must know: <span style="font-weight: bold;" class="mycode_b">Audio.bgm_loop</span> is set to <span style="font-weight: bold;" class="mycode_b">true</span>, meaning that all the other maps will keep playing the same old song. <img src="https://www.save-point.org/images/smilies/ejlol/metalhead.gif" alt="Metalhead" title="Metalhead" class="smilie smilie_162" /> <img src="https://www.save-point.org/images/smilies/ejlol/rapper.gif" alt="Rapper" title="Rapper" class="smilie smilie_227" /> <br />
<br />
<span style="font-weight: bold;" class="mycode_b">Warning</span><br />
<br />
You need to be using HiddenChest version <span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">1.1.81</span><span style="font-style: italic;" class="mycode_i"> or later!</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Script for RMXP Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * BGM No Loop XP * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   2024-06-13<br />
<br />
# This scriptlet allows you to prevent the game from playing the same old song<br />
# over and over again. Now you can define a list of BGMs for specific maps!<br />
<br />
module BgmNoLoop<br />
  WAIT = 20<br />
  VOLUME = 60<br />
  MAP_BGM = {}<br />
  MAP_BGM[1] = ["015-Theme04", "017-Theme06"]<br />
end<br />
<br />
class Game_Map<br />
  alias :kyon_bgm_no_loop_gm_map_setup :setup<br />
  def setup(map_id)<br />
    check_bgm_loop(map_id)<br />
    kyon_bgm_no_loop_gm_map_setup(map_id)<br />
  end<br />
<br />
  def check_bgm_loop(map_id)<br />
    Audio.bgm_loop = !BgmNoLoop::MAP_BGM.has_key?(map_id)<br />
    puts "Check Loop in Map ##{map_id}: " + Audio.bgm_loop.to_s<br />
  end<br />
<br />
  def map_bgm<br />
    @map.bgm<br />
  end<br />
<br />
  def find_bgms<br />
    bgm = @map.bgm<br />
    &#36;game_system.bgm_volume = bgm.volume<br />
    bgms = []<br />
    bgms &lt;&lt; bgm unless bgm.name.empty?<br />
    bgms + BgmNoLoop::MAP_BGM[@map_id]<br />
  end<br />
end<br />
<br />
class Game_System<br />
  alias :kyon_bgm_no_loop_gm_sys_init :initialize<br />
  alias :kyon_bgm_no_loop_gm_sys_up :update<br />
  def initialize<br />
    kyon_bgm_no_loop_gm_sys_init<br />
    reset_bgm_timer<br />
    reset_bgm_volume<br />
    @bgm_index = 0<br />
  end<br />
<br />
  def reset_bgm_timer<br />
    @bgm_timer = BgmNoLoop::WAIT<br />
  end<br />
<br />
  def reset_bgm_volume<br />
    @bgm_volume ||= BgmNoLoop::VOLUME<br />
  end<br />
<br />
  def update<br />
    kyon_bgm_no_loop_gm_sys_up<br />
    return if &#36;game_temp.in_battle or Audio.bgm_playing?<br />
    return if Audio.bgm_loop<br />
    if @bgm_timer &gt; 0<br />
      @bgm_timer -= 1<br />
      return<br />
    end<br />
    reset_bgm_timer<br />
    bgms = &#36;game_map.find_bgms<br />
    @bgm_index ||= 0<br />
    @bgm_index = (@bgm_index + 1) % bgms.size<br />
    bgm = bgms[@bgm_index]<br />
    bgm = RPG::AudioFile.new(bgm) if bgm.is_a?(String)<br />
    bgm_play(bgm) if bgm != nil<br />
  end<br />
<br />
  def bgm_play(bgm)<br />
    reset_bgm_volume<br />
    @playing_bgm = bgm<br />
    if bgm != nil and bgm.name != ""<br />
      Audio.bgm_play("Audio/BGM/" + bgm.name, @bgm_volume, bgm.pitch)<br />
    else<br />
      Audio.bgm_stop<br />
    end<br />
    Graphics.frame_reset<br />
  end<br />
  attr_accessor :bgm_volume<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" loading="lazy"  alt="[Image: tongue.gif]" class="mycode_img" />]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">BGM No Loop </span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">HiddenChest Exclusive!</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">XP Related<br />
<br />
by Kyonides</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Introduction</span><br />
<br />
This is a simple scriplet that will let RMXP users play one BGM after another based on which map ID's are included in the MAP_BGM array.<br />
<br />
There still is one important detail you must know: <span style="font-weight: bold;" class="mycode_b">Audio.bgm_loop</span> is set to <span style="font-weight: bold;" class="mycode_b">true</span>, meaning that all the other maps will keep playing the same old song. <img src="https://www.save-point.org/images/smilies/ejlol/metalhead.gif" alt="Metalhead" title="Metalhead" class="smilie smilie_162" /> <img src="https://www.save-point.org/images/smilies/ejlol/rapper.gif" alt="Rapper" title="Rapper" class="smilie smilie_227" /> <br />
<br />
<span style="font-weight: bold;" class="mycode_b">Warning</span><br />
<br />
You need to be using HiddenChest version <span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">1.1.81</span><span style="font-style: italic;" class="mycode_i"> or later!</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Script for RMXP Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * BGM No Loop XP * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   2024-06-13<br />
<br />
# This scriptlet allows you to prevent the game from playing the same old song<br />
# over and over again. Now you can define a list of BGMs for specific maps!<br />
<br />
module BgmNoLoop<br />
  WAIT = 20<br />
  VOLUME = 60<br />
  MAP_BGM = {}<br />
  MAP_BGM[1] = ["015-Theme04", "017-Theme06"]<br />
end<br />
<br />
class Game_Map<br />
  alias :kyon_bgm_no_loop_gm_map_setup :setup<br />
  def setup(map_id)<br />
    check_bgm_loop(map_id)<br />
    kyon_bgm_no_loop_gm_map_setup(map_id)<br />
  end<br />
<br />
  def check_bgm_loop(map_id)<br />
    Audio.bgm_loop = !BgmNoLoop::MAP_BGM.has_key?(map_id)<br />
    puts "Check Loop in Map ##{map_id}: " + Audio.bgm_loop.to_s<br />
  end<br />
<br />
  def map_bgm<br />
    @map.bgm<br />
  end<br />
<br />
  def find_bgms<br />
    bgm = @map.bgm<br />
    &#36;game_system.bgm_volume = bgm.volume<br />
    bgms = []<br />
    bgms &lt;&lt; bgm unless bgm.name.empty?<br />
    bgms + BgmNoLoop::MAP_BGM[@map_id]<br />
  end<br />
end<br />
<br />
class Game_System<br />
  alias :kyon_bgm_no_loop_gm_sys_init :initialize<br />
  alias :kyon_bgm_no_loop_gm_sys_up :update<br />
  def initialize<br />
    kyon_bgm_no_loop_gm_sys_init<br />
    reset_bgm_timer<br />
    reset_bgm_volume<br />
    @bgm_index = 0<br />
  end<br />
<br />
  def reset_bgm_timer<br />
    @bgm_timer = BgmNoLoop::WAIT<br />
  end<br />
<br />
  def reset_bgm_volume<br />
    @bgm_volume ||= BgmNoLoop::VOLUME<br />
  end<br />
<br />
  def update<br />
    kyon_bgm_no_loop_gm_sys_up<br />
    return if &#36;game_temp.in_battle or Audio.bgm_playing?<br />
    return if Audio.bgm_loop<br />
    if @bgm_timer &gt; 0<br />
      @bgm_timer -= 1<br />
      return<br />
    end<br />
    reset_bgm_timer<br />
    bgms = &#36;game_map.find_bgms<br />
    @bgm_index ||= 0<br />
    @bgm_index = (@bgm_index + 1) % bgms.size<br />
    bgm = bgms[@bgm_index]<br />
    bgm = RPG::AudioFile.new(bgm) if bgm.is_a?(String)<br />
    bgm_play(bgm) if bgm != nil<br />
  end<br />
<br />
  def bgm_play(bgm)<br />
    reset_bgm_volume<br />
    @playing_bgm = bgm<br />
    if bgm != nil and bgm.name != ""<br />
      Audio.bgm_play("Audio/BGM/" + bgm.name, @bgm_volume, bgm.pitch)<br />
    else<br />
      Audio.bgm_stop<br />
    end<br />
    Graphics.frame_reset<br />
  end<br />
  attr_accessor :bgm_volume<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" loading="lazy"  alt="[Image: tongue.gif]" class="mycode_img" />]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[PrintScene HC]]></title>
			<link>https://www.save-point.org/thread-8958.html</link>
			<pubDate>Mon, 27 May 2024 22:24:48 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-8958.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">PrintScene HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">HiddenChest Exclusive!</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">XP + VX ACE Related</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
This script emulates the behavior of a system's popup window in the maker while running on HiddenChest!<br />
<br />
You can click on the red box or the OK button to close it or even move the sprite around!<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Warning!</span><br />
The only caveat here is that you gotta move it <span style="font-weight: bold;" class="mycode_b"><span style="font-style: italic;" class="mycode_i">slowly</span></span> while pressing the <img src="https://www.save-point.org/images/smilies/ejlol/mouse.gif" alt="Mouse" title="Mouse" class="smilie smilie_134" /> left button on top of the title bar.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Script Call</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>dialog_box("As many", "lines", "as possible")</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">The Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * PrintScene HC * #<br />
#  Scripter : Kyonides Arkanthes<br />
#  2024-05-27<br />
<br />
# * Script Dependency: ClickableWindow<br />
<br />
# This script mimicks what the popup windows do, including letting you move them<br />
# around. The only issue I have found so far is that you need to move it slowly.<br />
<br />
# Script Call: dialog_box("As many", "lines", "as possible")<br />
<br />
module Kernel<br />
  def dialog_box(*lines)<br />
    scene = PrintScene.new(lines)<br />
    scene.main<br />
  end<br />
end<br />
<br />
class PrintSprite &lt; Sprite<br />
  WIDTH = 320<br />
  BUTTON_OK = "OK"<br />
  def initialize(messages, w=WIDTH, vp=nil)<br />
    super(vp)<br />
    @messages = messages<br />
    lines = @messages.size<br />
    h = lines * 32 + 64<br />
    self.x = (Graphics.width - w) / 2<br />
    self.y = (Graphics.height - h) / 2<br />
    self.bitmap = Bitmap.new(w, h)<br />
    @margin_x = 16<br />
    @margin_y = 32<br />
    @mouse_x = Input.mouse_x<br />
    @mouse_y = Input.mouse_y<br />
    @width, @height = Graphics.dimensions<br />
  end<br />
<br />
  def titlebar_color=(color)<br />
    @titlebar_color = color<br />
    w = src_rect.width<br />
    @area &lt;&lt; rect = Rect.new(0, 0, w, 24,)<br />
    self.bitmap.fill_rect(rect, color)<br />
    @area &lt;&lt; rect = Rect.new(w - 22, 2, 20, 20)<br />
    red = Color.new(220, 40, 40)<br />
    self.bitmap.fill_rect(rect, red)<br />
    icon_name = Game::ICON<br />
    if FileInt.exist?(icon_name)<br />
      icon = Bitmap.new(icon_name)<br />
    else<br />
      icon = Bitmap.new("app_logo", nil)<br />
    end<br />
    rect = Rect.new(4, 4, 16, 16)<br />
    self.bitmap.stretch_blt(rect, icon, icon.rect)<br />
    self.bitmap.font.size = 16<br />
    self.bitmap.draw_text(0, 0, w, 24, Game::TITLE, 1)<br />
  end<br />
<br />
  def message_box_color=(color)<br />
    r = src_rect<br />
    rect = Rect.new(@margin_x, r.height - 24, 80, 28)<br />
    self.bitmap.fill_rect(0, 24, r.width, r.height - 24, color)<br />
  end<br />
<br />
  def ok_box_color=(color)<br />
    r = src_rect<br />
    cx = (r.width - 80) / 2<br />
    @area &lt;&lt; rect = Rect.new(cx, r.height - 36, 80, 28)<br />
    self.bitmap.fill_rect(rect, color)<br />
    self.bitmap.font.size = 16<br />
    self.bitmap.draw_text(cx, r.height - 36, 80, 28, BUTTON_OK, 1)<br />
  end<br />
<br />
  def refresh<br />
    w = src_rect.width<br />
    @messages.size.times do |n|<br />
      self.bitmap.draw_text(12, @margin_y + n * 20, w - 24, 18, @messages[n])<br />
    end<br />
    @messages.clear<br />
  end<br />
<br />
  def display<br />
    self.bitmap.font.size = 15<br />
  end<br />
<br />
  def update<br />
    super<br />
    if Input.trigger?(Input::B) or Input.trigger?(Input::C)<br />
      PrintScene.running = nil<br />
    elsif Input.left_click? or Input.right_click?<br />
      1.upto(2) do |n|<br />
        next unless click_area?(n)<br />
        PrintScene.running = nil<br />
        break<br />
      end<br />
    elsif Input.press?(Input::MouseLeft)<br />
      if click_area?(0)<br />
        mx = Input.mouse_x - @mouse_x<br />
        my = Input.mouse_y - @mouse_y<br />
        self.x += mx.clamp(-@width, @width * 2)<br />
        self.y += my.clamp(-@height, @height * 2)<br />
      end<br />
    end<br />
    @mouse_x = Input.mouse_x<br />
    @mouse_y = Input.mouse_y<br />
  end<br />
  attr_reader :titlebar_color<br />
  attr_writer :margin_x, :margin_y<br />
end<br />
<br />
class PrintScene<br />
  def self.running=(state)<br />
    @@running = state<br />
  end<br />
<br />
  def initialize(lines)<br />
    @@running = true<br />
    @messages = lines.map {|line| line.to_s.split("&#92;n") }<br />
    @messages = @messages.flatten.compact<br />
  end<br />
<br />
  def main<br />
    Graphics.freeze<br />
    start<br />
    Graphics.transition<br />
    update_loop<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def start<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = Graphics.snap_to_gray_bitmap.dup<br />
    @print = PrintSprite.new(@messages)<br />
    @print.z = 1000<br />
    black = Color.new(0, 0, 0)<br />
    gray = Color.new(80, 80, 80)<br />
    @print.titlebar_color = black<br />
    @print.message_box_color = gray<br />
    @print.ok_box_color = black<br />
    @print.refresh<br />
  end<br />
<br />
  def update_loop<br />
    while @@running<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
  end<br />
<br />
  def update<br />
    @print.update<br />
    if Input.trigger?(Input::SHIFT)<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
<br />
  def terminate<br />
    @print.bitmap.dispose<br />
    @print.dispose<br />
    @backdrop.bitmap.dispose<br />
    @backdrop.dispose<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">PrintScene HC</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">HiddenChest Exclusive!</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">XP + VX ACE Related</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
This script emulates the behavior of a system's popup window in the maker while running on HiddenChest!<br />
<br />
You can click on the red box or the OK button to close it or even move the sprite around!<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Warning!</span><br />
The only caveat here is that you gotta move it <span style="font-weight: bold;" class="mycode_b"><span style="font-style: italic;" class="mycode_i">slowly</span></span> while pressing the <img src="https://www.save-point.org/images/smilies/ejlol/mouse.gif" alt="Mouse" title="Mouse" class="smilie smilie_134" /> left button on top of the title bar.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Script Call</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>dialog_box("As many", "lines", "as possible")</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">The Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * PrintScene HC * #<br />
#  Scripter : Kyonides Arkanthes<br />
#  2024-05-27<br />
<br />
# * Script Dependency: ClickableWindow<br />
<br />
# This script mimicks what the popup windows do, including letting you move them<br />
# around. The only issue I have found so far is that you need to move it slowly.<br />
<br />
# Script Call: dialog_box("As many", "lines", "as possible")<br />
<br />
module Kernel<br />
  def dialog_box(*lines)<br />
    scene = PrintScene.new(lines)<br />
    scene.main<br />
  end<br />
end<br />
<br />
class PrintSprite &lt; Sprite<br />
  WIDTH = 320<br />
  BUTTON_OK = "OK"<br />
  def initialize(messages, w=WIDTH, vp=nil)<br />
    super(vp)<br />
    @messages = messages<br />
    lines = @messages.size<br />
    h = lines * 32 + 64<br />
    self.x = (Graphics.width - w) / 2<br />
    self.y = (Graphics.height - h) / 2<br />
    self.bitmap = Bitmap.new(w, h)<br />
    @margin_x = 16<br />
    @margin_y = 32<br />
    @mouse_x = Input.mouse_x<br />
    @mouse_y = Input.mouse_y<br />
    @width, @height = Graphics.dimensions<br />
  end<br />
<br />
  def titlebar_color=(color)<br />
    @titlebar_color = color<br />
    w = src_rect.width<br />
    @area &lt;&lt; rect = Rect.new(0, 0, w, 24,)<br />
    self.bitmap.fill_rect(rect, color)<br />
    @area &lt;&lt; rect = Rect.new(w - 22, 2, 20, 20)<br />
    red = Color.new(220, 40, 40)<br />
    self.bitmap.fill_rect(rect, red)<br />
    icon_name = Game::ICON<br />
    if FileInt.exist?(icon_name)<br />
      icon = Bitmap.new(icon_name)<br />
    else<br />
      icon = Bitmap.new("app_logo", nil)<br />
    end<br />
    rect = Rect.new(4, 4, 16, 16)<br />
    self.bitmap.stretch_blt(rect, icon, icon.rect)<br />
    self.bitmap.font.size = 16<br />
    self.bitmap.draw_text(0, 0, w, 24, Game::TITLE, 1)<br />
  end<br />
<br />
  def message_box_color=(color)<br />
    r = src_rect<br />
    rect = Rect.new(@margin_x, r.height - 24, 80, 28)<br />
    self.bitmap.fill_rect(0, 24, r.width, r.height - 24, color)<br />
  end<br />
<br />
  def ok_box_color=(color)<br />
    r = src_rect<br />
    cx = (r.width - 80) / 2<br />
    @area &lt;&lt; rect = Rect.new(cx, r.height - 36, 80, 28)<br />
    self.bitmap.fill_rect(rect, color)<br />
    self.bitmap.font.size = 16<br />
    self.bitmap.draw_text(cx, r.height - 36, 80, 28, BUTTON_OK, 1)<br />
  end<br />
<br />
  def refresh<br />
    w = src_rect.width<br />
    @messages.size.times do |n|<br />
      self.bitmap.draw_text(12, @margin_y + n * 20, w - 24, 18, @messages[n])<br />
    end<br />
    @messages.clear<br />
  end<br />
<br />
  def display<br />
    self.bitmap.font.size = 15<br />
  end<br />
<br />
  def update<br />
    super<br />
    if Input.trigger?(Input::B) or Input.trigger?(Input::C)<br />
      PrintScene.running = nil<br />
    elsif Input.left_click? or Input.right_click?<br />
      1.upto(2) do |n|<br />
        next unless click_area?(n)<br />
        PrintScene.running = nil<br />
        break<br />
      end<br />
    elsif Input.press?(Input::MouseLeft)<br />
      if click_area?(0)<br />
        mx = Input.mouse_x - @mouse_x<br />
        my = Input.mouse_y - @mouse_y<br />
        self.x += mx.clamp(-@width, @width * 2)<br />
        self.y += my.clamp(-@height, @height * 2)<br />
      end<br />
    end<br />
    @mouse_x = Input.mouse_x<br />
    @mouse_y = Input.mouse_y<br />
  end<br />
  attr_reader :titlebar_color<br />
  attr_writer :margin_x, :margin_y<br />
end<br />
<br />
class PrintScene<br />
  def self.running=(state)<br />
    @@running = state<br />
  end<br />
<br />
  def initialize(lines)<br />
    @@running = true<br />
    @messages = lines.map {|line| line.to_s.split("&#92;n") }<br />
    @messages = @messages.flatten.compact<br />
  end<br />
<br />
  def main<br />
    Graphics.freeze<br />
    start<br />
    Graphics.transition<br />
    update_loop<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def start<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = Graphics.snap_to_gray_bitmap.dup<br />
    @print = PrintSprite.new(@messages)<br />
    @print.z = 1000<br />
    black = Color.new(0, 0, 0)<br />
    gray = Color.new(80, 80, 80)<br />
    @print.titlebar_color = black<br />
    @print.message_box_color = gray<br />
    @print.ok_box_color = black<br />
    @print.refresh<br />
  end<br />
<br />
  def update_loop<br />
    while @@running<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
    end<br />
  end<br />
<br />
  def update<br />
    @print.update<br />
    if Input.trigger?(Input::SHIFT)<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
<br />
  def terminate<br />
    @print.bitmap.dispose<br />
    @print.dispose<br />
    @backdrop.bitmap.dispose<br />
    @backdrop.dispose<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[ClickableWindows]]></title>
			<link>https://www.save-point.org/thread-8957.html</link>
			<pubDate>Mon, 27 May 2024 22:16:34 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-8957.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">ClickableWindows</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size"><br />
HiddenChest Exclusive!</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">XP + VX + ACE Related</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b">Warning!</span></div>
<br />
<div style="text-align: center;" class="mycode_align">Other scripts of mine like PrintScene HC depend on this one.</div>
<br />
These scriptlets allow you to <img src="https://www.save-point.org/images/smilies/ejlol/mouse.gif" alt="Mouse" title="Mouse" class="smilie smilie_134" /> click on the usual menu window options! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
<br />
As long as you click on the area defined by the blinking cursor, you will be fine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><br />
<br />
It does not fully support all windows but only child classes of Window_Selectable and a few others.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">The Caveats</span><br />
<br />
They are based on XP's and VX ACE's default scripts. There is no warranty they will work with custom ones.<br />
<br />
Some scenes forced me to add calls like Input.double_left_click? or Input.right_click? to make them work properly.<br />
<br />
<hr class="mycode_hr" />
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Script Section</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Script for the RMXP Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * ClickableWidget XP * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   2026-01-11<br />
<br />
# This is a script demo that shows you how it is now possible to click once on<br />
# a menu window to choose an option while ignoring the surrounding area.<br />
# Normally, you would have to add some calls to Input.left_click? or<br />
# Input.right_click? or even Input.middle_click? to your target scenes to make<br />
# this work.<br />
<br />
class Sprite<br />
  alias :kyon_click_sprite_sprite_up :update<br />
  def update<br />
    kyon_click_sprite_sprite_up<br />
    # Added Draggable Window Check<br />
    check_draggable<br />
    check_mouse_inside<br />
  end<br />
<br />
  def check_draggable<br />
    return unless draggable?<br />
    if Input.press_left_click?<br />
      if Mouse.no_target?<br />
        if mouse_inside_color? and drag_color?<br />
          Mouse.target = self<br />
          @mouse_x = Mouse.x<br />
          @mouse_y = Mouse.y<br />
        end<br />
      elsif Mouse.target?(self)<br />
        self.x += Mouse.x - @mouse_x<br />
        self.y += Mouse.y - @mouse_y<br />
        @mouse_x = Mouse.x<br />
        @mouse_y = Mouse.y<br />
      end<br />
      return<br />
    elsif Mouse.target?(self)<br />
      Mouse.target = nil<br />
    end<br />
  end<br />
<br />
  def hover_can_change?<br />
    return false if @hover_changed<br />
    return false if @base_name.nil? or @base_name.empty?<br />
    return false if @hover_name.nil? or @hover_name.empty?<br />
    @hover_filetype != nil<br />
  end<br />
<br />
  def check_mouse_inside<br />
    return if Mouse.target?(self)<br />
    if mouse_inside?<br />
      if hover_can_change?<br />
        set_hover_bitmap<br />
        @hover_changed = true<br />
        return<br />
      end<br />
    elsif @hover_changed<br />
      self.bitmap.dispose<br />
      set_base_bitmap<br />
      @hover_changed = false<br />
    end<br />
  end<br />
<br />
  def set_hover_bitmap<br />
    filetype = @hover_filetype.to_sym<br />
    case filetype<br />
    when :battler <br />
      self.bitmap = RPG::Cache.battler(@hover_name, @hover_hue)<br />
    when :character<br />
      self.bitmap = RPG::Cache.character(@hover_name, @hover_hue)<br />
    when :icon<br />
      self.bitmap = RPG::Cache.icon(@hover_name)<br />
    when :picture<br />
      self.bitmap = RPG::Cache.picture(@hover_name)<br />
    end<br />
  end<br />
<br />
  def set_base_bitmap<br />
    filetype = @hover_filetype.to_sym<br />
    case filetype<br />
    when :battler <br />
      self.bitmap = RPG::Cache.battler(@base_name, @hover_hue)<br />
    when :character<br />
      self.bitmap = RPG::Cache.character(@base_name, @hover_hue)<br />
    when :icon<br />
      self.bitmap = RPG::Cache.icon(@base_name)<br />
    when :picture<br />
      self.bitmap = RPG::Cache.picture(@base_name)<br />
    end<br />
  end<br />
end<br />
<br />
class Window_Base<br />
  def update<br />
    super<br />
    if &#36;game_system.windowskin_name != @windowskin_name<br />
      @windowskin_name = &#36;game_system.windowskin_name<br />
      self.windowskin = RPG::Cache.windowskin(@windowskin_name)<br />
    end<br />
    # Added Draggable Window Check<br />
    check_draggable<br />
  end<br />
<br />
  def check_draggable<br />
    return unless draggable?<br />
    if Input.press_left_click?<br />
      if Mouse.no_target? and mouse_inside?<br />
        Mouse.target = self<br />
        @mouse_x = Mouse.x<br />
        @mouse_y = Mouse.y<br />
      elsif Mouse.target?(self)<br />
        self.x += Mouse.x - @mouse_x<br />
        self.y += Mouse.y - @mouse_y<br />
        @mouse_x = Mouse.x<br />
        @mouse_y = Mouse.y<br />
      end<br />
      return<br />
    elsif Mouse.target?(self)<br />
      Mouse.target = nil<br />
    end<br />
  end<br />
end<br />
<br />
class Window_Selectable<br />
  def one_click_selection<br />
    # Set Index to invisible if clicked outside this window<br />
    self.index = -1<br />
    # Check each area - a list of Rect's<br />
    @area.size.times do |n|<br />
      next unless mouse_inside?(n)<br />
      self.index = n<br />
      break<br />
    end<br />
  end<br />
<br />
  def update<br />
    super<br />
    return unless self.active<br />
    return if @item_max == 0<br />
    # Added Left Click Check<br />
    if Input.left_click?<br />
      one_click_selection<br />
      return<br />
    end<br />
    if mouse_inside?<br />
      if Mouse.scroll_y?(:UP)<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        self.index = (@index - @column_max) % @item_max<br />
        return<br />
      elsif Mouse.scroll_y?(:DOWN)<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        self.index = (@index + @column_max) % @item_max<br />
        return<br />
      end<br />
    end<br />
    if Input.repeat?(Input::DOWN)<br />
      if (@column_max == 1 and Input.trigger?(Input::DOWN)) or<br />
         @index &lt; @item_max - @column_max<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index = (@index + @column_max) % @item_max<br />
      end<br />
    end<br />
    if Input.repeat?(Input::UP)<br />
      if (@column_max == 1 and Input.trigger?(Input::UP)) or<br />
         @index &gt;= @column_max<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index = (@index - @column_max + @item_max) % @item_max<br />
      end<br />
    end<br />
    if Input.repeat?(Input::RIGHT)<br />
      if @column_max &gt;= 2 and @index &lt; @item_max - 1<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index += 1<br />
      end<br />
    end<br />
    if Input.repeat?(Input::LEFT)<br />
      if @column_max &gt;= 2 and @index &gt; 0<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index -= 1<br />
      end<br />
    end<br />
    if Input.repeat?(Input::R)<br />
      if self.top_row + (self.page_row_max - 1) &lt; (self.row_max - 1)<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index = [@index + self.page_item_max, @item_max - 1].min<br />
        self.top_row += self.page_row_max<br />
      end<br />
    end<br />
    if Input.repeat?(Input::L)<br />
      if self.top_row &gt; 0<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index = [@index - self.page_item_max, 0].max<br />
        self.top_row -= self.page_row_max<br />
      end<br />
    end<br />
    if self.active and @help_window != nil<br />
      update_help if @index &gt;= 0<br />
    end<br />
    update_cursor_rect<br />
  end<br />
 <br />
  def get_area_rect(n)<br />
    rw = self.width / @column_max - 32<br />
    rx = 8 + n % @column_max * (rw + 32)<br />
    ry = n / @column_max * 32 - self.oy<br />
    Rect.new(rx, ry, rw, 32)<br />
  end<br />
end<br />
<br />
class Window_Command<br />
  def draw_item(n, color)<br />
    @area[n] ||= get_area_rect(n)<br />
    c = self.contents<br />
    c.font.color = color<br />
    rect = Rect.new(4, 32 * n, c.width - 8, 32)<br />
    c.fill_rect(rect, Color.new(0, 0, 0, 0))<br />
    c.draw_text(rect, @commands[n])<br />
  end<br />
end<br />
<br />
class Window_MenuStatus<br />
  def refresh<br />
    self.contents.clear<br />
    @item_max = &#36;game_party.actors.size<br />
    for i in 0...&#36;game_party.actors.size<br />
      x = 64<br />
      y = i * 116<br />
      @area[i] ||= Rect.new(0, i * 116, self.width - 32, 96)<br />
      actor = &#36;game_party.actors[i]<br />
      draw_actor_graphic(actor, x - 40, y + 80)<br />
      draw_actor_name(actor, x, y)<br />
      draw_actor_class(actor, x + 144, y)<br />
      draw_actor_level(actor, x, y + 32)<br />
      draw_actor_state(actor, x + 90, y + 32)<br />
      draw_actor_exp(actor, x, y + 64)<br />
      draw_actor_hp(actor, x + 236, y + 32)<br />
      draw_actor_sp(actor, x + 236, y + 64)<br />
    end<br />
  end<br />
end<br />
<br />
class Window_Target<br />
  def refresh<br />
    self.contents.clear<br />
    for i in 0...&#36;game_party.actors.size<br />
      x = 4<br />
      y = i * 116<br />
      @area[i] ||= Rect.new(0, i * 116, self.width - 32, 96)<br />
      actor = &#36;game_party.actors[i]<br />
      draw_actor_name(actor, x, y)<br />
      draw_actor_class(actor, x + 144, y)<br />
      draw_actor_level(actor, x + 8, y + 32)<br />
      draw_actor_state(actor, x + 8, y + 64)<br />
      draw_actor_hp(actor, x + 152, y + 32)<br />
      draw_actor_sp(actor, x + 152, y + 64)<br />
    end<br />
  end<br />
end<br />
<br />
class Window_EquipRight<br />
  def initialize(actor)<br />
    super(272, 64, 368, 192)<br />
    @click_width = width - 32<br />
    self.contents = Bitmap.new(@click_width, height - 32)<br />
    @actor = actor<br />
    create_areas<br />
    refresh<br />
    self.index = 0<br />
  end<br />
<br />
  def create_areas<br />
    5.times {|n| @area &lt;&lt; Rect.new(4, 32 * n, @click_width, 32) }<br />
  end<br />
end<br />
<br />
class Window_SaveFile<br />
  alias :kyon_click_win_win_svfl_init :initialize<br />
  def initialize(file_index, filename)<br />
    kyon_click_win_win_svfl_init(file_index, filename)<br />
    @area &lt;&lt; self.contents.rect<br />
  end<br />
end<br />
<br />
class Window_Message<br />
  alias :kyon_click_win_win_mess_init :initialize<br />
  def initialize<br />
    kyon_click_win_win_mess_init<br />
    self.pause_x = self.width - 80<br />
  end<br />
end<br />
<br />
class Scene_Title<br />
  LOGO = "icon_sound"<br />
  def load_database<br />
    &#36;data_actors        = load_data("Data/Actors.rxdata")<br />
    &#36;data_classes       = load_data("Data/Classes.rxdata")<br />
    &#36;data_skills        = load_data("Data/Skills.rxdata")<br />
    &#36;data_items         = load_data("Data/Items.rxdata")<br />
    &#36;data_weapons       = load_data("Data/Weapons.rxdata")<br />
    &#36;data_armors        = load_data("Data/Armors.rxdata")<br />
    &#36;data_enemies       = load_data("Data/Enemies.rxdata")<br />
    &#36;data_troops        = load_data("Data/Troops.rxdata")<br />
    &#36;data_states        = load_data("Data/States.rxdata")<br />
    &#36;data_animations    = load_data("Data/Animations.rxdata")<br />
    &#36;data_tilesets      = load_data("Data/Tilesets.rxdata")<br />
    &#36;data_common_events = load_data("Data/CommonEvents.rxdata")<br />
    &#36;data_system        = load_data("Data/System.rxdata")<br />
  end<br />
<br />
  def reset_game_system<br />
    &#36;game_system = Game_System.new<br />
  end<br />
<br />
  def start<br />
    create_backdrop<br />
    create_command_window<br />
    create_title<br />
    create_extras<br />
    check_continue<br />
    setup_audio<br />
  end<br />
<br />
  def create_backdrop<br />
    @sprite = Sprite.new<br />
    @sprite.bitmap = RPG::Cache.title(&#36;data_system.title_name)<br />
  end<br />
<br />
  def create_command_window<br />
    s1 = "New Game"<br />
    s2 = "Continue"<br />
    s3 = "Shutdown"<br />
    @command_window = Window_Command.new(192, [s1, s2, s3])<br />
    @command_window.back_opacity = 160<br />
    @command_window.x = 320 - @command_window.width / 2<br />
    @command_window.y = 288<br />
    @command_window.draggable = true<br />
  end<br />
<br />
  def create_title<br />
    @title = Sprite.new<br />
    @title.set_xyz(0, 60, 100)<br />
    @title.bitmap = b = Bitmap.new(Graphics.width, 60)<br />
    font = b.font<br />
    font.size = 52<br />
    font.outline = true<br />
    font.outline_size = 4<br />
    b.draw_text(b.rect, Game::TITLE, 1)<br />
  end<br />
<br />
  def create_extras<br />
    @logo = Sprite.new<br />
    @logo.set_xyz(24, 24, 100)<br />
    @logo.drag_condition = :color<br />
    @logo.base_name = LOGO<br />
    @logo.hover_name = LOGO + "2"<br />
    @logo.hover_filetype = :picture<br />
    @logo.set_base_bitmap<br />
    @day_index = 0<br />
    @days = %w{Sunday Monday Tuesday Wednesday Thursday Friday Saturday}<br />
    # Make day of the week graphic<br />
    @block = Sprite.new<br />
    @block.set_xyz(12, Graphics.height - 40, 100)<br />
    @bitmap = Bitmap.new(200, 36)<br />
    font = @bitmap.font<br />
    font.size = 32<br />
    font.outline = true<br />
    font.outline_size = 2<br />
    @bitmap.draw_text(@bitmap.rect, @days[@day_index], 1)<br />
    @block.bitmap = @bitmap<br />
  end<br />
<br />
  def check_continue<br />
    @continue_enabled = Dir["Save*.rxdata"].any?<br />
    if @continue_enabled<br />
      @command_window.index = 1<br />
    else<br />
      @command_window.disable_item(1)<br />
    end<br />
  end<br />
<br />
  def setup_audio<br />
    &#36;game_system.bgm_play(&#36;data_system.title_bgm)<br />
    Audio.me_stop<br />
    Audio.bgs_stop<br />
  end<br />
<br />
  def terminate<br />
    @command_window.dispose<br />
    @bitmap.dispose<br />
    @block.dispose<br />
    @logo.bitmap.dispose<br />
    @logo.dispose<br />
    @title.bitmap.dispose<br />
    @title.dispose<br />
    @sprite.bitmap.dispose<br />
    @sprite.dispose<br />
  end<br />
<br />
  def main<br />
    if &#36;BTEST<br />
      battle_test<br />
      return<br />
    end<br />
    load_database<br />
    reset_game_system<br />
    start<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      break if &#36;scene != self<br />
    end<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def update<br />
    @logo.update<br />
    @command_window.update<br />
    # Added Right Click Check<br />
    if Input.right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      if @command_window.index &lt; 2<br />
        @command_window.index = 2<br />
        Audio.bgm_pause<br />
      else<br />
        @command_window.index = -1<br />
        Audio.bgm_resume<br />
      end<br />
    # Added Left Click Check<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      case @command_window.index<br />
      when 0  # New game<br />
        command_new_game<br />
      when 1  # Continue<br />
        command_continue<br />
      when 2  # Shutdown<br />
        command_shutdown<br />
      end<br />
    elsif Input.repeat?(Input::KeyD) or Input.repeat_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @day_index = (@day_index + 1) % 7<br />
      @bitmap.clear<br />
      @bitmap.draw_text(@bitmap.rect, @days[@day_index], 1)<br />
    elsif Input.trigger?(Input::LeftShift)<br />
      &#36;game_system.se_play(&#36;data_system.equip_se)<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Map<br />
  def update<br />
    loop do<br />
      &#36;game_map.update<br />
      &#36;game_system.map_interpreter.update<br />
      &#36;game_player.update<br />
      &#36;game_system.update<br />
      &#36;game_screen.update<br />
      break unless &#36;game_temp.player_transferring<br />
      transfer_player<br />
      break if &#36;game_temp.transition_processing<br />
    end<br />
    @spriteset.update<br />
    @message_window.update<br />
    if &#36;game_temp.gameover<br />
      &#36;scene = Scene_Gameover.new<br />
      return<br />
    end<br />
    if &#36;game_temp.to_title<br />
      &#36;scene = Scene_Title.new<br />
      return<br />
    end<br />
    if &#36;game_temp.transition_processing<br />
      &#36;game_temp.transition_processing = false<br />
      if &#36;game_temp.transition_name == ""<br />
        Graphics.transition(20)<br />
      else<br />
        Graphics.transition(40, "Graphics/Transitions/" +<br />
          &#36;game_temp.transition_name)<br />
      end<br />
    end<br />
    if Input.trigger?(Input::KeyP)<br />
      &#36;game_system.se_play(&#36;data_system.shop_se)<br />
      Graphics.screenshot<br />
      return<br />
    end<br />
    return if &#36;game_temp.message_window_showing<br />
    if &#36;game_player.encounter_count == 0 and &#36;game_map.encounter_list != []<br />
      unless &#36;game_system.map_interpreter.running? or<br />
             &#36;game_system.encounter_disabled<br />
        n = rand(&#36;game_map.encounter_list.size)<br />
        troop_id = &#36;game_map.encounter_list[n]<br />
        if &#36;data_troops[troop_id] != nil<br />
          &#36;game_temp.battle_calling = true<br />
          &#36;game_temp.battle_troop_id = troop_id<br />
          &#36;game_temp.battle_can_escape = true<br />
          &#36;game_temp.battle_can_lose = false<br />
          &#36;game_temp.battle_proc = nil<br />
        end<br />
      end<br />
    end<br />
    # Added Right Click Check<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      unless &#36;game_system.map_interpreter.running? or<br />
             &#36;game_system.menu_disabled<br />
        &#36;game_temp.menu_calling = true<br />
        &#36;game_temp.menu_beep = true<br />
      end<br />
    end<br />
    if &#36;DEBUG and Input.press?(Input::F9)<br />
      &#36;game_temp.debug_calling = true<br />
    end<br />
    unless &#36;game_player.moving?<br />
      if &#36;game_temp.battle_calling<br />
        call_battle<br />
      elsif &#36;game_temp.shop_calling<br />
        call_shop<br />
      elsif &#36;game_temp.name_calling<br />
        call_name<br />
      elsif &#36;game_temp.menu_calling<br />
        call_menu<br />
      elsif &#36;game_temp.save_calling<br />
        call_save<br />
      elsif &#36;game_temp.debug_calling<br />
        call_debug<br />
      end<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Menu<br />
  def main<br />
    start<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      if &#36;scene != self<br />
        break<br />
      end<br />
    end<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def start<br />
    create_command_window<br />
    create_windows<br />
    Mouse.set_xy(80, 28 + @menu_index * 32)<br />
  end<br />
<br />
  def create_command_window<br />
    s1 = &#36;data_system.words.item<br />
    s2 = &#36;data_system.words.skill<br />
    s3 = &#36;data_system.words.equip<br />
    s4 = "Status"<br />
    s5 = "Save"<br />
    s6 = "End Game"<br />
    @command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6])<br />
    @command_window.index = @menu_index<br />
    if &#36;game_party.actors.size == 0<br />
      @command_window.disable_item(0)<br />
      @command_window.disable_item(1)<br />
      @command_window.disable_item(2)<br />
      @command_window.disable_item(3)<br />
    end<br />
    if &#36;game_system.save_disabled<br />
      @command_window.disable_item(4)<br />
    end<br />
  end<br />
<br />
  def create_windows<br />
    @playtime_window = Window_PlayTime.new<br />
    @playtime_window.x = 0<br />
    @playtime_window.y = 224<br />
    @steps_window = Window_Steps.new<br />
    @steps_window.x = 0<br />
    @steps_window.y = 320<br />
    @gold_window = Window_Gold.new<br />
    @gold_window.x = 0<br />
    @gold_window.y = 416<br />
    @status_window = Window_MenuStatus.new<br />
    @status_window.x = 160<br />
    @status_window.y = 0<br />
  end<br />
<br />
  def terminate<br />
    @command_window.dispose<br />
    @playtime_window.dispose<br />
    @steps_window.dispose<br />
    @gold_window.dispose<br />
    @status_window.dispose<br />
  end<br />
<br />
  def update_command<br />
    # Added Right Click Check<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Map.new<br />
      return<br />
    end<br />
    # Added Left Click Check<br />
    if Input.trigger?(Input::C) or Input.double_left_click?<br />
      if &#36;game_party.actors.size == 0 and @command_window.index &lt; 4<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      case @command_window.index<br />
      when 0  # item<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        &#36;scene = Scene_Item.new<br />
      when 1  # skill<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        @command_window.active = false<br />
        @status_window.active = true<br />
        @status_window.index = 0<br />
        Mouse.set_xy(@command_window.width + 120, 28)<br />
      when 2  # equipment<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        @command_window.active = false<br />
        @status_window.active = true<br />
        @status_window.index = 0<br />
        Mouse.set_xy(@command_window.width + 120, 28)<br />
      when 3  # status<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        @command_window.active = false<br />
        @status_window.active = true<br />
        @status_window.index = 0<br />
        Mouse.set_xy(@command_window.width + 120, 28)<br />
      when 4  # save<br />
        if &#36;game_system.save_disabled<br />
          &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
          return<br />
        end<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        &#36;scene = Scene_Save.new<br />
      when 5  # end game<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        &#36;scene = Scene_End.new<br />
      end<br />
      return<br />
    end<br />
  end<br />
<br />
  def update_status<br />
    # Added Double Right Click Check<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      @command_window.active = true<br />
      @status_window.active = false<br />
      @status_window.index = -1<br />
      mx = @command_window.x + 80<br />
      my = 28 + @command_window.index * 32<br />
      Mouse.set_xy(mx, my)<br />
      return<br />
    end<br />
    # Modified OK Button Functionality<br />
    if Input.trigger?(Input::C)<br />
      process_status<br />
      return<br />
    # Added Double Left Click Check<br />
    elsif Input.double_left_click?<br />
      return unless @status_window.mouse_inside?(@status_window.index)<br />
      process_status<br />
    end<br />
  end<br />
<br />
  def process_status<br />
    case @command_window.index<br />
    when 1  # skill<br />
      if &#36;game_party.actors[@status_window.index].restriction &gt;= 2<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      &#36;scene = Scene_Skill.new(@status_window.index)<br />
    when 2  # equipment<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      &#36;scene = Scene_Equip.new(@status_window.index)<br />
    when 3  # status<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      &#36;scene = Scene_Status.new(@status_window.index)<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Item<br />
  alias :kyon_click_win_scn_item_up_item :update_item<br />
  def update_item<br />
    kyon_click_win_scn_item_up_item<br />
    # Added Double Right Click Check<br />
    if Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Menu.new(0)<br />
      return<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Equip<br />
  alias :kyon_click_win_scn_equip_up_right :update_right<br />
  def update_right<br />
    kyon_click_win_scn_equip_up_right<br />
    if Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Menu.new(2)<br />
      return<br />
    elsif Input.double_left_click?<br />
      n = @right_window.index<br />
      if !@right_window.mouse_inside?(n) or @actor.equip_fix?(n)<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      @right_window.active = false<br />
      @item_window.active = true<br />
      @item_window.index = 0<br />
      return<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_File<br />
  alias :kyon_click_win_scn_fl_up :update<br />
  def update<br />
    kyon_click_win_scn_fl_up<br />
    if Input.double_right_click?<br />
      on_cancel<br />
      return<br />
    elsif Input.double_left_click?<br />
      @savefile_windows.each_with_index do |win, n|<br />
        next unless win.mouse_inside?(0)<br />
        choose_file(n)<br />
        on_decision(make_filename(n))<br />
        &#36;game_temp.last_file_index = n<br />
        break<br />
      end<br />
      return<br />
    elsif Input.left_click?<br />
      @savefile_windows.each_with_index do |win, n|<br />
        next unless win.mouse_inside?(0)<br />
        choose_file(n)<br />
        break<br />
      end<br />
      return<br />
    end<br />
  end<br />
<br />
  def choose_file(n)<br />
    @savefile_windows[@file_index].selected = false<br />
    @savefile_windows[n].selected = true<br />
    @file_index = n<br />
  end<br />
end<br />
<br />
class Scene_End<br />
  def main<br />
    s1 = "To Title"<br />
    s2 = "Shutdown"<br />
    s3 = "Cancel"<br />
    @command_window = Window_Command.new(192, [s1, s2, s3])<br />
    @command_window.x = 320 - @command_window.width / 2<br />
    @command_window.y = 240 - @command_window.height / 2<br />
    @command_window.draggable = true<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      break if &#36;scene != self<br />
    end<br />
    Graphics.freeze<br />
    @command_window.dispose<br />
    if &#36;scene.is_a?(Scene_Title)<br />
      Graphics.transition<br />
      Graphics.freeze<br />
    end<br />
  end<br />
<br />
  def update<br />
    @command_window.update<br />
    # Added Right Click Check<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Menu.new(5)<br />
      return<br />
    # Added Left Click Check<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      case @command_window.index<br />
      when 0  # to title<br />
        command_to_title<br />
      when 1  # shutdown<br />
        command_shutdown<br />
      when 2  # quit<br />
        command_cancel<br />
      end<br />
      return<br />
    end<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RM VX Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * ClickableWindow VX * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   2026-01-11<br />
<br />
# This is a script demo that shows you how it is now possible to click once on<br />
# a menu window to choose an option while ignoring the surrounding area.<br />
# Normally, you would have to add some calls to Input.left_click? or<br />
# Input.right_click? or even Input.middle_click? to your target scenes to make<br />
# this work.<br />
<br />
class Window_Selectable<br />
  def one_click_selection<br />
    # Set Index to invisible if clicked outside this window<br />
    self.index = -1<br />
    # Check each area - a list of Rect's<br />
    @area.size.times do |n|<br />
      next unless mouse_inside?(n)<br />
      self.index = n<br />
      Sound.play_cursor<br />
      break<br />
    end<br />
  end<br />
<br />
  def cursor_movable?<br />
    return false if !visible or !active<br />
    return false if @item_max == 0 or @opening or @closing<br />
    return true<br />
  end<br />
<br />
  def update<br />
    super<br />
    if cursor_movable?<br />
      last_index = @index<br />
      # Added Left Click Check<br />
      if Input.left_click?<br />
        one_click_selection<br />
        return<br />
      end<br />
      if mouse_inside?<br />
        if Mouse.scroll_y?(:UP)<br />
          Sound.play_cursor<br />
          self.index = (@index - @column_max) % @item_max<br />
          return<br />
        elsif Mouse.scroll_y?(:DOWN)<br />
          Sound.play_cursor<br />
          self.index = (@index + @column_max) % @item_max<br />
          return<br />
        end<br />
      end<br />
      if Input.repeat?(Input::DOWN)<br />
        cursor_down(Input.trigger?(Input::DOWN))<br />
      end<br />
      if Input.repeat?(Input::UP)<br />
        cursor_up(Input.trigger?(Input::UP))<br />
      end<br />
      if Input.repeat?(Input::RIGHT)<br />
        cursor_right(Input.trigger?(Input::RIGHT))<br />
      end<br />
      if Input.repeat?(Input::LEFT)<br />
        cursor_left(Input.trigger?(Input::LEFT))<br />
      end<br />
      if Input.repeat?(Input::R)<br />
        cursor_pagedown<br />
      end<br />
      if Input.repeat?(Input::L)<br />
        cursor_pageup<br />
      end<br />
      if @index != last_index<br />
        Sound.play_cursor<br />
      end<br />
    end<br />
    update_cursor<br />
    call_update_help<br />
  end<br />
end<br />
<br />
class Window_Command<br />
  def draw_item(n, enabled = true)<br />
    rect = @area[n] ||= item_rect(n)<br />
    rect.x += 4<br />
    rect.width -= 8<br />
    self.contents.clear_rect(rect)<br />
    self.contents.font.color = normal_color<br />
    self.contents.font.color.alpha = enabled ? 255 : 128<br />
    self.contents.draw_text(rect, @commands[n])<br />
  end<br />
end<br />
<br />
class Scene_Title<br />
  def update<br />
    super<br />
    @command_window.update<br />
    # Added Left Click Check<br />
    if Input.trigger?(Input::C) or Input.double_left_click?<br />
      case @command_window.index<br />
      when 0    #New game<br />
        command_new_game<br />
      when 1    # Continue<br />
        command_continue<br />
      when 2    # Shutdown<br />
        command_shutdown<br />
      end<br />
    # Added Right Click Check<br />
    elsif Input.right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      if @command_window.index &lt; 2<br />
        @command_window.index = 2<br />
      end<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Map<br />
  def update_call_menu<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      return if &#36;game_map.interpreter.running?<br />
      return if &#36;game_system.menu_disabled<br />
      &#36;game_temp.menu_beep = true<br />
      &#36;game_temp.next_scene = "menu"<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Menu<br />
  def update_command_selection<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      Sound.play_cancel<br />
      &#36;scene = Scene_Map.new<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      if &#36;game_party.members.size == 0 and @command_window.index &lt; 4<br />
        Sound.play_buzzer<br />
        return<br />
      elsif &#36;game_system.save_disabled and @command_window.index == 4<br />
        Sound.play_buzzer<br />
        return<br />
      end<br />
      Sound.play_decision<br />
      case @command_window.index<br />
      when 0      # Item<br />
        &#36;scene = Scene_Item.new<br />
      when 1,2,3  # Skill, equipment, status<br />
        start_actor_selection<br />
      when 4      # Save<br />
        &#36;scene = Scene_File.new(true, false, false)<br />
      when 5      # End Game<br />
        &#36;scene = Scene_End.new<br />
      end<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_End<br />
  def update<br />
    super<br />
    update_menu_background<br />
    @command_window.update<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      Sound.play_cancel<br />
      return_scene<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      case @command_window.index<br />
      when 0  # to title<br />
        command_to_title<br />
      when 1  # shutdown<br />
        command_shutdown<br />
      when 2  # quit<br />
        command_cancel<br />
      end<br />
    end<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RM VX ACE Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * ClickableWindow ACE * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   2025-01-11<br />
<br />
# This is a script demo that shows you how it is now possible to click once on<br />
# a menu window to choose an option while ignoring the surrounding area.<br />
# Normally, you would have to add some calls to Input.left_click? or<br />
# Input.right_click? or even Input.middle_click? to your target scenes to make<br />
# this work.<br />
<br />
class Window_Selectable<br />
  def process_cursor_move<br />
    return unless cursor_movable?<br />
    last_index = @index<br />
    if Input.left_click?<br />
      # Set Index to invisible if clicked outside this window<br />
      self.index = -1<br />
      # Check each area - a list of Rect's<br />
      @area.size.times do |n|<br />
        next unless mouse_inside?(n)<br />
        self.index = n<br />
        Sound.play_cursor<br />
        break<br />
      end<br />
      return<br />
    end<br />
    cursor_down (Input.trigger?(:DOWN))  if Input.repeat?(:DOWN)<br />
    cursor_up   (Input.trigger?(:UP))    if Input.repeat?(:UP)<br />
    cursor_right(Input.trigger?(:RIGHT)) if Input.repeat?(:RIGHT)<br />
    cursor_left (Input.trigger?(:LEFT))  if Input.repeat?(:LEFT)<br />
    cursor_pagedown   if !handle?(:pagedown) &amp;&amp; Input.trigger?(:R)<br />
    cursor_pageup     if !handle?(:pageup)   &amp;&amp; Input.trigger?(:L)<br />
    Sound.play_cursor if @index != last_index<br />
  end<br />
<br />
  def process_handling<br />
    return unless open? &amp;&amp; active<br />
    return process_ok       if ok_enabled? &amp;&amp; Input.double_left_click?<br />
    return process_cancel   if cancel_enabled? &amp;&amp; Input.double_right_click?<br />
    return process_ok       if ok_enabled?        &amp;&amp; Input.trigger?(:C)<br />
    return process_cancel   if cancel_enabled?    &amp;&amp; Input.trigger?(:B)<br />
    return process_pagedown if handle?(:pagedown) &amp;&amp; Input.trigger?(:R)<br />
    return process_pageup   if handle?(:pageup)   &amp;&amp; Input.trigger?(:L)<br />
  end<br />
end<br />
<br />
class Window_Command<br />
  def draw_item(n)<br />
    rect = @area[n] ||= item_rect_for_text(n)<br />
    change_color(normal_color, command_enabled?(n))<br />
    draw_text(rect, command_name(n), alignment)<br />
  end<br />
end<br />
<br />
class Window_MenuCommand<br />
  def select_last<br />
    select_symbol(@@last_command_symbol)<br />
    Mouse.set_xy(80, 20 + @index * 24)<br />
  end<br />
end<br />
<br />
class Window_SaveFile<br />
  alias :kyon_click_win_win_svfl_init :initialize<br />
  def initialize(height, index)<br />
    kyon_click_win_win_svfl_init(height, index)<br />
    @area &lt;&lt; self.contents.rect<br />
  end<br />
end<br />
<br />
class Scene_File<br />
  def update_savefile_selection<br />
    if Input.double_left_click?<br />
      @savefile_windows.each_with_index do |win, n|<br />
        next unless win.mouse_inside?<br />
        choose_file(n)<br />
        on_savefile_ok<br />
        break<br />
      end<br />
      return<br />
    elsif Input.left_click?<br />
      @savefile_windows.each_with_index do |win, n|<br />
        next unless win.mouse_inside?<br />
        choose_file(n)<br />
        break<br />
      end<br />
      return<br />
    elsif Input.double_right_click?<br />
      on_savefile_cancel<br />
      return<br />
    end<br />
    return on_savefile_ok     if Input.trigger?(:C)<br />
    return on_savefile_cancel if Input.trigger?(:B)<br />
    update_cursor<br />
  end<br />
<br />
  def choose_file(n)<br />
    @savefile_windows[@index].selected = false<br />
    @savefile_windows[n].selected = true<br />
    @index = n<br />
    ensure_cursor_visible<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">ClickableWindows</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size"><br />
HiddenChest Exclusive!</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">XP + VX + ACE Related</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">by Kyonides</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b">Warning!</span></div>
<br />
<div style="text-align: center;" class="mycode_align">Other scripts of mine like PrintScene HC depend on this one.</div>
<br />
These scriptlets allow you to <img src="https://www.save-point.org/images/smilies/ejlol/mouse.gif" alt="Mouse" title="Mouse" class="smilie smilie_134" /> click on the usual menu window options! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
<br />
As long as you click on the area defined by the blinking cursor, you will be fine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><br />
<br />
It does not fully support all windows but only child classes of Window_Selectable and a few others.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">The Caveats</span><br />
<br />
They are based on XP's and VX ACE's default scripts. There is no warranty they will work with custom ones.<br />
<br />
Some scenes forced me to add calls like Input.double_left_click? or Input.right_click? to make them work properly.<br />
<br />
<hr class="mycode_hr" />
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Script Section</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Script for the RMXP Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * ClickableWidget XP * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   2026-01-11<br />
<br />
# This is a script demo that shows you how it is now possible to click once on<br />
# a menu window to choose an option while ignoring the surrounding area.<br />
# Normally, you would have to add some calls to Input.left_click? or<br />
# Input.right_click? or even Input.middle_click? to your target scenes to make<br />
# this work.<br />
<br />
class Sprite<br />
  alias :kyon_click_sprite_sprite_up :update<br />
  def update<br />
    kyon_click_sprite_sprite_up<br />
    # Added Draggable Window Check<br />
    check_draggable<br />
    check_mouse_inside<br />
  end<br />
<br />
  def check_draggable<br />
    return unless draggable?<br />
    if Input.press_left_click?<br />
      if Mouse.no_target?<br />
        if mouse_inside_color? and drag_color?<br />
          Mouse.target = self<br />
          @mouse_x = Mouse.x<br />
          @mouse_y = Mouse.y<br />
        end<br />
      elsif Mouse.target?(self)<br />
        self.x += Mouse.x - @mouse_x<br />
        self.y += Mouse.y - @mouse_y<br />
        @mouse_x = Mouse.x<br />
        @mouse_y = Mouse.y<br />
      end<br />
      return<br />
    elsif Mouse.target?(self)<br />
      Mouse.target = nil<br />
    end<br />
  end<br />
<br />
  def hover_can_change?<br />
    return false if @hover_changed<br />
    return false if @base_name.nil? or @base_name.empty?<br />
    return false if @hover_name.nil? or @hover_name.empty?<br />
    @hover_filetype != nil<br />
  end<br />
<br />
  def check_mouse_inside<br />
    return if Mouse.target?(self)<br />
    if mouse_inside?<br />
      if hover_can_change?<br />
        set_hover_bitmap<br />
        @hover_changed = true<br />
        return<br />
      end<br />
    elsif @hover_changed<br />
      self.bitmap.dispose<br />
      set_base_bitmap<br />
      @hover_changed = false<br />
    end<br />
  end<br />
<br />
  def set_hover_bitmap<br />
    filetype = @hover_filetype.to_sym<br />
    case filetype<br />
    when :battler <br />
      self.bitmap = RPG::Cache.battler(@hover_name, @hover_hue)<br />
    when :character<br />
      self.bitmap = RPG::Cache.character(@hover_name, @hover_hue)<br />
    when :icon<br />
      self.bitmap = RPG::Cache.icon(@hover_name)<br />
    when :picture<br />
      self.bitmap = RPG::Cache.picture(@hover_name)<br />
    end<br />
  end<br />
<br />
  def set_base_bitmap<br />
    filetype = @hover_filetype.to_sym<br />
    case filetype<br />
    when :battler <br />
      self.bitmap = RPG::Cache.battler(@base_name, @hover_hue)<br />
    when :character<br />
      self.bitmap = RPG::Cache.character(@base_name, @hover_hue)<br />
    when :icon<br />
      self.bitmap = RPG::Cache.icon(@base_name)<br />
    when :picture<br />
      self.bitmap = RPG::Cache.picture(@base_name)<br />
    end<br />
  end<br />
end<br />
<br />
class Window_Base<br />
  def update<br />
    super<br />
    if &#36;game_system.windowskin_name != @windowskin_name<br />
      @windowskin_name = &#36;game_system.windowskin_name<br />
      self.windowskin = RPG::Cache.windowskin(@windowskin_name)<br />
    end<br />
    # Added Draggable Window Check<br />
    check_draggable<br />
  end<br />
<br />
  def check_draggable<br />
    return unless draggable?<br />
    if Input.press_left_click?<br />
      if Mouse.no_target? and mouse_inside?<br />
        Mouse.target = self<br />
        @mouse_x = Mouse.x<br />
        @mouse_y = Mouse.y<br />
      elsif Mouse.target?(self)<br />
        self.x += Mouse.x - @mouse_x<br />
        self.y += Mouse.y - @mouse_y<br />
        @mouse_x = Mouse.x<br />
        @mouse_y = Mouse.y<br />
      end<br />
      return<br />
    elsif Mouse.target?(self)<br />
      Mouse.target = nil<br />
    end<br />
  end<br />
end<br />
<br />
class Window_Selectable<br />
  def one_click_selection<br />
    # Set Index to invisible if clicked outside this window<br />
    self.index = -1<br />
    # Check each area - a list of Rect's<br />
    @area.size.times do |n|<br />
      next unless mouse_inside?(n)<br />
      self.index = n<br />
      break<br />
    end<br />
  end<br />
<br />
  def update<br />
    super<br />
    return unless self.active<br />
    return if @item_max == 0<br />
    # Added Left Click Check<br />
    if Input.left_click?<br />
      one_click_selection<br />
      return<br />
    end<br />
    if mouse_inside?<br />
      if Mouse.scroll_y?(:UP)<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        self.index = (@index - @column_max) % @item_max<br />
        return<br />
      elsif Mouse.scroll_y?(:DOWN)<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        self.index = (@index + @column_max) % @item_max<br />
        return<br />
      end<br />
    end<br />
    if Input.repeat?(Input::DOWN)<br />
      if (@column_max == 1 and Input.trigger?(Input::DOWN)) or<br />
         @index &lt; @item_max - @column_max<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index = (@index + @column_max) % @item_max<br />
      end<br />
    end<br />
    if Input.repeat?(Input::UP)<br />
      if (@column_max == 1 and Input.trigger?(Input::UP)) or<br />
         @index &gt;= @column_max<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index = (@index - @column_max + @item_max) % @item_max<br />
      end<br />
    end<br />
    if Input.repeat?(Input::RIGHT)<br />
      if @column_max &gt;= 2 and @index &lt; @item_max - 1<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index += 1<br />
      end<br />
    end<br />
    if Input.repeat?(Input::LEFT)<br />
      if @column_max &gt;= 2 and @index &gt; 0<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index -= 1<br />
      end<br />
    end<br />
    if Input.repeat?(Input::R)<br />
      if self.top_row + (self.page_row_max - 1) &lt; (self.row_max - 1)<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index = [@index + self.page_item_max, @item_max - 1].min<br />
        self.top_row += self.page_row_max<br />
      end<br />
    end<br />
    if Input.repeat?(Input::L)<br />
      if self.top_row &gt; 0<br />
        &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
        @index = [@index - self.page_item_max, 0].max<br />
        self.top_row -= self.page_row_max<br />
      end<br />
    end<br />
    if self.active and @help_window != nil<br />
      update_help if @index &gt;= 0<br />
    end<br />
    update_cursor_rect<br />
  end<br />
 <br />
  def get_area_rect(n)<br />
    rw = self.width / @column_max - 32<br />
    rx = 8 + n % @column_max * (rw + 32)<br />
    ry = n / @column_max * 32 - self.oy<br />
    Rect.new(rx, ry, rw, 32)<br />
  end<br />
end<br />
<br />
class Window_Command<br />
  def draw_item(n, color)<br />
    @area[n] ||= get_area_rect(n)<br />
    c = self.contents<br />
    c.font.color = color<br />
    rect = Rect.new(4, 32 * n, c.width - 8, 32)<br />
    c.fill_rect(rect, Color.new(0, 0, 0, 0))<br />
    c.draw_text(rect, @commands[n])<br />
  end<br />
end<br />
<br />
class Window_MenuStatus<br />
  def refresh<br />
    self.contents.clear<br />
    @item_max = &#36;game_party.actors.size<br />
    for i in 0...&#36;game_party.actors.size<br />
      x = 64<br />
      y = i * 116<br />
      @area[i] ||= Rect.new(0, i * 116, self.width - 32, 96)<br />
      actor = &#36;game_party.actors[i]<br />
      draw_actor_graphic(actor, x - 40, y + 80)<br />
      draw_actor_name(actor, x, y)<br />
      draw_actor_class(actor, x + 144, y)<br />
      draw_actor_level(actor, x, y + 32)<br />
      draw_actor_state(actor, x + 90, y + 32)<br />
      draw_actor_exp(actor, x, y + 64)<br />
      draw_actor_hp(actor, x + 236, y + 32)<br />
      draw_actor_sp(actor, x + 236, y + 64)<br />
    end<br />
  end<br />
end<br />
<br />
class Window_Target<br />
  def refresh<br />
    self.contents.clear<br />
    for i in 0...&#36;game_party.actors.size<br />
      x = 4<br />
      y = i * 116<br />
      @area[i] ||= Rect.new(0, i * 116, self.width - 32, 96)<br />
      actor = &#36;game_party.actors[i]<br />
      draw_actor_name(actor, x, y)<br />
      draw_actor_class(actor, x + 144, y)<br />
      draw_actor_level(actor, x + 8, y + 32)<br />
      draw_actor_state(actor, x + 8, y + 64)<br />
      draw_actor_hp(actor, x + 152, y + 32)<br />
      draw_actor_sp(actor, x + 152, y + 64)<br />
    end<br />
  end<br />
end<br />
<br />
class Window_EquipRight<br />
  def initialize(actor)<br />
    super(272, 64, 368, 192)<br />
    @click_width = width - 32<br />
    self.contents = Bitmap.new(@click_width, height - 32)<br />
    @actor = actor<br />
    create_areas<br />
    refresh<br />
    self.index = 0<br />
  end<br />
<br />
  def create_areas<br />
    5.times {|n| @area &lt;&lt; Rect.new(4, 32 * n, @click_width, 32) }<br />
  end<br />
end<br />
<br />
class Window_SaveFile<br />
  alias :kyon_click_win_win_svfl_init :initialize<br />
  def initialize(file_index, filename)<br />
    kyon_click_win_win_svfl_init(file_index, filename)<br />
    @area &lt;&lt; self.contents.rect<br />
  end<br />
end<br />
<br />
class Window_Message<br />
  alias :kyon_click_win_win_mess_init :initialize<br />
  def initialize<br />
    kyon_click_win_win_mess_init<br />
    self.pause_x = self.width - 80<br />
  end<br />
end<br />
<br />
class Scene_Title<br />
  LOGO = "icon_sound"<br />
  def load_database<br />
    &#36;data_actors        = load_data("Data/Actors.rxdata")<br />
    &#36;data_classes       = load_data("Data/Classes.rxdata")<br />
    &#36;data_skills        = load_data("Data/Skills.rxdata")<br />
    &#36;data_items         = load_data("Data/Items.rxdata")<br />
    &#36;data_weapons       = load_data("Data/Weapons.rxdata")<br />
    &#36;data_armors        = load_data("Data/Armors.rxdata")<br />
    &#36;data_enemies       = load_data("Data/Enemies.rxdata")<br />
    &#36;data_troops        = load_data("Data/Troops.rxdata")<br />
    &#36;data_states        = load_data("Data/States.rxdata")<br />
    &#36;data_animations    = load_data("Data/Animations.rxdata")<br />
    &#36;data_tilesets      = load_data("Data/Tilesets.rxdata")<br />
    &#36;data_common_events = load_data("Data/CommonEvents.rxdata")<br />
    &#36;data_system        = load_data("Data/System.rxdata")<br />
  end<br />
<br />
  def reset_game_system<br />
    &#36;game_system = Game_System.new<br />
  end<br />
<br />
  def start<br />
    create_backdrop<br />
    create_command_window<br />
    create_title<br />
    create_extras<br />
    check_continue<br />
    setup_audio<br />
  end<br />
<br />
  def create_backdrop<br />
    @sprite = Sprite.new<br />
    @sprite.bitmap = RPG::Cache.title(&#36;data_system.title_name)<br />
  end<br />
<br />
  def create_command_window<br />
    s1 = "New Game"<br />
    s2 = "Continue"<br />
    s3 = "Shutdown"<br />
    @command_window = Window_Command.new(192, [s1, s2, s3])<br />
    @command_window.back_opacity = 160<br />
    @command_window.x = 320 - @command_window.width / 2<br />
    @command_window.y = 288<br />
    @command_window.draggable = true<br />
  end<br />
<br />
  def create_title<br />
    @title = Sprite.new<br />
    @title.set_xyz(0, 60, 100)<br />
    @title.bitmap = b = Bitmap.new(Graphics.width, 60)<br />
    font = b.font<br />
    font.size = 52<br />
    font.outline = true<br />
    font.outline_size = 4<br />
    b.draw_text(b.rect, Game::TITLE, 1)<br />
  end<br />
<br />
  def create_extras<br />
    @logo = Sprite.new<br />
    @logo.set_xyz(24, 24, 100)<br />
    @logo.drag_condition = :color<br />
    @logo.base_name = LOGO<br />
    @logo.hover_name = LOGO + "2"<br />
    @logo.hover_filetype = :picture<br />
    @logo.set_base_bitmap<br />
    @day_index = 0<br />
    @days = %w{Sunday Monday Tuesday Wednesday Thursday Friday Saturday}<br />
    # Make day of the week graphic<br />
    @block = Sprite.new<br />
    @block.set_xyz(12, Graphics.height - 40, 100)<br />
    @bitmap = Bitmap.new(200, 36)<br />
    font = @bitmap.font<br />
    font.size = 32<br />
    font.outline = true<br />
    font.outline_size = 2<br />
    @bitmap.draw_text(@bitmap.rect, @days[@day_index], 1)<br />
    @block.bitmap = @bitmap<br />
  end<br />
<br />
  def check_continue<br />
    @continue_enabled = Dir["Save*.rxdata"].any?<br />
    if @continue_enabled<br />
      @command_window.index = 1<br />
    else<br />
      @command_window.disable_item(1)<br />
    end<br />
  end<br />
<br />
  def setup_audio<br />
    &#36;game_system.bgm_play(&#36;data_system.title_bgm)<br />
    Audio.me_stop<br />
    Audio.bgs_stop<br />
  end<br />
<br />
  def terminate<br />
    @command_window.dispose<br />
    @bitmap.dispose<br />
    @block.dispose<br />
    @logo.bitmap.dispose<br />
    @logo.dispose<br />
    @title.bitmap.dispose<br />
    @title.dispose<br />
    @sprite.bitmap.dispose<br />
    @sprite.dispose<br />
  end<br />
<br />
  def main<br />
    if &#36;BTEST<br />
      battle_test<br />
      return<br />
    end<br />
    load_database<br />
    reset_game_system<br />
    start<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      break if &#36;scene != self<br />
    end<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def update<br />
    @logo.update<br />
    @command_window.update<br />
    # Added Right Click Check<br />
    if Input.right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      if @command_window.index &lt; 2<br />
        @command_window.index = 2<br />
        Audio.bgm_pause<br />
      else<br />
        @command_window.index = -1<br />
        Audio.bgm_resume<br />
      end<br />
    # Added Left Click Check<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      case @command_window.index<br />
      when 0  # New game<br />
        command_new_game<br />
      when 1  # Continue<br />
        command_continue<br />
      when 2  # Shutdown<br />
        command_shutdown<br />
      end<br />
    elsif Input.repeat?(Input::KeyD) or Input.repeat_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      @day_index = (@day_index + 1) % 7<br />
      @bitmap.clear<br />
      @bitmap.draw_text(@bitmap.rect, @days[@day_index], 1)<br />
    elsif Input.trigger?(Input::LeftShift)<br />
      &#36;game_system.se_play(&#36;data_system.equip_se)<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Map<br />
  def update<br />
    loop do<br />
      &#36;game_map.update<br />
      &#36;game_system.map_interpreter.update<br />
      &#36;game_player.update<br />
      &#36;game_system.update<br />
      &#36;game_screen.update<br />
      break unless &#36;game_temp.player_transferring<br />
      transfer_player<br />
      break if &#36;game_temp.transition_processing<br />
    end<br />
    @spriteset.update<br />
    @message_window.update<br />
    if &#36;game_temp.gameover<br />
      &#36;scene = Scene_Gameover.new<br />
      return<br />
    end<br />
    if &#36;game_temp.to_title<br />
      &#36;scene = Scene_Title.new<br />
      return<br />
    end<br />
    if &#36;game_temp.transition_processing<br />
      &#36;game_temp.transition_processing = false<br />
      if &#36;game_temp.transition_name == ""<br />
        Graphics.transition(20)<br />
      else<br />
        Graphics.transition(40, "Graphics/Transitions/" +<br />
          &#36;game_temp.transition_name)<br />
      end<br />
    end<br />
    if Input.trigger?(Input::KeyP)<br />
      &#36;game_system.se_play(&#36;data_system.shop_se)<br />
      Graphics.screenshot<br />
      return<br />
    end<br />
    return if &#36;game_temp.message_window_showing<br />
    if &#36;game_player.encounter_count == 0 and &#36;game_map.encounter_list != []<br />
      unless &#36;game_system.map_interpreter.running? or<br />
             &#36;game_system.encounter_disabled<br />
        n = rand(&#36;game_map.encounter_list.size)<br />
        troop_id = &#36;game_map.encounter_list[n]<br />
        if &#36;data_troops[troop_id] != nil<br />
          &#36;game_temp.battle_calling = true<br />
          &#36;game_temp.battle_troop_id = troop_id<br />
          &#36;game_temp.battle_can_escape = true<br />
          &#36;game_temp.battle_can_lose = false<br />
          &#36;game_temp.battle_proc = nil<br />
        end<br />
      end<br />
    end<br />
    # Added Right Click Check<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      unless &#36;game_system.map_interpreter.running? or<br />
             &#36;game_system.menu_disabled<br />
        &#36;game_temp.menu_calling = true<br />
        &#36;game_temp.menu_beep = true<br />
      end<br />
    end<br />
    if &#36;DEBUG and Input.press?(Input::F9)<br />
      &#36;game_temp.debug_calling = true<br />
    end<br />
    unless &#36;game_player.moving?<br />
      if &#36;game_temp.battle_calling<br />
        call_battle<br />
      elsif &#36;game_temp.shop_calling<br />
        call_shop<br />
      elsif &#36;game_temp.name_calling<br />
        call_name<br />
      elsif &#36;game_temp.menu_calling<br />
        call_menu<br />
      elsif &#36;game_temp.save_calling<br />
        call_save<br />
      elsif &#36;game_temp.debug_calling<br />
        call_debug<br />
      end<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Menu<br />
  def main<br />
    start<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      if &#36;scene != self<br />
        break<br />
      end<br />
    end<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def start<br />
    create_command_window<br />
    create_windows<br />
    Mouse.set_xy(80, 28 + @menu_index * 32)<br />
  end<br />
<br />
  def create_command_window<br />
    s1 = &#36;data_system.words.item<br />
    s2 = &#36;data_system.words.skill<br />
    s3 = &#36;data_system.words.equip<br />
    s4 = "Status"<br />
    s5 = "Save"<br />
    s6 = "End Game"<br />
    @command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6])<br />
    @command_window.index = @menu_index<br />
    if &#36;game_party.actors.size == 0<br />
      @command_window.disable_item(0)<br />
      @command_window.disable_item(1)<br />
      @command_window.disable_item(2)<br />
      @command_window.disable_item(3)<br />
    end<br />
    if &#36;game_system.save_disabled<br />
      @command_window.disable_item(4)<br />
    end<br />
  end<br />
<br />
  def create_windows<br />
    @playtime_window = Window_PlayTime.new<br />
    @playtime_window.x = 0<br />
    @playtime_window.y = 224<br />
    @steps_window = Window_Steps.new<br />
    @steps_window.x = 0<br />
    @steps_window.y = 320<br />
    @gold_window = Window_Gold.new<br />
    @gold_window.x = 0<br />
    @gold_window.y = 416<br />
    @status_window = Window_MenuStatus.new<br />
    @status_window.x = 160<br />
    @status_window.y = 0<br />
  end<br />
<br />
  def terminate<br />
    @command_window.dispose<br />
    @playtime_window.dispose<br />
    @steps_window.dispose<br />
    @gold_window.dispose<br />
    @status_window.dispose<br />
  end<br />
<br />
  def update_command<br />
    # Added Right Click Check<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Map.new<br />
      return<br />
    end<br />
    # Added Left Click Check<br />
    if Input.trigger?(Input::C) or Input.double_left_click?<br />
      if &#36;game_party.actors.size == 0 and @command_window.index &lt; 4<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      case @command_window.index<br />
      when 0  # item<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        &#36;scene = Scene_Item.new<br />
      when 1  # skill<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        @command_window.active = false<br />
        @status_window.active = true<br />
        @status_window.index = 0<br />
        Mouse.set_xy(@command_window.width + 120, 28)<br />
      when 2  # equipment<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        @command_window.active = false<br />
        @status_window.active = true<br />
        @status_window.index = 0<br />
        Mouse.set_xy(@command_window.width + 120, 28)<br />
      when 3  # status<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        @command_window.active = false<br />
        @status_window.active = true<br />
        @status_window.index = 0<br />
        Mouse.set_xy(@command_window.width + 120, 28)<br />
      when 4  # save<br />
        if &#36;game_system.save_disabled<br />
          &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
          return<br />
        end<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        &#36;scene = Scene_Save.new<br />
      when 5  # end game<br />
        &#36;game_system.se_play(&#36;data_system.decision_se)<br />
        &#36;scene = Scene_End.new<br />
      end<br />
      return<br />
    end<br />
  end<br />
<br />
  def update_status<br />
    # Added Double Right Click Check<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      @command_window.active = true<br />
      @status_window.active = false<br />
      @status_window.index = -1<br />
      mx = @command_window.x + 80<br />
      my = 28 + @command_window.index * 32<br />
      Mouse.set_xy(mx, my)<br />
      return<br />
    end<br />
    # Modified OK Button Functionality<br />
    if Input.trigger?(Input::C)<br />
      process_status<br />
      return<br />
    # Added Double Left Click Check<br />
    elsif Input.double_left_click?<br />
      return unless @status_window.mouse_inside?(@status_window.index)<br />
      process_status<br />
    end<br />
  end<br />
<br />
  def process_status<br />
    case @command_window.index<br />
    when 1  # skill<br />
      if &#36;game_party.actors[@status_window.index].restriction &gt;= 2<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      &#36;scene = Scene_Skill.new(@status_window.index)<br />
    when 2  # equipment<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      &#36;scene = Scene_Equip.new(@status_window.index)<br />
    when 3  # status<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      &#36;scene = Scene_Status.new(@status_window.index)<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Item<br />
  alias :kyon_click_win_scn_item_up_item :update_item<br />
  def update_item<br />
    kyon_click_win_scn_item_up_item<br />
    # Added Double Right Click Check<br />
    if Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Menu.new(0)<br />
      return<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Equip<br />
  alias :kyon_click_win_scn_equip_up_right :update_right<br />
  def update_right<br />
    kyon_click_win_scn_equip_up_right<br />
    if Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Menu.new(2)<br />
      return<br />
    elsif Input.double_left_click?<br />
      n = @right_window.index<br />
      if !@right_window.mouse_inside?(n) or @actor.equip_fix?(n)<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      @right_window.active = false<br />
      @item_window.active = true<br />
      @item_window.index = 0<br />
      return<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_File<br />
  alias :kyon_click_win_scn_fl_up :update<br />
  def update<br />
    kyon_click_win_scn_fl_up<br />
    if Input.double_right_click?<br />
      on_cancel<br />
      return<br />
    elsif Input.double_left_click?<br />
      @savefile_windows.each_with_index do |win, n|<br />
        next unless win.mouse_inside?(0)<br />
        choose_file(n)<br />
        on_decision(make_filename(n))<br />
        &#36;game_temp.last_file_index = n<br />
        break<br />
      end<br />
      return<br />
    elsif Input.left_click?<br />
      @savefile_windows.each_with_index do |win, n|<br />
        next unless win.mouse_inside?(0)<br />
        choose_file(n)<br />
        break<br />
      end<br />
      return<br />
    end<br />
  end<br />
<br />
  def choose_file(n)<br />
    @savefile_windows[@file_index].selected = false<br />
    @savefile_windows[n].selected = true<br />
    @file_index = n<br />
  end<br />
end<br />
<br />
class Scene_End<br />
  def main<br />
    s1 = "To Title"<br />
    s2 = "Shutdown"<br />
    s3 = "Cancel"<br />
    @command_window = Window_Command.new(192, [s1, s2, s3])<br />
    @command_window.x = 320 - @command_window.width / 2<br />
    @command_window.y = 240 - @command_window.height / 2<br />
    @command_window.draggable = true<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      break if &#36;scene != self<br />
    end<br />
    Graphics.freeze<br />
    @command_window.dispose<br />
    if &#36;scene.is_a?(Scene_Title)<br />
      Graphics.transition<br />
      Graphics.freeze<br />
    end<br />
  end<br />
<br />
  def update<br />
    @command_window.update<br />
    # Added Right Click Check<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Menu.new(5)<br />
      return<br />
    # Added Left Click Check<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      case @command_window.index<br />
      when 0  # to title<br />
        command_to_title<br />
      when 1  # shutdown<br />
        command_shutdown<br />
      when 2  # quit<br />
        command_cancel<br />
      end<br />
      return<br />
    end<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RM VX Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * ClickableWindow VX * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   2026-01-11<br />
<br />
# This is a script demo that shows you how it is now possible to click once on<br />
# a menu window to choose an option while ignoring the surrounding area.<br />
# Normally, you would have to add some calls to Input.left_click? or<br />
# Input.right_click? or even Input.middle_click? to your target scenes to make<br />
# this work.<br />
<br />
class Window_Selectable<br />
  def one_click_selection<br />
    # Set Index to invisible if clicked outside this window<br />
    self.index = -1<br />
    # Check each area - a list of Rect's<br />
    @area.size.times do |n|<br />
      next unless mouse_inside?(n)<br />
      self.index = n<br />
      Sound.play_cursor<br />
      break<br />
    end<br />
  end<br />
<br />
  def cursor_movable?<br />
    return false if !visible or !active<br />
    return false if @item_max == 0 or @opening or @closing<br />
    return true<br />
  end<br />
<br />
  def update<br />
    super<br />
    if cursor_movable?<br />
      last_index = @index<br />
      # Added Left Click Check<br />
      if Input.left_click?<br />
        one_click_selection<br />
        return<br />
      end<br />
      if mouse_inside?<br />
        if Mouse.scroll_y?(:UP)<br />
          Sound.play_cursor<br />
          self.index = (@index - @column_max) % @item_max<br />
          return<br />
        elsif Mouse.scroll_y?(:DOWN)<br />
          Sound.play_cursor<br />
          self.index = (@index + @column_max) % @item_max<br />
          return<br />
        end<br />
      end<br />
      if Input.repeat?(Input::DOWN)<br />
        cursor_down(Input.trigger?(Input::DOWN))<br />
      end<br />
      if Input.repeat?(Input::UP)<br />
        cursor_up(Input.trigger?(Input::UP))<br />
      end<br />
      if Input.repeat?(Input::RIGHT)<br />
        cursor_right(Input.trigger?(Input::RIGHT))<br />
      end<br />
      if Input.repeat?(Input::LEFT)<br />
        cursor_left(Input.trigger?(Input::LEFT))<br />
      end<br />
      if Input.repeat?(Input::R)<br />
        cursor_pagedown<br />
      end<br />
      if Input.repeat?(Input::L)<br />
        cursor_pageup<br />
      end<br />
      if @index != last_index<br />
        Sound.play_cursor<br />
      end<br />
    end<br />
    update_cursor<br />
    call_update_help<br />
  end<br />
end<br />
<br />
class Window_Command<br />
  def draw_item(n, enabled = true)<br />
    rect = @area[n] ||= item_rect(n)<br />
    rect.x += 4<br />
    rect.width -= 8<br />
    self.contents.clear_rect(rect)<br />
    self.contents.font.color = normal_color<br />
    self.contents.font.color.alpha = enabled ? 255 : 128<br />
    self.contents.draw_text(rect, @commands[n])<br />
  end<br />
end<br />
<br />
class Scene_Title<br />
  def update<br />
    super<br />
    @command_window.update<br />
    # Added Left Click Check<br />
    if Input.trigger?(Input::C) or Input.double_left_click?<br />
      case @command_window.index<br />
      when 0    #New game<br />
        command_new_game<br />
      when 1    # Continue<br />
        command_continue<br />
      when 2    # Shutdown<br />
        command_shutdown<br />
      end<br />
    # Added Right Click Check<br />
    elsif Input.right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      if @command_window.index &lt; 2<br />
        @command_window.index = 2<br />
      end<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Map<br />
  def update_call_menu<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      return if &#36;game_map.interpreter.running?<br />
      return if &#36;game_system.menu_disabled<br />
      &#36;game_temp.menu_beep = true<br />
      &#36;game_temp.next_scene = "menu"<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Menu<br />
  def update_command_selection<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      Sound.play_cancel<br />
      &#36;scene = Scene_Map.new<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      if &#36;game_party.members.size == 0 and @command_window.index &lt; 4<br />
        Sound.play_buzzer<br />
        return<br />
      elsif &#36;game_system.save_disabled and @command_window.index == 4<br />
        Sound.play_buzzer<br />
        return<br />
      end<br />
      Sound.play_decision<br />
      case @command_window.index<br />
      when 0      # Item<br />
        &#36;scene = Scene_Item.new<br />
      when 1,2,3  # Skill, equipment, status<br />
        start_actor_selection<br />
      when 4      # Save<br />
        &#36;scene = Scene_File.new(true, false, false)<br />
      when 5      # End Game<br />
        &#36;scene = Scene_End.new<br />
      end<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_End<br />
  def update<br />
    super<br />
    update_menu_background<br />
    @command_window.update<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      Sound.play_cancel<br />
      return_scene<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      case @command_window.index<br />
      when 0  # to title<br />
        command_to_title<br />
      when 1  # shutdown<br />
        command_shutdown<br />
      when 2  # quit<br />
        command_cancel<br />
      end<br />
    end<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RM VX ACE Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * ClickableWindow ACE * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   2025-01-11<br />
<br />
# This is a script demo that shows you how it is now possible to click once on<br />
# a menu window to choose an option while ignoring the surrounding area.<br />
# Normally, you would have to add some calls to Input.left_click? or<br />
# Input.right_click? or even Input.middle_click? to your target scenes to make<br />
# this work.<br />
<br />
class Window_Selectable<br />
  def process_cursor_move<br />
    return unless cursor_movable?<br />
    last_index = @index<br />
    if Input.left_click?<br />
      # Set Index to invisible if clicked outside this window<br />
      self.index = -1<br />
      # Check each area - a list of Rect's<br />
      @area.size.times do |n|<br />
        next unless mouse_inside?(n)<br />
        self.index = n<br />
        Sound.play_cursor<br />
        break<br />
      end<br />
      return<br />
    end<br />
    cursor_down (Input.trigger?(:DOWN))  if Input.repeat?(:DOWN)<br />
    cursor_up   (Input.trigger?(:UP))    if Input.repeat?(:UP)<br />
    cursor_right(Input.trigger?(:RIGHT)) if Input.repeat?(:RIGHT)<br />
    cursor_left (Input.trigger?(:LEFT))  if Input.repeat?(:LEFT)<br />
    cursor_pagedown   if !handle?(:pagedown) &amp;&amp; Input.trigger?(:R)<br />
    cursor_pageup     if !handle?(:pageup)   &amp;&amp; Input.trigger?(:L)<br />
    Sound.play_cursor if @index != last_index<br />
  end<br />
<br />
  def process_handling<br />
    return unless open? &amp;&amp; active<br />
    return process_ok       if ok_enabled? &amp;&amp; Input.double_left_click?<br />
    return process_cancel   if cancel_enabled? &amp;&amp; Input.double_right_click?<br />
    return process_ok       if ok_enabled?        &amp;&amp; Input.trigger?(:C)<br />
    return process_cancel   if cancel_enabled?    &amp;&amp; Input.trigger?(:B)<br />
    return process_pagedown if handle?(:pagedown) &amp;&amp; Input.trigger?(:R)<br />
    return process_pageup   if handle?(:pageup)   &amp;&amp; Input.trigger?(:L)<br />
  end<br />
end<br />
<br />
class Window_Command<br />
  def draw_item(n)<br />
    rect = @area[n] ||= item_rect_for_text(n)<br />
    change_color(normal_color, command_enabled?(n))<br />
    draw_text(rect, command_name(n), alignment)<br />
  end<br />
end<br />
<br />
class Window_MenuCommand<br />
  def select_last<br />
    select_symbol(@@last_command_symbol)<br />
    Mouse.set_xy(80, 20 + @index * 24)<br />
  end<br />
end<br />
<br />
class Window_SaveFile<br />
  alias :kyon_click_win_win_svfl_init :initialize<br />
  def initialize(height, index)<br />
    kyon_click_win_win_svfl_init(height, index)<br />
    @area &lt;&lt; self.contents.rect<br />
  end<br />
end<br />
<br />
class Scene_File<br />
  def update_savefile_selection<br />
    if Input.double_left_click?<br />
      @savefile_windows.each_with_index do |win, n|<br />
        next unless win.mouse_inside?<br />
        choose_file(n)<br />
        on_savefile_ok<br />
        break<br />
      end<br />
      return<br />
    elsif Input.left_click?<br />
      @savefile_windows.each_with_index do |win, n|<br />
        next unless win.mouse_inside?<br />
        choose_file(n)<br />
        break<br />
      end<br />
      return<br />
    elsif Input.double_right_click?<br />
      on_savefile_cancel<br />
      return<br />
    end<br />
    return on_savefile_ok     if Input.trigger?(:C)<br />
    return on_savefile_cancel if Input.trigger?(:B)<br />
    update_cursor<br />
  end<br />
<br />
  def choose_file(n)<br />
    @savefile_windows[@index].selected = false<br />
    @savefile_windows[n].selected = true<br />
    @index = n<br />
    ensure_cursor_visible<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" />]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[KSoundFontMenu]]></title>
			<link>https://www.save-point.org/thread-8955.html</link>
			<pubDate>Fri, 24 May 2024 05:04:26 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=1471">kyonides</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-8955.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KSoundFontMenu</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">HiddenChest Exclusive!</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">XP + VX + ACE Related<br />
<br />
by Kyonides</span></span></div>
<br />
This scriptlet allows you to actually play a specific MIDI melody AND change the current synthesizer's <span style="font-weight: bold;" class="mycode_b">SoundFont!</span> <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
<br />
All of these scripts will only work by running the HiddenChest binary executable.<br />
<br />
There are certain consideration to take in consideration before using it:<br />
<ul class="mycode_list"><li>The MIDI file should be playing BEFORE you proceed to call Setup.choose_soundfont(index)<br />
Otherwise the change would be ignored by the internal system.<br />
</li>
<li>Some scenes might take advantage of setting the current soundfont again, no filename change involved here, to make sure it will be using the selected soundfont.<br />
Yet, it is not mandatory because this apparent issue could have been caused by using some soundfonts with similar sound sets.<br />
</li>
<li>The change may take a couple of seconds to take effect.<br />
That is why I added the "Processing New SF..." label to the KSoundFont module. <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Extra Step</span><br />
<br />
Add the following lines to your Game.ini file:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>SoundFontWin=C:/Audio/SF2/GMGSx.sf2<br />
SoundFontLnx=/home/user/Maker/GMGSx.sf2<br />
SoundFontPathWin=C:/Music/SF2<br />
SoundFontPathLnx=/home/user/Music/SF2</code></div></div><br />
These lines will allow the HiddenChest engine find your custom SoundFonts on both Windows &amp; Linux! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
Keep in mind that HiddenChest has always been a cross-platform engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><br />
<br />
<hr class="mycode_hr" />
<span style="font-weight: bold;" class="mycode_b">Script Calls</span><br />
<br />
Open the KSoundFont::Menu Scene depending on your RM Editor:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;scene = KSoundFont::Menu.new<br />
SceneManager(KSoundFont::Menu)</code></div></div><br />
Select Your Favorite SoundFont - All Versions:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>Game.choose_soundfont(index)</code></div></div><br />
Getting and Saving the Index of Your Favorite SoundFont<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;game_system.soundfont_index<br />
&#36;game_system.soundfont_index = Number</code></div></div><br />
Getting a SoundFont (Full Path) Based on its Current Position:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>Game.soundfonts[index]</code></div></div><br />
Default SoundFont (if it Exists):<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>System::SOUNDFONT</code></div></div><br />
Default SoundFont Directory (It Should Exist if you ever pretend to add 2+ SoundFonts):<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>System::SOUNDFONT_DIR</code></div></div><br />
<hr class="mycode_hr" />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Scripts Section</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Script For RMXP Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KSoundFontMenu XP * # <br />
#   Scripter : Kyonides Arkanthes<br />
#   2024-06-03<br />
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call<br />
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI<br />
#       synthetizer might ignore your request at that specific point.<br />
#       Calling the same method at the beginning of KSoundFont::Menu ensures it<br />
#       will always play the MIDI using the chosen soundfont.<br />
# * Script Call * #<br />
# &#36;scene = KSoundFont::Menu.new<br />
module KSoundFont<br />
  START_SF = [0]<br />
  TITLE = "Select a SoundFont"<br />
  THIS_SOUNDFONT = "Current SoundFont"<br />
  DELAY_MESSAGE = "Processing New SF..."<br />
  NO_SOUNDFONT = "No SoundFont"<br />
  TRANSPARENT = Color.new(0, 0, 0, 0)<br />
class PathsWindow &lt; Window_Command<br />
  def initialize(w, paths)<br />
    @paths = paths<br />
    commands = paths.map {|fn| fn.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "") }<br />
    super(w, commands)<br />
  end<br />
  def path<br />
    @paths[@index]<br />
  end<br />
  def name<br />
    @commands[@index]<br />
  end<br />
end<br />
class SmallInfoWindow &lt; Window_Base<br />
  def initialize(wx, wy, w, h)<br />
    super<br />
    self.contents = Bitmap.new(w - 32, h - 32)<br />
    contents.font.color = system_color<br />
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)<br />
    contents.font.color = normal_color<br />
  end<br />
  def set_text(text)<br />
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)<br />
    contents.draw_text(0, 32, width - 32, 32, text, 1)<br />
  end<br />
end<br />
class Menu<br />
  def main<br />
    @timer = 0<br />
    pos = &#36;game_system.soundfont_index<br />
    Game.choose_soundfont(pos)<br />
    soundfonts = Game.soundfonts<br />
    gs_indexes = &#36;game_system.soundfont_indexes<br />
    if gs_indexes.any?<br />
      @indexes = gs_indexes.sort<br />
      if @indexes.size &lt; soundfonts.size<br />
        soundfonts = @indexes.map{|n| soundfonts[n] }<br />
      end<br />
    end<br />
    @total = soundfonts.size<br />
    @full_list = Game.soundfonts.size == @total<br />
    soundfont = soundfonts[pos]<br />
    dialog_box soundfont<br />
    if soundfonts.any?<br />
      soundfont = soundfont.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "")<br />
    else<br />
      soundfont = NO_SOUNDFONT<br />
    end<br />
    @help_window = Window_Help.new<br />
    @help_window.set_text(TITLE, 1)<br />
    @command_window = PathsWindow.new(192, soundfonts)<br />
    @command_window.y = 64<br />
    @command_window.index = pos<br />
    @info_window = SmallInfoWindow.new(192, @command_window.y, 240, 96)<br />
    @info_window.set_text(soundfont)<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      break if &#36;scene != self<br />
    end<br />
    Graphics.freeze<br />
    @info_window.dispose<br />
    @command_window.dispose<br />
    @help_window.dispose<br />
  end<br />
  def update<br />
    if @timer &gt; 0<br />
      @timer -= 1<br />
      if @timer == 0<br />
        @info_window.set_text(@command_window.name)<br />
      end<br />
      return<br />
    end<br />
    @command_window.update<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Map.new<br />
      return<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      if @total &lt; 2<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      n = @command_window.index<br />
      n = @indexes[n] unless @full_list<br />
      &#36;game_system.soundfont_index = n<br />
      @info_window.set_text(DELAY_MESSAGE)<br />
      @timer = Graphics.frame_rate * 2<br />
    elsif Input.trigger?(Input::SHIFT)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
end<br />
end<br />
class Game_System<br />
  alias :kyon_soundfont_menu_gm_sys_init :initialize<br />
  def initialize<br />
    kyon_soundfont_menu_gm_sys_init<br />
    self.soundfont_index = find_soundfont_index<br />
    @soundfont_indexes = KSoundFont::START_SF.dup<br />
  end<br />
  def find_soundfont_index<br />
    Game.soundfont_index || 0<br />
  end<br />
  def soundfont_index<br />
    @soundfont_index ||= find_soundfont_index<br />
  end<br />
  def soundfont_index=(n)<br />
    Game.choose_soundfont(n)<br />
    @soundfont_index = n<br />
  end<br />
  def soundfont_indexes<br />
    @soundfont_indexes ||= []<br />
  end<br />
end<br />
class Scene_Load<br />
  alias :kyon_soundfont_menu_scn_ld_rsd :read_save_data<br />
  def read_save_data(file)<br />
    kyon_soundfont_menu_scn_ld_rsd(file)<br />
    &#36;game_system.bgm_play(&#36;game_system.playing_bgm)<br />
    Game.choose_soundfont(&#36;game_system.soundfont_index)<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RMVX Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KSoundFontMenu VX * # <br />
#   Scripter : Kyonides Arkanthes<br />
#   2024-06-03<br />
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call<br />
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI<br />
#       synthetizer might ignore your request at that specific point.<br />
#       Calling the same method at the beginning of KSoundFont::Menu ensures it<br />
#       will always play the MIDI using the chosen soundfont.<br />
# * Script Call * #<br />
# &#36;scene = KSoundFont::Menu.new<br />
module KSoundFont<br />
  START_SF = [0]<br />
  TITLE = "Select a SoundFont"<br />
  THIS_SOUNDFONT = "Current SoundFont"<br />
  DELAY_MESSAGE = "Processing New SF..."<br />
  NO_SOUNDFONT = "No SoundFont"<br />
  TRANSPARENT = Color.new(0, 0, 0, 0)<br />
class PathsWindow &lt; Window_Command<br />
  def initialize(w, paths)<br />
    @paths = paths<br />
    commands = paths.map {|fn| fn.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "") }<br />
    super(w, commands)<br />
  end<br />
  def path<br />
    @paths[@index]<br />
  end<br />
  def name<br />
    @commands[@index]<br />
  end<br />
end<br />
class SmallInfoWindow &lt; Window_Base<br />
  def initialize(wx, wy, w, h)<br />
    super<br />
    self.contents = Bitmap.new(w - 32, h - 32)<br />
    contents.font.color = system_color<br />
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)<br />
    contents.font.color = normal_color<br />
  end<br />
  def set_text(text)<br />
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)<br />
    contents.draw_text(0, 32, width - 32, 32, text, 1)<br />
  end<br />
end<br />
class Menu<br />
  def main<br />
    @timer = 0<br />
    pos = &#36;game_system.soundfont_index<br />
    Game.choose_soundfont(pos)<br />
    soundfonts = Game.soundfonts<br />
    gs_indexes = &#36;game_system.soundfont_indexes<br />
    if gs_indexes.any?<br />
      @indexes = gs_indexes.sort<br />
      if @indexes.size &lt; soundfonts.size<br />
        soundfonts = @indexes.map{|n| soundfonts[n] }<br />
      end<br />
    end<br />
    @total = soundfonts.size<br />
    @full_list = Game.soundfonts.size == @total<br />
    soundfont = soundfonts[pos]<br />
    if soundfonts.any?<br />
      soundfont = soundfont.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "")<br />
    else<br />
      soundfont = NO_SOUNDFONT<br />
    end<br />
    @help_window = Window_Help.new<br />
    @help_window.set_text(TITLE, 1)<br />
    hwy = @help_window.height<br />
    @command_window = PathsWindow.new(192, soundfonts)<br />
    @command_window.y = hwy<br />
    @command_window.index = pos<br />
    @info_window = SmallInfoWindow.new(192, hwy, 240, 96)<br />
    @info_window.set_text(soundfont)<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      break if &#36;scene != self<br />
    end<br />
    Graphics.freeze<br />
    @info_window.dispose<br />
    @command_window.dispose<br />
    @help_window.dispose<br />
  end<br />
  def update<br />
    if @timer &gt; 0<br />
      @timer -= 1<br />
      if @timer == 0<br />
        @info_window.set_text(@command_window.name)<br />
      end<br />
      return<br />
    end<br />
    @command_window.update<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      Sound.play_cancel<br />
      &#36;scene = Scene_Map.new<br />
      return<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      return Sound.play_buzzer if @total &lt; 2<br />
      Sound.play_decision<br />
      n = @command_window.index<br />
      n = @indexes[n] unless @full_list<br />
      &#36;game_system.soundfont_index = n<br />
      @info_window.set_text(DELAY_MESSAGE)<br />
      @timer = Graphics.frame_rate * 2<br />
    elsif Input.trigger?(Input::SHIFT)<br />
      Sound.play_cursor<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
end<br />
end<br />
class Game_System<br />
  alias :kyon_soundfont_menu_gm_sys_init :initialize<br />
  def initialize<br />
    kyon_soundfont_menu_gm_sys_init<br />
    self.soundfont_index = find_soundfont_index<br />
    @soundfont_indexes = KSoundFont::START_SF.dup<br />
  end<br />
  def find_soundfont_index<br />
    Game.soundfont_index || 0<br />
  end<br />
  def soundfont_index<br />
    @soundfont_index ||= find_soundfont_index<br />
  end<br />
  def soundfont_index=(n)<br />
    Game.choose_soundfont(n)<br />
    @soundfont_index = n<br />
  end<br />
  def soundfont_indexes<br />
    @soundfont_indexes ||= []<br />
  end<br />
end<br />
class Scene_File<br />
  alias :kyon_soundfont_menu_scn_fl_rsd :read_save_data<br />
  def read_save_data(file)<br />
    kyon_soundfont_menu_scn_fl_rsd(file)<br />
    @last_bgm.play<br />
    Game.choose_soundfont(&#36;game_system.soundfont_index)<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RMVX ACE Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KSoundFontMenu ACE * # <br />
#   Scripter : Kyonides Arkanthes<br />
#   2024-06-03<br />
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call<br />
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI<br />
#       synthetizer might ignore your request at that specific point.<br />
#       Calling the same method at the beginning of KSoundFont::Menu ensures it<br />
#       will always play the MIDI using the chosen soundfont.<br />
# * Script Call * #<br />
# SceneManager(KSoundFont::Menu)<br />
module KSoundFont<br />
  START_SF = [0]<br />
  TITLE = "Select a SoundFont"<br />
  THIS_SOUNDFONT = "Current SoundFont"<br />
  DELAY_MESSAGE = "Processing New SF..."<br />
  NO_SOUNDFONT = "No SoundFont"<br />
  TRANSPARENT = Color.new(0, 0, 0, 0)<br />
class HelpWindow &lt; Window_Help<br />
  def set_text(text, align)<br />
    return if text == @text and align == @align<br />
    @text = text<br />
    @align = align<br />
    refresh<br />
  end<br />
  def refresh<br />
    contents.clear<br />
    draw_text(contents.rect, @text, @align)<br />
  end<br />
end<br />
class PathsWindow &lt; Window_Selectable<br />
  def initialize(w, paths)<br />
    @paths = paths<br />
    @commands = paths.map {|fn| fn.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "") }<br />
    @item_max = @commands.size<br />
    h = @item_max * line_height + line_height<br />
    super(0, 0, w, h)<br />
    return if @item_max == 0<br />
    refresh<br />
    self.active = true<br />
  end<br />
  def draw_all_items<br />
    @item_max.times do |n|<br />
      rect = @area[n] ||= item_rect_for_text(n)<br />
      draw_text(rect, @commands[n])<br />
    end<br />
  end<br />
  def process_handling<br />
    <br />
  end<br />
  def path<br />
    @paths[@index]<br />
  end<br />
  def name<br />
    @commands[@index]<br />
  end<br />
  attr_reader :item_max<br />
end<br />
class SmallInfoWindow &lt; Window_Base<br />
  def initialize(wx, wy, w, h)<br />
    super<br />
    self.contents = Bitmap.new(w - 32, h - 32)<br />
    contents.font.color = system_color<br />
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)<br />
    contents.font.color = normal_color<br />
  end<br />
  def set_text(text)<br />
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)<br />
    contents.draw_text(0, 32, width - 32, 32, text, 1)<br />
  end<br />
end<br />
class Menu &lt; Scene_Base<br />
  def start<br />
    super<br />
    @timer = 0<br />
    pos = &#36;game_system.soundfont_index<br />
    Game.choose_soundfont(pos)<br />
    soundfonts = Game.soundfonts<br />
    gs_indexes = &#36;game_system.soundfont_indexes<br />
    if gs_indexes.any?<br />
      @indexes = gs_indexes.sort<br />
      if @indexes.size &lt; soundfonts.size<br />
        soundfonts = @indexes.map{|n| soundfonts[n] }<br />
      end<br />
    end<br />
    @total = soundfonts.size<br />
    @full_list = Game.soundfonts.size == @total<br />
    soundfont = soundfonts[pos]<br />
    if soundfonts.any?<br />
      soundfont = soundfont.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "")<br />
    else<br />
      soundfont = NO_SOUNDFONT<br />
    end<br />
    @help_window = HelpWindow.new<br />
    @help_window.set_text(TITLE, 1)<br />
    hwy = @help_window.height<br />
    @command_window = PathsWindow.new(192, soundfonts)<br />
    @command_window.y = hwy<br />
    @command_window.index = pos<br />
    @info_window = SmallInfoWindow.new(192, hwy, 240, 96)<br />
    @info_window.set_text(soundfont)<br />
  end<br />
  def update<br />
    Graphics.update<br />
    Input.update<br />
    if @timer &gt; 0<br />
      @timer -= 1<br />
      if @timer == 0<br />
        @info_window.set_text(@command_window.name)<br />
      end<br />
      return<br />
    end<br />
    @command_window.update<br />
    if Input.trigger?(:B) or Input.double_right_click?<br />
      Sound.play_cancel<br />
      SceneManager.return<br />
      return<br />
    elsif Input.trigger?(:C) or Input.double_left_click?<br />
      return Sound.play_buzzer if @total &lt; 2<br />
      Sound.play_ok<br />
      n = @command_window.index<br />
      n = @indexes[n] unless @full_list<br />
      &#36;game_system.soundfont_index = n<br />
      @info_window.set_text(DELAY_MESSAGE)<br />
      @timer = Graphics.frame_rate * 2<br />
    elsif Input.trigger?(:SHIFT)<br />
      Sound.play_cursor<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
end<br />
end<br />
class Game_System<br />
  alias :kyon_soundfont_menu_gm_sys_init :initialize<br />
  alias :kyon_soundfont_menu_gm_sys_on_after_load :on_after_load<br />
  def initialize<br />
    kyon_soundfont_menu_gm_sys_init<br />
    self.soundfont_index = find_soundfont_index<br />
    @soundfont_indexes = KSoundFont::START_SF.dup<br />
  end<br />
  def find_soundfont_index<br />
    Game.soundfont_index || 0<br />
  end<br />
  def soundfont_index<br />
    @soundfont_index ||= find_soundfont_index<br />
  end<br />
  def soundfont_index=(n)<br />
    Game.choose_soundfont(n)<br />
    @soundfont_index = n<br />
  end<br />
  def soundfont_indexes<br />
    @soundfont_indexes ||= []<br />
  end<br />
  def on_after_load<br />
    kyon_soundfont_menu_gm_sys_on_after_load<br />
    Game.choose_soundfont(&#36;game_system.soundfont_index)<br />
  end<br />
end</code></div></div><br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Screenshots</span></span></div>
<br />
<div class="tborder">
  			<div class="thead" style="padding:4px; margin:1px;"><input type="button" class="button" value="+" style="font-family:Monospace; padding:0px" onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].style.display=='none'){ this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='';this.value='-';} else {this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='none';this.value='+';}"/> 3 Snapshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<div style="text-align: center;" class="mycode_align">
<img src="https://www.save-point.org/attachment.php?aid=2111" loading="lazy"  alt="[Image: attachment.php?aid=2111]" class="mycode_img" /><br />
<img src="https://www.save-point.org/attachment.php?aid=2115" loading="lazy"  alt="[Image: attachment.php?aid=2115]" class="mycode_img" /><br />
<img src="https://www.save-point.org/attachment.php?aid=2120" loading="lazy"  alt="[Image: attachment.php?aid=2120]" class="mycode_img" /><br />
<br />
</div>
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" /><br />
<br />
<img src="https://www.save-point.org/images/attachtypes/image.gif" title="JPG Image" border="0" alt=".jpg" />
&nbsp;&nbsp;<a href="attachment.php?aid=2115" target="_blank" title="">ksoundfont_vx001.jpg</a> (Size: 40.18 KB / Downloads: 475)
<br />
<br />
<img src="https://www.save-point.org/images/attachtypes/image.gif" title="JPG Image" border="0" alt=".jpg" />
&nbsp;&nbsp;<a href="attachment.php?aid=2120" target="_blank" title="">ksoundfont_ace001.jpg</a> (Size: 32.63 KB / Downloads: 452)
]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KSoundFontMenu</span></span></div>
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">HiddenChest Exclusive!</span></span></div>
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">XP + VX + ACE Related<br />
<br />
by Kyonides</span></span></div>
<br />
This scriptlet allows you to actually play a specific MIDI melody AND change the current synthesizer's <span style="font-weight: bold;" class="mycode_b">SoundFont!</span> <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
<br />
All of these scripts will only work by running the HiddenChest binary executable.<br />
<br />
There are certain consideration to take in consideration before using it:<br />
<ul class="mycode_list"><li>The MIDI file should be playing BEFORE you proceed to call Setup.choose_soundfont(index)<br />
Otherwise the change would be ignored by the internal system.<br />
</li>
<li>Some scenes might take advantage of setting the current soundfont again, no filename change involved here, to make sure it will be using the selected soundfont.<br />
Yet, it is not mandatory because this apparent issue could have been caused by using some soundfonts with similar sound sets.<br />
</li>
<li>The change may take a couple of seconds to take effect.<br />
That is why I added the "Processing New SF..." label to the KSoundFont module. <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Extra Step</span><br />
<br />
Add the following lines to your Game.ini file:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>SoundFontWin=C:/Audio/SF2/GMGSx.sf2<br />
SoundFontLnx=/home/user/Maker/GMGSx.sf2<br />
SoundFontPathWin=C:/Music/SF2<br />
SoundFontPathLnx=/home/user/Music/SF2</code></div></div><br />
These lines will allow the HiddenChest engine find your custom SoundFonts on both Windows &amp; Linux! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
Keep in mind that HiddenChest has always been a cross-platform engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><br />
<br />
<hr class="mycode_hr" />
<span style="font-weight: bold;" class="mycode_b">Script Calls</span><br />
<br />
Open the KSoundFont::Menu Scene depending on your RM Editor:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;scene = KSoundFont::Menu.new<br />
SceneManager(KSoundFont::Menu)</code></div></div><br />
Select Your Favorite SoundFont - All Versions:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>Game.choose_soundfont(index)</code></div></div><br />
Getting and Saving the Index of Your Favorite SoundFont<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;game_system.soundfont_index<br />
&#36;game_system.soundfont_index = Number</code></div></div><br />
Getting a SoundFont (Full Path) Based on its Current Position:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>Game.soundfonts[index]</code></div></div><br />
Default SoundFont (if it Exists):<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>System::SOUNDFONT</code></div></div><br />
Default SoundFont Directory (It Should Exist if you ever pretend to add 2+ SoundFonts):<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>System::SOUNDFONT_DIR</code></div></div><br />
<hr class="mycode_hr" />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Scripts Section</span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Script For RMXP Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KSoundFontMenu XP * # <br />
#   Scripter : Kyonides Arkanthes<br />
#   2024-06-03<br />
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call<br />
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI<br />
#       synthetizer might ignore your request at that specific point.<br />
#       Calling the same method at the beginning of KSoundFont::Menu ensures it<br />
#       will always play the MIDI using the chosen soundfont.<br />
# * Script Call * #<br />
# &#36;scene = KSoundFont::Menu.new<br />
module KSoundFont<br />
  START_SF = [0]<br />
  TITLE = "Select a SoundFont"<br />
  THIS_SOUNDFONT = "Current SoundFont"<br />
  DELAY_MESSAGE = "Processing New SF..."<br />
  NO_SOUNDFONT = "No SoundFont"<br />
  TRANSPARENT = Color.new(0, 0, 0, 0)<br />
class PathsWindow &lt; Window_Command<br />
  def initialize(w, paths)<br />
    @paths = paths<br />
    commands = paths.map {|fn| fn.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "") }<br />
    super(w, commands)<br />
  end<br />
  def path<br />
    @paths[@index]<br />
  end<br />
  def name<br />
    @commands[@index]<br />
  end<br />
end<br />
class SmallInfoWindow &lt; Window_Base<br />
  def initialize(wx, wy, w, h)<br />
    super<br />
    self.contents = Bitmap.new(w - 32, h - 32)<br />
    contents.font.color = system_color<br />
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)<br />
    contents.font.color = normal_color<br />
  end<br />
  def set_text(text)<br />
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)<br />
    contents.draw_text(0, 32, width - 32, 32, text, 1)<br />
  end<br />
end<br />
class Menu<br />
  def main<br />
    @timer = 0<br />
    pos = &#36;game_system.soundfont_index<br />
    Game.choose_soundfont(pos)<br />
    soundfonts = Game.soundfonts<br />
    gs_indexes = &#36;game_system.soundfont_indexes<br />
    if gs_indexes.any?<br />
      @indexes = gs_indexes.sort<br />
      if @indexes.size &lt; soundfonts.size<br />
        soundfonts = @indexes.map{|n| soundfonts[n] }<br />
      end<br />
    end<br />
    @total = soundfonts.size<br />
    @full_list = Game.soundfonts.size == @total<br />
    soundfont = soundfonts[pos]<br />
    dialog_box soundfont<br />
    if soundfonts.any?<br />
      soundfont = soundfont.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "")<br />
    else<br />
      soundfont = NO_SOUNDFONT<br />
    end<br />
    @help_window = Window_Help.new<br />
    @help_window.set_text(TITLE, 1)<br />
    @command_window = PathsWindow.new(192, soundfonts)<br />
    @command_window.y = 64<br />
    @command_window.index = pos<br />
    @info_window = SmallInfoWindow.new(192, @command_window.y, 240, 96)<br />
    @info_window.set_text(soundfont)<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      break if &#36;scene != self<br />
    end<br />
    Graphics.freeze<br />
    @info_window.dispose<br />
    @command_window.dispose<br />
    @help_window.dispose<br />
  end<br />
  def update<br />
    if @timer &gt; 0<br />
      @timer -= 1<br />
      if @timer == 0<br />
        @info_window.set_text(@command_window.name)<br />
      end<br />
      return<br />
    end<br />
    @command_window.update<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      &#36;game_system.se_play(&#36;data_system.cancel_se)<br />
      &#36;scene = Scene_Map.new<br />
      return<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      if @total &lt; 2<br />
        &#36;game_system.se_play(&#36;data_system.buzzer_se)<br />
        return<br />
      end<br />
      &#36;game_system.se_play(&#36;data_system.decision_se)<br />
      n = @command_window.index<br />
      n = @indexes[n] unless @full_list<br />
      &#36;game_system.soundfont_index = n<br />
      @info_window.set_text(DELAY_MESSAGE)<br />
      @timer = Graphics.frame_rate * 2<br />
    elsif Input.trigger?(Input::SHIFT)<br />
      &#36;game_system.se_play(&#36;data_system.cursor_se)<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
end<br />
end<br />
class Game_System<br />
  alias :kyon_soundfont_menu_gm_sys_init :initialize<br />
  def initialize<br />
    kyon_soundfont_menu_gm_sys_init<br />
    self.soundfont_index = find_soundfont_index<br />
    @soundfont_indexes = KSoundFont::START_SF.dup<br />
  end<br />
  def find_soundfont_index<br />
    Game.soundfont_index || 0<br />
  end<br />
  def soundfont_index<br />
    @soundfont_index ||= find_soundfont_index<br />
  end<br />
  def soundfont_index=(n)<br />
    Game.choose_soundfont(n)<br />
    @soundfont_index = n<br />
  end<br />
  def soundfont_indexes<br />
    @soundfont_indexes ||= []<br />
  end<br />
end<br />
class Scene_Load<br />
  alias :kyon_soundfont_menu_scn_ld_rsd :read_save_data<br />
  def read_save_data(file)<br />
    kyon_soundfont_menu_scn_ld_rsd(file)<br />
    &#36;game_system.bgm_play(&#36;game_system.playing_bgm)<br />
    Game.choose_soundfont(&#36;game_system.soundfont_index)<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RMVX Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KSoundFontMenu VX * # <br />
#   Scripter : Kyonides Arkanthes<br />
#   2024-06-03<br />
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call<br />
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI<br />
#       synthetizer might ignore your request at that specific point.<br />
#       Calling the same method at the beginning of KSoundFont::Menu ensures it<br />
#       will always play the MIDI using the chosen soundfont.<br />
# * Script Call * #<br />
# &#36;scene = KSoundFont::Menu.new<br />
module KSoundFont<br />
  START_SF = [0]<br />
  TITLE = "Select a SoundFont"<br />
  THIS_SOUNDFONT = "Current SoundFont"<br />
  DELAY_MESSAGE = "Processing New SF..."<br />
  NO_SOUNDFONT = "No SoundFont"<br />
  TRANSPARENT = Color.new(0, 0, 0, 0)<br />
class PathsWindow &lt; Window_Command<br />
  def initialize(w, paths)<br />
    @paths = paths<br />
    commands = paths.map {|fn| fn.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "") }<br />
    super(w, commands)<br />
  end<br />
  def path<br />
    @paths[@index]<br />
  end<br />
  def name<br />
    @commands[@index]<br />
  end<br />
end<br />
class SmallInfoWindow &lt; Window_Base<br />
  def initialize(wx, wy, w, h)<br />
    super<br />
    self.contents = Bitmap.new(w - 32, h - 32)<br />
    contents.font.color = system_color<br />
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)<br />
    contents.font.color = normal_color<br />
  end<br />
  def set_text(text)<br />
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)<br />
    contents.draw_text(0, 32, width - 32, 32, text, 1)<br />
  end<br />
end<br />
class Menu<br />
  def main<br />
    @timer = 0<br />
    pos = &#36;game_system.soundfont_index<br />
    Game.choose_soundfont(pos)<br />
    soundfonts = Game.soundfonts<br />
    gs_indexes = &#36;game_system.soundfont_indexes<br />
    if gs_indexes.any?<br />
      @indexes = gs_indexes.sort<br />
      if @indexes.size &lt; soundfonts.size<br />
        soundfonts = @indexes.map{|n| soundfonts[n] }<br />
      end<br />
    end<br />
    @total = soundfonts.size<br />
    @full_list = Game.soundfonts.size == @total<br />
    soundfont = soundfonts[pos]<br />
    if soundfonts.any?<br />
      soundfont = soundfont.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "")<br />
    else<br />
      soundfont = NO_SOUNDFONT<br />
    end<br />
    @help_window = Window_Help.new<br />
    @help_window.set_text(TITLE, 1)<br />
    hwy = @help_window.height<br />
    @command_window = PathsWindow.new(192, soundfonts)<br />
    @command_window.y = hwy<br />
    @command_window.index = pos<br />
    @info_window = SmallInfoWindow.new(192, hwy, 240, 96)<br />
    @info_window.set_text(soundfont)<br />
    Graphics.transition<br />
    loop do<br />
      Graphics.update<br />
      Input.update<br />
      update<br />
      break if &#36;scene != self<br />
    end<br />
    Graphics.freeze<br />
    @info_window.dispose<br />
    @command_window.dispose<br />
    @help_window.dispose<br />
  end<br />
  def update<br />
    if @timer &gt; 0<br />
      @timer -= 1<br />
      if @timer == 0<br />
        @info_window.set_text(@command_window.name)<br />
      end<br />
      return<br />
    end<br />
    @command_window.update<br />
    if Input.trigger?(Input::B) or Input.double_right_click?<br />
      Sound.play_cancel<br />
      &#36;scene = Scene_Map.new<br />
      return<br />
    elsif Input.trigger?(Input::C) or Input.double_left_click?<br />
      return Sound.play_buzzer if @total &lt; 2<br />
      Sound.play_decision<br />
      n = @command_window.index<br />
      n = @indexes[n] unless @full_list<br />
      &#36;game_system.soundfont_index = n<br />
      @info_window.set_text(DELAY_MESSAGE)<br />
      @timer = Graphics.frame_rate * 2<br />
    elsif Input.trigger?(Input::SHIFT)<br />
      Sound.play_cursor<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
end<br />
end<br />
class Game_System<br />
  alias :kyon_soundfont_menu_gm_sys_init :initialize<br />
  def initialize<br />
    kyon_soundfont_menu_gm_sys_init<br />
    self.soundfont_index = find_soundfont_index<br />
    @soundfont_indexes = KSoundFont::START_SF.dup<br />
  end<br />
  def find_soundfont_index<br />
    Game.soundfont_index || 0<br />
  end<br />
  def soundfont_index<br />
    @soundfont_index ||= find_soundfont_index<br />
  end<br />
  def soundfont_index=(n)<br />
    Game.choose_soundfont(n)<br />
    @soundfont_index = n<br />
  end<br />
  def soundfont_indexes<br />
    @soundfont_indexes ||= []<br />
  end<br />
end<br />
class Scene_File<br />
  alias :kyon_soundfont_menu_scn_fl_rsd :read_save_data<br />
  def read_save_data(file)<br />
    kyon_soundfont_menu_scn_fl_rsd(file)<br />
    @last_bgm.play<br />
    Game.choose_soundfont(&#36;game_system.soundfont_index)<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Script for RMVX ACE Editor</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KSoundFontMenu ACE * # <br />
#   Scripter : Kyonides Arkanthes<br />
#   2024-06-03<br />
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call<br />
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI<br />
#       synthetizer might ignore your request at that specific point.<br />
#       Calling the same method at the beginning of KSoundFont::Menu ensures it<br />
#       will always play the MIDI using the chosen soundfont.<br />
# * Script Call * #<br />
# SceneManager(KSoundFont::Menu)<br />
module KSoundFont<br />
  START_SF = [0]<br />
  TITLE = "Select a SoundFont"<br />
  THIS_SOUNDFONT = "Current SoundFont"<br />
  DELAY_MESSAGE = "Processing New SF..."<br />
  NO_SOUNDFONT = "No SoundFont"<br />
  TRANSPARENT = Color.new(0, 0, 0, 0)<br />
class HelpWindow &lt; Window_Help<br />
  def set_text(text, align)<br />
    return if text == @text and align == @align<br />
    @text = text<br />
    @align = align<br />
    refresh<br />
  end<br />
  def refresh<br />
    contents.clear<br />
    draw_text(contents.rect, @text, @align)<br />
  end<br />
end<br />
class PathsWindow &lt; Window_Selectable<br />
  def initialize(w, paths)<br />
    @paths = paths<br />
    @commands = paths.map {|fn| fn.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "") }<br />
    @item_max = @commands.size<br />
    h = @item_max * line_height + line_height<br />
    super(0, 0, w, h)<br />
    return if @item_max == 0<br />
    refresh<br />
    self.active = true<br />
  end<br />
  def draw_all_items<br />
    @item_max.times do |n|<br />
      rect = @area[n] ||= item_rect_for_text(n)<br />
      draw_text(rect, @commands[n])<br />
    end<br />
  end<br />
  def process_handling<br />
    <br />
  end<br />
  def path<br />
    @paths[@index]<br />
  end<br />
  def name<br />
    @commands[@index]<br />
  end<br />
  attr_reader :item_max<br />
end<br />
class SmallInfoWindow &lt; Window_Base<br />
  def initialize(wx, wy, w, h)<br />
    super<br />
    self.contents = Bitmap.new(w - 32, h - 32)<br />
    contents.font.color = system_color<br />
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)<br />
    contents.font.color = normal_color<br />
  end<br />
  def set_text(text)<br />
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)<br />
    contents.draw_text(0, 32, width - 32, 32, text, 1)<br />
  end<br />
end<br />
class Menu &lt; Scene_Base<br />
  def start<br />
    super<br />
    @timer = 0<br />
    pos = &#36;game_system.soundfont_index<br />
    Game.choose_soundfont(pos)<br />
    soundfonts = Game.soundfonts<br />
    gs_indexes = &#36;game_system.soundfont_indexes<br />
    if gs_indexes.any?<br />
      @indexes = gs_indexes.sort<br />
      if @indexes.size &lt; soundfonts.size<br />
        soundfonts = @indexes.map{|n| soundfonts[n] }<br />
      end<br />
    end<br />
    @total = soundfonts.size<br />
    @full_list = Game.soundfonts.size == @total<br />
    soundfont = soundfonts[pos]<br />
    if soundfonts.any?<br />
      soundfont = soundfont.split(/[&#92;/|&#92;&#92;]/)[-1].sub(".sf2", "")<br />
    else<br />
      soundfont = NO_SOUNDFONT<br />
    end<br />
    @help_window = HelpWindow.new<br />
    @help_window.set_text(TITLE, 1)<br />
    hwy = @help_window.height<br />
    @command_window = PathsWindow.new(192, soundfonts)<br />
    @command_window.y = hwy<br />
    @command_window.index = pos<br />
    @info_window = SmallInfoWindow.new(192, hwy, 240, 96)<br />
    @info_window.set_text(soundfont)<br />
  end<br />
  def update<br />
    Graphics.update<br />
    Input.update<br />
    if @timer &gt; 0<br />
      @timer -= 1<br />
      if @timer == 0<br />
        @info_window.set_text(@command_window.name)<br />
      end<br />
      return<br />
    end<br />
    @command_window.update<br />
    if Input.trigger?(:B) or Input.double_right_click?<br />
      Sound.play_cancel<br />
      SceneManager.return<br />
      return<br />
    elsif Input.trigger?(:C) or Input.double_left_click?<br />
      return Sound.play_buzzer if @total &lt; 2<br />
      Sound.play_ok<br />
      n = @command_window.index<br />
      n = @indexes[n] unless @full_list<br />
      &#36;game_system.soundfont_index = n<br />
      @info_window.set_text(DELAY_MESSAGE)<br />
      @timer = Graphics.frame_rate * 2<br />
    elsif Input.trigger?(:SHIFT)<br />
      Sound.play_cursor<br />
      Graphics.screenshot<br />
    end<br />
  end<br />
end<br />
end<br />
class Game_System<br />
  alias :kyon_soundfont_menu_gm_sys_init :initialize<br />
  alias :kyon_soundfont_menu_gm_sys_on_after_load :on_after_load<br />
  def initialize<br />
    kyon_soundfont_menu_gm_sys_init<br />
    self.soundfont_index = find_soundfont_index<br />
    @soundfont_indexes = KSoundFont::START_SF.dup<br />
  end<br />
  def find_soundfont_index<br />
    Game.soundfont_index || 0<br />
  end<br />
  def soundfont_index<br />
    @soundfont_index ||= find_soundfont_index<br />
  end<br />
  def soundfont_index=(n)<br />
    Game.choose_soundfont(n)<br />
    @soundfont_index = n<br />
  end<br />
  def soundfont_indexes<br />
    @soundfont_indexes ||= []<br />
  end<br />
  def on_after_load<br />
    kyon_soundfont_menu_gm_sys_on_after_load<br />
    Game.choose_soundfont(&#36;game_system.soundfont_index)<br />
  end<br />
end</code></div></div><br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Screenshots</span></span></div>
<br />
<div class="tborder">
  			<div class="thead" style="padding:4px; margin:1px;"><input type="button" class="button" value="+" style="font-family:Monospace; padding:0px" onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].style.display=='none'){ this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='';this.value='-';} else {this.parentNode.parentNode.getElementsByTagName('div')[1].style.display='none';this.value='+';}"/> 3 Snapshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<div style="text-align: center;" class="mycode_align">
<img src="https://www.save-point.org/attachment.php?aid=2111" loading="lazy"  alt="[Image: attachment.php?aid=2111]" class="mycode_img" /><br />
<img src="https://www.save-point.org/attachment.php?aid=2115" loading="lazy"  alt="[Image: attachment.php?aid=2115]" class="mycode_img" /><br />
<img src="https://www.save-point.org/attachment.php?aid=2120" loading="lazy"  alt="[Image: attachment.php?aid=2120]" class="mycode_img" /><br />
<br />
</div>
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free for any kind of game running on the HiddenChest engine. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><br />
Due credit is mandatory.<br />
Don't post the contents of this topic anywhere else!<br />
You better paste a link to this thread and make them come here instead.<br />
That's it! <img src="https://www.save-point.org/images/smilies/ejlol/tongue.gif" alt="Tongue sticking out" title="Tongue sticking out" class="smilie smilie_24" /><br />
<br />
<img src="https://www.save-point.org/images/attachtypes/image.gif" title="JPG Image" border="0" alt=".jpg" />
&nbsp;&nbsp;<a href="attachment.php?aid=2115" target="_blank" title="">ksoundfont_vx001.jpg</a> (Size: 40.18 KB / Downloads: 475)
<br />
<br />
<img src="https://www.save-point.org/images/attachtypes/image.gif" title="JPG Image" border="0" alt=".jpg" />
&nbsp;&nbsp;<a href="attachment.php?aid=2120" target="_blank" title="">ksoundfont_ace001.jpg</a> (Size: 32.63 KB / Downloads: 452)
]]></content:encoded>
		</item>
	</channel>
</rss>